%D \module
%D   [       file=strc-num,
%D        version=2008.10.20,
%D          title=\CONTEXT\ Structure Macros,
%D       subtitle=Basic Numbering,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright=PRAGMA-ADE / Hans Hagen]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{ConTeXt Structure Macros / Basic Numbering}

\registerctxluafile{strc-num}{1.001}

\unprotect

% we need to rework this, i.e. clone like itm, des etc with \s!parent

% numbering

% \definestructurecounter[name]
% \setupstructurecounter[name][wijze=,blok=,tekst=,plaats=,conversie=,start=]
% \setstructurecounter[name]{value}
% \resetstructurecounter[name]
% \incrementstructurecounter[name]
% \decrementstructurecounter[name]
% \savestructurecounter[name]
% \restorestructurecounter[name]
% \convertedstructurecounter[name] % depricated: \getstructurecounter[name]
% \rawstructurecounter[name]

% private (defined in core-sec.tex)
%
% \nextstructurecounter[name][tag][reference]
% \currentstructurecounter[name]

% todo: better inheritane system

\definesystemvariable {nn}

\def\setupstructurecountering{\dodoubleempty\getparameters[\??nn]}

\setupstructurecountering
  [\c!way=\v!by\v!chapter,
% \c!blockway=,
% \c!prefixstopper=,
\c!prefixconnector=.,
\c!prefixsegments=\thenamedstructurecounterlevel\currentstructurecounter,
\c!start=0,
\c!state=\v!start,
   \c!prefix=\v!yes,
   \c!state=\v!start]

% \letvalue{\??nn\s!empty}\empty

