% use this to define text in different languages for the key <env arg>
% the translation for <env arg> is printed when the environment ends.
% (temporarily change fqname to the \fqname:<env arg> to allow
% the use of \eng and \ger without the key parameter)
% [1]: key
\newenvironment{ttext}[1][desc]{
    \edef\realfqname{\fqname}
    \edef\fqname{\fqname:#1}
}{
    \expandafter\GT\expandafter{\fqname}% \\
    \edef\fqname{\realfqname}
}


\def\descwidth{0.3\textwidth}
\def\eqwidth{0.6\textwidth}


%
% FORMULA ENVIRONMENT
% The following commands are meant to be used with the formula environment
%

% Name in black and below description in gray
% [1]: minipage width
% 2: fqname of name
% 3: fqname of a translation that holds the explanation
\newcommand{\NameWithDescription}[3][\descwidth]{
    \begin{minipage}{#1}
        \IfTranslationExists{#2}{
            \raggedright
            \GT{#2}
        }{\detokenize{#2}}
        \IfTranslationExists{#3}{
           \\ {\color{dark1} \GT{#3}}
        }{}
    \end{minipage}
}


% TODO: rename
\newsavebox{\contentBoxBox}
% [1]: minipage width
% 2: fqname of a translation that holds the explanation
\newenvironment{ContentBoxWithExplanation}[2][\eqwidth]{
    \def\ContentFqName{#2}
    \begin{lrbox}{\contentBoxBox}
    \begin{minipage}{#1}
}{
        \IfTranslationExists{\ContentFqName}{%
            \smartnewline
            \noindent
            \begingroup
                \color{dark1} 
                \GT{\ContentFqName}
                % \edef\temp{\GT{#1_defs}}
                % \expandafter\StrSubstitute\expandafter{\temp}{:}{\\}
            \endgroup
        }{}
    \end{minipage}
    \end{lrbox}
    \fbox{\usebox{\contentBoxBox}}
}




\newenvironment{formula}[1]{
    % [1]: language
    % 2: name
    % 3: description
    % 4: definitions/links
    \newcommand{\desc}[4][english]{
        % language, name, description, definitions
        \ifblank{##2}{}{\dt[#1]{##1}{##2}}
        \ifblank{##3}{}{\dt[#1_desc]{##1}{##3}}
        \ifblank{##4}{}{\dt[#1_defs]{##1}{##4}}
    }
    \directlua{n_formulaEntries = 0}
    \newcommand{\newFormulaEntry}{
        \directlua{
            if n_formulaEntries > 0 then
            tex.print("\\vspace{0.3\\baselineskip}\\hrule\\vspace{0.3\\baselineskip}")
            end
            n_formulaEntries = n_formulaEntries + 1
        }
        % \par\noindent\ignorespaces
    }
    % 1: equation for align environment
    \newcommand{\eq}[1]{
        \newFormulaEntry
        \begin{align}
            \label{eq:\fqname:#1}
            ##1
        \end{align}
    }
    % 1: equation for alignat environment
    \newcommand{\eqAlignedAt}[2]{
        \newFormulaEntry
        \begin{flalign}%
            \TODO{\text{remove macro}}
            % dont place label when one is provided
            % \IfSubStringInString{label}\unexpanded{#3}{}{
            %     \label{eq:#1}
            % }
            ##1%
        \end{flalign}
    }
    % 1: equation for flalign environment
    \newcommand{\eqFLAlign}[2]{
        \newFormulaEntry
        \begin{alignat}{##1}%
            % dont place label when one is provided
            % \IfSubStringInString{label}\unexpanded{#3}{}{
            %     \label{eq:#1}
            % }
            ##2%
        \end{alignat}
    }
    \newcommand{\fig}[2][1.0]{
        \newFormulaEntry
        \centering
        \includegraphics[width=##1\textwidth]{##2}
    }
    % 1: content for the ttext environment
    \newcommand{\ttxt}[2][#1:desc]{
        \newFormulaEntry
        \begin{ttext}[##1]
            ##2
        \end{ttext}
    }
    % 1: key - must expand to a valid lua string!
    % 2: symbol
    % 3: units
    % 4: comment key to translation
    \newcommand{\quantity}[3]{%
        \directLuaAux{
            quantities["#1"] = {} 
            quantities["#1"]["symbol"]  = [[\detokenize{##1}]]
            quantities["#1"]["units"]   = [[\detokenize{##2}]]
            quantities["#1"]["comment"] = [[\detokenize{##3}]]
        }\directLuaAuxExpand{
            quantities["#1"]["fqname"]  = [[\fqname]] %-- fqname required for getting the translation key
        }
        \newFormulaEntry
        \printQuantity{#1}
    }

    % must be used only in third argument of "constant" command
    % 1: value
    % 2: unit
    \newcommand{\val}[2]{
        \directLuaAux{
            table.insert(constants["#1"]["values"], { value = [[\detokenize{##1}]], unit = [[\detokenize{##2}]] })
        }
    }
    % 1: symbol
    % 2: either exp or def; experimentally or defined constant
    % 3: one or more \val{value}{unit} commands
    \newcommand{\constant}[3]{
        \directLuaAux{
            constants["#1"] = {}
            constants["#1"]["symbol"]  = [[\detokenize{##1}]]
            constants["#1"]["exp_or_def"]   = [[\detokenize{##2}]]
            constants["#1"]["values"] = {} %-- array of {value, unit}
        }\directLuaAuxExpand{
            constants["#1"]["fqname"]  = [[\fqname]] %-- fqname required for getting the translation key
        }
        \begingroup
            ##3
        \endgroup
        \newFormulaEntry
        \printConstant{#1}
    }

    \begingroup
        \label{f:\fqname:#1}
        \par\noindent\ignorespaces
        % \textcolor{gray}{\hrule}
        \vspace{0.5\baselineskip}
        \NameWithDescription[\descwidth]{\fqname:#1}{\fqname:#1_desc}
        \hfill
        \begin{ContentBoxWithExplanation}{\fqname:#1_defs}
}{
        \end{ContentBoxWithExplanation}
    \endgroup
    \textcolor{dark3}{\hrule}
    \vspace{0.5\baselineskip}
    \ignorespacesafterend
}
%
% QUANTITY
%

% units: siunitx units arguments, possibly chained by '='
% returns: 1\si{unit1} = 1\si{unit2} = ...
\directlua{
    function split_and_print_units(units)
        if units == nil then
            tex.print("1")
            return
        end
            
        local parts = {}
        for part in string.gmatch(units, "[^=]+") do
            table.insert(parts, part)
        end
        local result = ""
        for i, unit in ipairs(parts) do
            if i > 1 then result = result .. " = " end
            result = result .. "\\SI{1}{" .. unit .. "}"
        end
        tex.print(result)
    end
}


%     % for TOC
%     \refstepcounter{constant}%
%     % \addquantity{\expandafter\gt\expandafter{\qtyname}}%
%     % \noindent\textbf{My Environment \themyenv: #1}\par%
% }
\directLuaAux{
    if constants == nil then
        constants = {}
    end
}
\newcommand\printConstant[1]{
    \begingroup % for label
        Symbol: $\luavar{constants["#1"]["symbol"]}$
        % \\Unit: $\directlua{split_and_print_units(constants["#1"]["units"])}$
        \directlua{
            tex.print("\\\\\\GT{const:"..constants["#1"]["exp_or_def"].."}")
        }
        \directlua{
            %--tex.sprint("Hier steht Luatext" .. ":", #constVals)
            for i, pair in ipairs(constants["#1"]["values"]) do
            tex.sprint("\\\\\\hspace*{1cm}${", pair["value"], "}\\,\\si{", pair["unit"], "}$")
                %--tex.sprint("VALUE ", i, v)
            end
        }
        % label it only once
        \directlua{ 
            if constants["#1"]["labeled"] == nil then
                constants["#1"]["labeled"] = true
                tex.print("\\label{const:#1}")
            end
        }
    \endgroup
}

\newcounter{constant}

\directLuaAux{
    if quantities == nil then
        quantities = {}
    end
}
\newcommand\printQuantity[1]{
    \begingroup % for label
        Symbol: $\luavar{quantities["#1"]["symbol"]}$
        \\Unit: $\directlua{split_and_print_units(quantities["#1"]["units"])}$
        % label it only once
        \directlua{ 
            if quantities["#1"]["labeled"] == nil then
                quantities["#1"]["labeled"] = true
                tex.print("\\label{qty:#1}")
            end
        }
    \endgroup
}

% Custon environment with table of contents, requires etoolbox?
% Define a custom list
\newcommand{\listofmyenv}{%
    \section*{List of My Environments}%
    \addcontentsline{toc}{section}{List of My Environments}%
    \par\noindent\hrule\par\vspace{0.5\baselineskip}\@starttoc{myenv}%
}
\newcommand{\addmyenv}[1]{\addcontentsline{myenv}{subsection}{\protect\numberline{\themyenv}#1}}
% Define the custom environment
\newcounter{myenv}
\newenvironment{myenv}[1]{%
  \refstepcounter{myenv}%
  \addmyenv{#1}%
  \noindent\textbf{My Environment \themyenv: #1}\par%
}{\par\vspace{0.5\baselineskip}}




%
% DISTRIBUTION
%
\def\distrightwidth{0.45\textwidth}
\def\distleftwidth{0.45\textwidth}

% Table for distributions
% create entries for parameters using \disteq
\newenvironment{distribution}{
    % 1: param name (translation key)
    % 2: math
    \newcommand{\disteq}[2]{
        % add links to some names
        \directlua{
            local cases = {
                pdf         = "f:math:pt:pdf",
                pmf         = "f:math:pt:pmf",
                cdf         = "f:math:pt:cdf",
                mean        = "f:math:pt:mean",
                variance    = "f:math:pt:variance"
            }
            if cases["\luaescapestring{##1}"] \string~= nil then
                tex.sprint("\\hyperref["..cases["\luaescapestring{##1}"].."]{\\GT{##1}}")
            else
                tex.sprint("\\GT{##1}")
            end
        }
        & ##2 \\ \hline
    }
    \hfill
    \begin{minipage}{\distrightwidth}
        \begingroup
            \setlength{\tabcolsep}{0.9em}  % horizontal
            \renewcommand{\arraystretch}{2}  % vertical
            \begin{tabular}{|l|>{$\displaystyle}c<{$}|}
            \hline
}{
            \end{tabular}
        \endgroup
    \end{minipage}
}

% A 2 column table in a minipage
% create entries for parameters using \entry
% 1: minipage width
% 2: key of the table
\newenvironment{minipagetable}[2][0.5\textwidth]{
    % save real fq name
    \edef\tmpFqname{\fqname}
    \edef\tmpMinipagetableWidth{#1}
    \edef\tmpMinipagetableName{#2}
    \directlua{
        entries = {}
    }

    % 1: field name (translation key)
    % 2: translation define statements (field content)
    \newcommand{\entry}[2]{
        % temporarily set fqname so that the translation commands dont need an explicit key
        \edef\fqname{\tmpFqname:#2:##1}
        ##2
        \edef\fqname{\tmpFqname}
        \directlua{
            table.insert(entries, "\luaescapestring{##1}")
        }
    }
}{
    % \hfill
    \begin{minipage}{\tmpMinipagetableWidth}
        \begingroup
            \setlength{\tabcolsep}{0.9em}  % horizontal
            \renewcommand{\arraystretch}{2}  % vertical
            \begin{tabularx}{\textwidth}{|l|X|}
            \hline
            \directlua{
                for _, k in ipairs(entries) do
                    tex.print("\\GT{" .. k .. "} & \\gt{\tmpMinipagetableName:" .. k .. "}\\\\")
                end
            }
            \hline
            \end{tabularx}
        \endgroup
    \end{minipage}
    % reset the fqname
}
