%D \module
%D   [       file=strc-blk,
%D        version=2008.10.20,
%D          title=\CONTEXT\ Structure Macros,
%D       subtitle=Blockmoves,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%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 / Blockmoves}

\registerctxluafile{strc-blk}{}

\unprotect

% we run on top of buffers and sections
%
% todo: prefix numbers (needs further integration elsewhere)
%       check functionality
%       alternative files (needs further integration elsewhere)
%
% order matters: \c!before (think of: \c!before=\startitemize)
%
% no \endgroups

\installcorenamespace {block}
\installcorenamespace {blocktemp}

\installcommandhandler \??block {block} \??block

\appendtoks
    \clf_definestructureblock{\currentblock}%
    \setuevalue{\e!begin\currentblock}{\strc_blocks_begin{\currentblock}}%
    \letvalue  {\e!end  \currentblock}\donothing
\to \everydefineblock

% The naive way:
%
% \unexpanded\def\strc_blocks_begin#1%
%   {\dotripleempty\strc_blocks_begin_indeed[#1]}
%
% \unexpanded\def\strc_blocks_begin_indeed[#1][#2][#3]%
%   {\normalexpanded{\buff_pickup{\??block}{\e!begin#1}{\e!end#1}}
%      {}%
%      {\clf_savestructureblock{#1}{#2}{#3}{\??block}}%
%      \plusone}%
%
% We need to prevent too much lookahead which will gobble newlines
% that are needed for buffers. See blocks-002.tex as example.

% maybe: systemmode "block:<name>"

\let\m_block   \empty
\let\m_subblock\empty

\unexpanded\def\strc_blocks_begin#1%
  {\edef\m_block   {#1}%
   \let \m_subblock\empty
   \doifelsenextoptionalcs\strc_blocks_begin_yes\strc_blocks_begin_nop}

\unexpanded\def\strc_blocks_begin_yes[#1]%
  {\doifelseassignmentcs{#1}%
     \strc_blocks_begin_indeed
     \strc_blocks_begin_tagged
     {#1}}

\unexpanded\def\strc_blocks_begin_tagged#1%
  {\edef\m_subblock{#1}%
   \doifelsenextoptionalcs\strc_blocks_begin_yes_yes\strc_blocks_begin_nop}

\unexpanded\def\strc_blocks_begin_yes_yes[#1]%
  {\strc_blocks_begin_indeed{#1}}

\unexpanded\def\strc_blocks_begin_nop
  {\strc_blocks_begin_indeed{}}

\unexpanded\def\strc_blocks_begin_indeed#1%
  {\normalexpanded{\buff_pickup{\??block}{\e!begin\m_block}{\e!end\m_block}}%
     {}%
     {\clf_savestructureblock{\m_block}{\m_subblock}{#1}{\??block}}%
     \plusone}

\let\strc_blocks_setup\relax

\newconstant   \c_strc_blocks_index
\newconditional\c_strc_blocks_display

\unexpanded\def\dostarthiddenblock % called at lua end
  {\begingroup
   \visiblefalse % blocks float
   \startnointerference
   \strc_start_block}

\unexpanded\def\dostophiddenblock % called at lua end
  {\strc_stop_block
   \stopnointerference
   \endgroup}

\unexpanded\def\dostartnormalblock % called at lua end
  {\begingroup
   \visibletrue
   \strc_start_block}

\unexpanded\def\dostopnormalblock % called at lua end
  {\strc_stop_block
   \endgroup}

\def\strc_start_block#1#2%
  {\edef\currentblock{#2}%
   \c_strc_blocks_index#1\relax
   \strc_blocks_setup
   \let\strc_blocks_setup\relax
   \edef\p_alternative{\blockparameter\c!alternative}%
   \ifx\p_alternative\v!text
      \setfalse\c_strc_blocks_display
   \else
      \settrue\c_strc_blocks_display
   \fi
   \ifconditional\c_strc_blocks_display
      \blockparameter\c!before
   \fi
   \begingroup
   \usesetupsparameter\blockparameter\relax
   \dostarttagged\t!block\currentblock
   \useblockstyleandcolor\c!style\c!color
   \blockparameter\c!inner % old
   \ifconditional\c_strc_blocks_display
     \usealignparameter\blockparameter
   \else
     \blockparameter\c!left
   \fi
   \ignorespaces}

\def\strc_stop_block
  {\removeunwantedspaces
   \ifconditional\c_strc_blocks_display
     \par
   \else
     \blockparameter\c!right
   \fi
   \dostoptagged
   \endgroup
   \ifconditional\c_strc_blocks_display
     \blockparameter\c!after
   \fi}

\def\strc_blocks_set_state[#1][#2][#3]% state name tag
  {\clf_setstructureblockstate{#1}{#2}{#3}}

\def\strc_blocks_select[#1][#2][#3][#4]% state name tag setups
  {\begingroup
   \doifelseassignment{#3}
     {\getparameters[\??blocktemp][\c!criterium=\v!text,#3]%
      \def\strc_blocks_setup{\setupcurrentblock[#3]}%
      \clf_selectstructureblock{#1}{#2}{}{\csname\??blocktemp\c!criterium\endcsname}}
     {\getparameters[\??blocktemp][\c!criterium=\v!text,#4]%
      \def\strc_blocks_setup{\setupcurrentblock[#4]}%
      \clf_selectstructureblock{#1}{#2}{#3}{\csname\??blocktemp\c!criterium\endcsname}}%
   \endgroup}

\def\blockuservariable#1%
  {\clf_structureblockuservariable\c_strc_blocks_index{#1}}

% hide   : save, if [+] also hidden execute
% keep   : save and normal execute
% use    : normal execute unless [-]
% process: hidden execute unless [-]
% select : idem use

\unexpanded\def\hideblocks   {\dotripleempty   \strc_blocks_set_state[hide]}
\unexpanded\def\keepblocks   {\dotripleempty   \strc_blocks_set_state[keep]}
\unexpanded\def\useblocks    {\doquadrupleempty\strc_blocks_select   [use]}
\unexpanded\def\processblocks{\doquadrupleempty\strc_blocks_select   [process]}
\unexpanded\def\selectblocks {\doquadrupleempty\strc_blocks_select   [use]}

\unexpanded\def\doifelseblocksempty{\clf_doifelsestructureblocksempty} % {name}{tag}{criterium}

\protect \endinput

