\ProvidesPackage{mqfqname}
\RequirePackage{mqlua}
\RequirePackage{etoolbox}


\directlua{
    sections = sections or {}

    function fqnameEnter(name)
      table.insert(sections, name)
      % table.sort(sections)
    end

    function fqnameLeave()
      if table.getn(sections) > 0 then
        table.remove(sections)
      end
    end

    function fqnameGet()
      return table.concat(sections, ":")
    end

    function fqnameLeaveOnlyFirstN(n)
      if n >= 0 then
        while table.getn(sections) > n do
          table.remove(sections)
        end
      end
    end
}
\newcommand{\mqfqname@update}{%
  \edef\fqname{\luavar{fqnameGet()}}
}
\newcommand{\mqfqname@enter}[1]{%
  \directlua{fqnameEnter("\luaescapestring{#1}")}%
  \mqfqname@update
}
\newcommand{\mqfqname@leave}{%
  \directlua{fqnameLeave()}%
  \mqfqname@update
}

\newcommand{\mqfqname@leaveOnlyFirstN}[1]{%
  \directlua{fqnameLeaveOnlyFirstN(#1)}%
}

% SECTIONING
% start <section>, get heading from translation, set label
% secFqname is the fully qualified name of sections: the keys of all previous sections joined with a ':'
% fqname is secFqname:<key> where <key> is the key/id of some environment, like formula
% [1]: code to run after setting \fqname, but before the \part, \section etc
% 2: key
\newcommand{\Part}[2][desc]{
    \newpage
    \mqfqname@leaveOnlyFirstN{0}
    \mqfqname@enter{#2}
    \edef\secFqname{\fqname}
    #1
    % this is necessary so that \part/\section... takes the fully expanded string. Otherwise the pdf toc will have just the fqname
    \edef\fqnameText{\GT{\fqname}}
    \part{\fqnameText} 
    \label{sec:\fqname}
}
\newcommand{\Section}[2][]{
    \mqfqname@leaveOnlyFirstN{1}
    \mqfqname@enter{#2}
    \edef\secFqname{\fqname}
    #1
    \edef\fqnameText{\GT{\fqname}}
    \section{\fqnameText}
    \label{sec:\fqname}
}
\newcommand{\Subsection}[2][]{
    \mqfqname@leaveOnlyFirstN{2}
    \mqfqname@enter{#2}
    \edef\secFqname{\fqname}
    #1
    \edef\fqnameText{\GT{\fqname}}
    \subsection{\fqnameText}
    \label{sec:\fqname}
}
\newcommand{\Subsubsection}[2][]{
    \mqfqname@leaveOnlyFirstN{3}
    \mqfqname@enter{#2}
    \edef\secFqname{\fqname}
    #1
    \edef\fqnameText{\GT{\fqname}}
    \subsubsection{\fqnameText}
    \label{sec:\fqname}
}
\edef\fqname{NULL}

\newcommand\printFqName{\expandafter\detokenize\expandafter{\fqname}}


\newcommand\luaDoubleFieldValue[3]{%
    \directlua{
        if #1 \string~= nil and #1[#2] \string~= nil and #1[#2][#3] \string~= nil then
            tex.sprint(#1[#2][#3])
            return
        end
        luatexbase.module_warning('luaDoubleFieldValue', 'Invalid indices to `#1`: `#2` and `#3`');
        tex.sprint("???")
    }%
}
% REFERENCES
% All xyzRef commands link to the key using the translated name
% Uppercase (XyzRef) commands have different link texts, but the same link target
% 1: key/fully qualified name (without qty/eq/sec/const/el... prefix)

% Equations/Formulas
% \newrobustcmd{\fqEqRef}[1]{%
\newrobustcmd{\fqEqRef}[1]{%
    % \edef\fqeqrefname{\GT{#1}}
    % \hyperref[eq:#1]{\fqeqrefname}
    \hyperref[f:#1]{\GT{#1}}%
}
% Formula in the current section
\newrobustcmd{\secEqRef}[1]{%
    % \edef\fqeqrefname{\GT{#1}}
    % \hyperref[eq:#1]{\fqeqrefname}
    \hyperref[f:\secFqname:#1]{\GT{\secFqname:#1}}%
}

% Section
% <name>
\newrobustcmd{\fqSecRef}[1]{%
    \hyperref[sec:#1]{\GT{#1}}%
}
% Quantities
% <symbol>
\newrobustcmd{\qtyRef}[1]{%
    \edef\tempname{\luaDoubleFieldValue{quantities}{"#1"}{"linkto"}}%
    \hyperref[qty:#1]{\expandafter\GT\expandafter{\tempname:#1}}%
}
% <symbol> <name>
\newrobustcmd{\QtyRef}[1]{%
    $\luaDoubleFieldValue{quantities}{"#1"}{"symbol"}$ \qtyRef{#1}%
}
% Constants
% <name>
\newrobustcmd{\constRef}[1]{%
    \edef\tempname{\luaDoubleFieldValue{constants}{"#1"}{"linkto"}}%
    \hyperref[const:#1]{\expandafter\GT\expandafter{\tempname:#1}}%
}
% <symbol> <name>
\newrobustcmd{\ConstRef}[1]{%
    $\luaDoubleFieldValue{constants}{"#1"}{"symbol"}$ \constRef{#1}%
}
% Element from periodic table
% <symbol>
\newrobustcmd{\elRef}[1]{%
    \hyperref[el:#1]{{\color{fg0}#1}}%
}
% <name>
\newrobustcmd{\ElRef}[1]{%
    \hyperref[el:#1]{\GT{el:#1}}%
}



% "LABELS"
% These currently do not place a label,
% instead they provide an alternative way to reference an existing label
\directLuaAux{
    absLabels = absLabels or {}
    abbrLabels = abbrLabel or {}
}
% [1]: target (fqname to point to)
% 2: key
\newcommand{\absLink}[2][sec:\fqname]{
    \directLuaAuxExpand{
        absLabels["#2"] = [[#1]] 
    } 
}
% [1]: target (fqname to point to)
% 2: key
% 3: label (abbreviation)
\newcommand{\abbrLink}[3][sec:\fqname]{
    \directLuaAuxExpand{
        abbrLabels["#2"] = {}
        abbrLabels["#2"]["abbr"] = [[#3]] 
        abbrLabels["#2"]["fqname"] = [[#1]] 
    } 
}
% [1]: 
\newrobustcmd{\absRef}[2][\relax]{%
    \directlua{
        if absLabels["#2"] == nil then
            tex.sprint("\\detokenize{#2}???")
        else
            if "#1" == "" then  %-- if [#1]  is not given, use translation of key as text, else us given text
                tex.sprint("\\hyperref[" .. absLabels["#2"] .. "]{\\GT{" .. absLabels["#2"] .. "}}")
            else
                tex.sprint("\\hyperref[" .. absLabels["#2"] .. "]{\luaescapestring{#1}}")
            end
        end
    }
}
\newrobustcmd{\abbrRef}[1]{%
    \directlua{
        if abbrLabels["#1"] == nil then
            tex.sprint("\\detokenize{#1}???")
        else
            tex.sprint("\\hyperref[" .. abbrLabels["#1"]["fqname"] .. "]{" .. abbrLabels["#1"]["abbr"] .. "}")
        end
    }
}