\def\structurecounterparameter#1#2%
  {\csname
     \ifcsname\??nn#1#2\endcsname
       \??nn#1#2%
     \else\ifcsname\??nn\@@thestructurecounter{#1}#2\endcsname
       \??nn\@@thestructurecounter{#1}#2%
     \else\ifcsname\??nn#2\endcsname
       \??nn#2%
     \else
       \s!empty
     \fi\fi\fi
   \endcsname}

\def\@@thestructurecounter#1%
  {\ifcsname\??nn#1\c!number\endcsname
     \expandafter\@@thestructurecounter\csname\??nn#1\c!number\endcsname
   \else
     #1%
   \fi}

% \def\structurecounterparameter        #1#2{\csname\dostructurecounterparameter{\??nn#1}#2\endcsname}
% \def\dostructurecounterparameter      #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dostructurecounterparentparameter\csname#1\s!number\endcsname#2\fi}
% \def\dostructurecounterparentparameter#1#2{\ifx#1\relax\s!empty\else\dostructurecounterparameter#1#2\fi}

%

\def\definestructurecounter
  {\dodoubleempty\dodefinestructurecounter}

\def\dodefinestructurecounter[#1][#2]%
  {\doifassignmentelse{#2}
     {\dododefinestructurecounter[#1][#2]}
     {\doifelsenothing{#2}
        {\dododefinestructurecounter[#1][]}
        {\donodefinestructurecounter[#1][#2]}}}

\def\dododefinestructurecounter[#1][#2]%
  {\getparameters[\??nn#1][\s!counter=,#2]% counter is for internal purposes
   \ctxlua{structure.counters.define("#1",tonumber("\structurecounterparameter{#1}\c!start") or 0,"\structurecounterparameter{#1}\s!counter")}%
   \docheckstructurecountersetup{#1}}

\def\donodefinestructurecounter[#1][#2]% inherit
  {\getparameters[\??nn#1][\c!number=#2]%
   \docheckstructurecountersetup{#1}}

\def\setupstructurecounter
  {\dodoubleargument\dosetupstructurecounter}

\def\dosetupstructurecounter[#1][#2]%
  {\getparameters[\??nn#1][\c!start=,#2]%
   \docheckstructurecountersetup{#1}}

\def\structurecounterway#1% slow, we need to store it at the tex end
  {\ctxlua{structure.sections.way("\structurecounterparameter{#1}\c!way","\v!by")}}

\def\thenamedstructurecounterlevel#1%
  {\thenamedstructureheadlevel{\structurecounterway{#1}}}

\def\docheckstructurecountersetup#1%
  {% this can be done at the lua end / a bit messy here ... todo ...
   \ifcsname\??nn#1\c!number\endcsname
        \doifelsevalue   {\??nn#1\c!number}{#1} {\letbeundefined{\??nn#1\c!number}}%
       {\doifvaluenothing{\??nn#1\c!number}     {\letbeundefined{\??nn#1\c!number}}}%
   \fi
   \ifcsname\??nn#1\c!number\endcsname
     % it's a clone
   \else
     \edef\currentstructurecounterlevel{\thenamedstructurecounterlevel{#1}}%
     \ctxlua{
        structure.counters.restart("#1",1,"\structurecounterparameter{#1}\c!start")
        structure.counters.setstate("#1","\structurecounterparameter{#1}\c!state")
        structure.counters.setlevel("#1",\currentstructurecounterlevel)
        structure.sections.setchecker("#1",\currentstructurecounterlevel,structure.counters.reset)
     }%
   \fi}

\def\doifstructurecounterelse#1{\ctxlua{structure.counters.doifelse("\@@thestructurecounter{#1}")}}
\def\doifstructurecounter    #1{\ctxlua{structure.counters.doif    ("\@@thestructurecounter{#1}")}}
\def\doifnotstructurecounter #1{\ctxlua{structure.counters.doifnot ("\@@thestructurecounter{#1}")}}

\def\setstructurecounter      [#1]#2{\ctxlua{structure.counters.set    ("\@@thestructurecounter{#1}",1,\number#2)}}
\def\setstructurecounterown   [#1]#2{\ctxlua{structure.counters.setown ("\@@thestructurecounter{#1}",1,"#2")}}
\def\resetstructurecounter      [#1]{\ctxlua{structure.counters.reset  ("\@@thestructurecounter{#1}",1)}}
\def\restartstructurecounter  [#1]#2{\ctxlua{structure.counters.restart("\@@thestructurecounter{#1}",1,#2)}}
\def\savestructurecounter       [#1]{\ctxlua{structure.counters.save   ("\@@thestructurecounter{#1}")}}
\def\restorestructurecounter    [#1]{\ctxlua{structure.counters.restore("\@@thestructurecounter{#1}")}}
\def\incrementstructurecounter  [#1]{\ctxlua{structure.counters.add    ("\@@thestructurecounter{#1}",1,1)}}
\def\decrementstructurecounter  [#1]{\ctxlua{structure.counters.add    ("\@@thestructurecounter{#1}",1,-1)}}
\def\rawstructurecounter        [#1]{\ctxlua{structure.counters.value  ("\@@thestructurecounter{#1}",1)}}
\def\laststructurecounter       [#1]{\ctxlua{structure.counters.last   ("\@@thestructurecounter{#1}",1)}}
\def\firststructurecounter      [#1]{\ctxlua{structure.counters.first  ("\@@thestructurecounter{#1}",1)}}
\def\nextstructurecounter       [#1]{\ctxlua{structure.counters.next   ("\@@thestructurecounter{#1}",1)}}
\def\prevstructurecounter       [#1]{\ctxlua{structure.counters.prev   ("\@@thestructurecounter{#1}",1)}}
\def\structurecountersubs       [#1]{\ctxlua{structure.counters.subs   ("\@@thestructurecounter{#1}",1)}}

\def\tracestructurecounter      [#1]{\ctxlua{structure.counters.trace  ("\@@thestructurecounter{#1}")}}

\def\incrementedstructurecounter[#1]{\ctxlua{tex.write(structure.counters.add("\@@thestructurecounter{#1}",1,1))}}
\def\decrementedstructurecounter[#1]{\ctxlua{tex.write(structure.counters.add("\@@thestructurecounter{#1}",1,-1))}}

\def\setsubstructurecounter        {\dodoubleargument\dosetsubstructurecounter}
\def\setsubstructurecounterown     {\dodoubleargument\dosetsubstructurecounterown}
\def\resetsubstructurecounter      {\dodoubleargument\doresetsubstructurecounter}
\def\restartsubstructurecounter    {\dodoubleargument\dorestartsubstructurecounter}
\def\incrementsubstructurecounter  {\dodoubleargument\doincrementsubstructurecounter}
\def\decrementsubstructurecounter  {\dodoubleargument\dodecrementsubstructurecounter}
\def\rawsubstructurecounter        {\dodoubleargument\dorawsubstructurecounter}

\def\dosetsubstructurecounter      [#1][#2]#3{\ctxlua{structure.counters.set    ("\@@thestructurecounter{#1}",#2,\number#3)}}
\def\dosetsubstructurecounterown   [#1][#2]#3{\ctxlua{structure.counters.setown ("\@@thestructurecounter{#1}",#2,"#3")}}
\def\doresetsubstructurecounter      [#1][#2]{\ctxlua{structure.counters.reset  ("\@@thestructurecounter{#1}",#2)}}
\def\dorestartsubstructurecounter  [#1][#2]#3{\ctxlua{structure.counters.restart("\@@thestructurecounter{#1}",#2,#3)}}
\def\doincrementsubstructurecounter  [#1][#2]{\ctxlua{structure.counters.add    ("\@@thestructurecounter{#1}",#2,1)}}
\def\dodecrementsubstructurecounter  [#1][#2]{\ctxlua{structure.counters.add    ("\@@thestructurecounter{#1}",#2,-1)}}
\def\dorawsubstructurecounter        [#1][#2]{\ctxlua{structure.counters.value  ("\@@thestructurecounter{#1}",#2)}}
\def\dolastsubstructurecounter       [#1][#2]{\ctxlua{structure.counters.last   ("\@@thestructurecounter{#1}",#2)}}
\def\dofirstsubstructurecounter      [#1][#2]{\ctxlua{structure.counters.first  ("\@@thestructurecounter{#1}",#2)}}
\def\dosubstructurecountersubs       [#1][#2]{\ctxlua{structure.counters.subs   ("\@@thestructurecounter{#1}",#2)}}

% The bypage check needs a multipass reference and therefore
% we only check for it when we increment and know that some
% content will be placed. We could also check for spreads.

% to be checked !

\def\docheckstructurecounterbypage#1% since we call lua to get the way we can as well do all in lua
  {\doif{\structurecounterway{#1}}\v!page{\checkpagechange{#1}\ifpagechanged\resetstructurecounter[#1]\fi}}

\def\incrementstructurecounter[#1]%
  {\docheckstructurecounterbypage{#1}%
   \ctxlua{structure.counters.add("\@@thestructurecounter{#1}",1,1)}}

\def\doincrementsubstructurecounter[#1][#2]%
  {\docheckstructurecounterbypage{#1}
   \ctxlua{structure.counters.add("\@@thestructurecounter{#1}",#2,1)}}

\def\convertedstructurecounter
  {\dodoubleempty\doconvertedstructurecounter}

\def\doconvertedstructurecounter[#1][#2]%
  {\begingroup
   \ifsecondargument\getparameters[\??nn#1][#2]\fi
   \ctxlua{structure.counters.prefixedconverted(
     "\@@thestructurecounter{#1}",
     {
       prefix        = "\structurecounterparameter{#1}\c!prefix",
       separatorset  = "\structurecounterparameter{#1}\c!prefixseparatorset",
       conversion    = "\structurecounterparameter{#1}\c!prefixconversion",
       conversionset = "\structurecounterparameter{#1}\c!prefixconversionset",
       stopper       = \!!bs\structurecounterparameter{#1}\c!prefixstopper\!!es,
       set           = "\structurecounterparameter{#1}\c!prefixset",
       segments      = "\structurecounterparameter{#1}\c!prefixsegments",
       connector     = \!!bs\structurecounterparameter{#1}\c!prefixconnector\!!es,
     },
     {
       order         = "\structurecounterparameter{#1}\c!numberorder",
       separatorset  = "\structurecounterparameter{#1}\c!numberseparatorset",
       conversion    = \!!bs\structurecounterparameter{#1}\c!numberconversion\!!es,
       conversionset = "\structurecounterparameter{#1}\c!numberconversionset",
       stopper       = \!!bs\structurecounterparameter{#1}\c!numberstopper\!!es,
       segments      = "\structurecounterparameter{#1}\c!numbersegments",
       type          = "\structurecounterparameter{#1}\c!type",
       criterium     = "\structurecounterparameter{#1}\c!criterium", % might change if we also want this with sectioning
     }
   )}%
   \endgroup}

\def\directconvertedstructurecounter#1#2% name, type
  {\begingroup
   \ctxlua{structure.counters.prefixedconverted(
     "\@@thestructurecounter{#1}",
     {
       prefix        = "\structurecounterparameter{#1}\c!prefix",
       separatorset  = "\structurecounterparameter{#1}\c!prefixseparatorset",
       conversion    = "\structurecounterparameter{#1}\c!prefixconversion",
       conversionset = "\structurecounterparameter{#1}\c!prefixconversionset",
       stopper       = \!!bs\structurecounterparameter{#1}\c!prefixstopper\!!es,
       set           = "\structurecounterparameter{#1}\c!prefixset",
       segments      = "\structurecounterparameter{#1}\c!prefixsegments",
       connector     = \!!bs\structurecounterparameter{#1}\c!prefixconnector\!!es,
     },
     {
       order         = "\structurecounterparameter{#1}\c!numberorder",
       separatorset  = "\structurecounterparameter{#1}\c!numberseparatorset",
       conversion    = \!!bs\structurecounterparameter{#1}\c!numberconversion\!!es,
       conversionset = "\structurecounterparameter{#1}\c!numberconversionset",
       stopper       = \!!bs\structurecounterparameter{#1}\c!numberstopper\!!es,
       segments      = "\structurecounterparameter{#1}\c!numbersegments",
       type          = "#2",
     }
   )}%
   \endgroup}

\def\convertedsubstructurecounter
  {\dotripleempty\doconvertedsubstructurecounter}

\def\doconvertedsubstructurecounter[#1][#2][#3]% #2 can be n or n:m
  {\ifsecondargument
     \doconvertedstructurecounter[#1][\c!numbersegments=#2,#3]%
   \else
     \secondargumentfalse\doconvertedstructurecounter[#1][]%
   \fi}

\let\getstructurecounter\convertedstructurecounter

\def\doifdefinedstructurecounter    #1{\doifdefined    {\csname\s!structurecounter#1\c!number\endcsname}}
\def\doifundefinedstructurecounter  #1{\doifundefined  {\csname\s!number#1\c!number\endcsname}}
\def\doifdefinedstructurecounterelse#1{\doifdefinedelse{\csname\s!number#1\c!number\endcsname}}

\ifx\checkstructurecounter\undefined \def\checkstructurecounter[#1]{} \fi

\def\checkstructurecounter[#1]{}

%D What follows is a compatibility layer. This will be phased out (at
%D least from core usage).

\def\reset
  {\dosingleargument\doreset}

\def\doreset[#1]%
  {\processcommalist[#1]\dodoreset}

\def\dodoreset#1%
  {\csname\s!reset#1\endcsname}%

\let \numberparameter       \structurecounterparameter % {name}\c!key

\let \definenumber          \definestructurecounter    % [name]
\let \setupnumber           \setupstructurecounter     % [name][setups]

\let \setnumber             \setstructurecounter       % [name]{value}
\let \resetnumber           \resetstructurecounter     % [name]
\let \savenumber            \savestructurecounter      % [name]
\let \restorenumber         \restorestructurecounter   % [name]
\let \incrementnumber       \incrementstructurecounter % [name]
\let \decrementnumber       \decrementstructurecounter % [name]
\let \rawnumber             \rawstructurecounter       % [name]
\let \getnumber             \getstructurecounter       % [name]
\let \convertednumber       \getstructurecounter       % [name]

\let \doifdefinednumber     \doifstructurecounter      % {number}{true}
\let \doifundefinednumber   \doifnotstructurecounter   % {number}{true}
\let \doifdefinednumberelse \doifstructurecounterelse  % {number}{true}{false}

% weird one

\def\accumulatednumber[#1]{}

% funny, here, todo: these are the defaults

\def\setupnumbering
  {\dodoubleempty\getparameters[\??nr]}

\setupnumbering
  [\c!way=\v!by\v!chapter,
   \c!blockway=,
   \c!state=\v!start]

\def\numberingparameter#1{\csname\??nr#1\endcsname}

%    \c!prefixconnector=.,
%    \c!stopper=,

% \c!prefix=\v!no,
% \c!prefixconnector=.,
% \c!way=bychapter,
% \c!prefixsegments=2:2,


%D Helpers:

% call:
%
% \dostructurecountercomponent
%   \currentfloat
%   \getfloatparameters \floatparameter \detokenizedfloatparameter
%   \hascaption \hastitle \hasnumber
%   [settings][userdata]
%
% sets:
%
% \laststructurecounternumber
% \laststructurecountersynchronize

\newconditional\hasstructurecountercaption
\newconditional\hasstructurecountertitle
\newconditional\hasstructurecounternumber

\def\dostructurecountercomponent#1#2#3#4#5#6#7[#8][#9]%
  {\begingroup
   %
   #2[#8]%
   \edef\hasstructurecountercaption{#3\s!hascaption}%
   \edef\hasstructurecountertitle{#3\s!hastitle}%
   \edef\hasstructurecounternumber{#3\s!hasnumber}%
   %
   \edef\currentname{#3\c!name}%
   \ifx\currentname\empty
     \edef\currentname{#1}%
   \fi
   \edef\currentcounter{#3\s!counter}%
   \ifx\currentcounter\empty
     \let\currentcounter\currentname
   \fi
   %
   \doif{#3\c!title}\v!none{\setfalse\hasstructurecountercaption\setfalse\hasstructurecounternumber}% will become obsolete
   %
   \ifx\hasstructurecounternumber\v!yes
     \incrementstructurecounter[\currentcounter]%
   \fi
   %
   \ifx\hasstructurecountercaption\v!yes
     \edef\currentexpansion{#3\c!expansion}%
     \ifx\currentexpansion\s!xml
       \edef\currenttitle{#4\c!title}%
       \edef\currentbookmark{#4\c!bookmark}%
       \xmlstartraw
         \edef\currentlisttitle{#3\c!title}%
       \xmlstopraw
       \let\currentcoding\s!xml
     \else
       \ifx\currentexpansion\v!yes
         \edef\currenttitle{#3\c!title}%
         \edef\currentbookmark{#3\c!bookmark}%
       \else
         \edef\currenttitle{#4\c!title}%
         \edef\currentbookmark{#4\c!bookmark}%
       \fi
       \let\currentlisttitle\currenttitle
       \let\currentcoding\s!tex
     \fi
     \edef\currentlabel{#3\c!label}%
     \edef\currentreference{#3\c!reference}%
     \setnextinternalreference
     \xdef\laststructurecounternumber{\ctxlua{structure.lists.push{
        metadata = {
            kind     = "#1",
            name     = "\currentname",
            level    = structure.sections.currentlevel(),
            catcodes = \the\catcodetable,
        },
        references = {
            internal        = \nextinternalreference,
            reference       = "\currentreference",
            referenceprefix = "\referenceprefix",
            block           = "\currentstructureblock",
            section         = structure.sections.currentid(),
        },
        titledata = {
            label    = \!!bs\detokenize\expandafter{\currentlabel    }\!!es,
            title    = \!!bs\detokenize\expandafter{\currenttitle    }\!!es,
        \ifx\currentbookmark\currenttitle \else
            bookmark = \!!bs\detokenize\expandafter{\currentbookmark }\!!es,
        \fi
        \ifx\currentlisttitle\currenttitle \else
            list     = \!!bs\detokenize\expandafter{\currentlisttitle}\!!es,
        \fi
        },
    \ifx\hasstructurecountercaption\v!yes
        prefixdata = {
            prefix        = "#3\c!prefix",
            separatorset  = "#3\c!prefixseparatorset",
            conversion    = \!!bs#3\c!prefixconversion\!!es,
            conversionset = "#3\c!prefixconversionset",
            set           = "#3\c!prefixset",
            segments      = "#3\c!prefixsegments",
            connector     = \!!bs#3\c!prefixconnector\!!es,
        },
        numberdata = {
            numbers       = structure.counters.compact("\currentcounter",nil,true),
            separatorset  = "#3\c!numberseparatorset",
            conversion    = \!!bs#3\c!numberconversion\!!es,
            conversionset = "#3\c!numberconversionset",
            stopper       = \!!bs#3\c!numberstopper\!!es,
            segments      = "#3\c!numbersegments",
        },
    \fi
        userdata = structure.helpers.touserdata(\!!bs\detokenize{#9}\!!es)
       }
     }}%
     \xdef\laststructurecounterattribute  {\ctxlua    {tex.write(jobreferences.setinternalreference(nil,nil,\nextinternalreference))}}%
     \xdef\laststructurecountersynchronize{\ctxlatelua{structure.lists.enhance(\laststructurecounternumber)}}%
   \else
     \glet\laststructurecounternumber     \relax
     \glet\laststructurecounterattribute  \relax
     \glet\laststructurecountersynchronize\relax
   \fi
   \endgroup}

\def\dostructurecountersetup#1#2% name \someparameter
  {\setupstructurecounter
     [#1]
     [              \c!start=#2\c!start,
                    \c!state=#2\c!state,
                      \c!way=#2\c!way,
                            %
                   \c!prefix=#2\c!prefix,
       \c!prefixseparatorset=#2\c!prefixseparatorset,
         \c!prefixconversion=#2\c!prefixconversion,
      \c!prefixconversionset=#2\c!prefixconversionset,
            \c!prefixstopper=#2\c!prefixstopper,
                \c!prefixset=#2\c!prefixset,
           \c!prefixsegments=#2\c!prefixsegments,
                \c!prefixset=#2\c!prefixset,
          \c!prefixconnector=#2\c!prefixconnector,
                            %
       \c!numberseparatorset=#2\c!numberseparatorset,
         \c!numberconversion=#2\c!numberconversion,
      \c!numberconversionset=#2\c!numberconversionset,
            \c!numberstopper=#2\c!numberstopper,
           \c!numbersegments=#2\c!numbersegments]}

\protect \endinput
