\ifx\definestreamlayer\undefined \input page-str \fi

%D First we implement a simple left||right synchronization
%D mechanism, which we may perfect and extend over time.

\unprotect

\defineoutputstream [\v!left]
\defineoutputstream [\v!right]

\definemarknote[\v!left]
\definemarknote[\v!right]

\startsetups stream:\v!left:bottom
    \flushmarknotes[\v!left]
\stopsetups
\startsetups stream:\v!right:bottom
    \flushmarknotes[\v!right]
\stopsetups
\startsetups stream:\v!left:reset
   \erasemarknotes[\v!left]
\stopsetups
\startsetups stream:\v!right:reset
   \erasemarknotes[\v!right]
\stopsetups

\def\LeftNote               {\setmarknote             [\v!left]}  % {#1}
\def\RightNote              {\setmarknote             [\v!right]} % {#1}
\def\SwitchToLeft           {\enableoutputstream      [\v!left]}
\def\SwitchToRight          {\enableoutputstream      [\v!right]}
\def\SwitchToNormal         {\enableoutputstream      [\s!default]}
\def\SynchronizeLeftAndRight{\synchronizeoutputstreams[\v!left,\v!right]}
\def\FlushLeftAndRight      {\flushoutputstreampages  [\v!left,\v!right]}

\protect

% \topskip     \strutheight
% \splittopskip\strutheight

%D Example of usage:
%D
%D \starttyping
%D \nopenalties \setupinterlinespace[top=height] \setupcolors[state=start]
%D
%D \showgrid \showstruts
%D
%D \starttext
%D
%D \title{Whatever} \page
%D
%D \dorecurse {5} {
%D     \let\RecurseLevel\recurselevel
%D     \SwitchToLeft   \dorecurse{10}{\dontleavehmode{\tf\RecurseLevel:l \begstrut \input tufte \endstrut \endgraf}}
%D     \SwitchToRight  \dorecurse{10}{\dontleavehmode{\sl\RecurseLevel:r \begstrut \input knuth \endstrut \endgraf}}
%D     \SwitchToNormal \SynchronizeLeftAndRight
%D     \SwitchToLeft   \dorecurse{10}{\dontleavehmode{\bf\RecurseLevel:l \begstrut \input zapf  \endstrut \endgraf}}
%D     \SwitchToRight  \dorecurse{10}{\dontleavehmode{\bs\RecurseLevel:r \begstrut \input davis \endstrut \endgraf}}
%D     \SwitchToNormal \SynchronizeLeftAndRight
%D }
%D \stoptext
%D \stoptyping
%D
%D Another example:
%D
%D \starttyping
%D \nopenalties \setupinterlinespace[top=height] \setupcolors[state=start]
%D
%D \showgrid \showstruts
%D
%D \starttext
%D
%D \SwitchToNormal \FlushLeftAndRight \page
%D
%D \def\StartCouple{\page\SwitchToNormal}
%D \def\StopCouple {\SwitchToNormal \SynchronizeLeftAndRight \FlushLeftAndRight}
%D
%D \def\Original   {\SwitchToNormal\SynchronizeLeftAndRight\SwitchToLeft}
%D \def\Translation{\SwitchToRight}
%D
%D \StartCouple
%D \dorecurse{10} {
%D     \Original    o: \begstrut \inright{\blackrule}\input tufte   \endstrut \LeftNote {tufte}   \endgraf
%D     \Translation t: \begstrut \inleft {\blackrule}\input zapf    \endstrut \RightNote{zapf}    \endgraf
%D     \Original    o: \begstrut \inright{\blackrule}\input knuth   \endstrut \LeftNote {knuth}   \endgraf
%D     \Translation t: \begstrut \inleft {\blackrule}\input davis   \endstrut \RightNote{davis}   \endgraf
%D     \Original    o: \begstrut \inright{\blackrule}\input douglas \endstrut \LeftNote {douglas} \endgraf
%D     \Translation t: \begstrut \inleft {\blackrule}\input bryson  \endstrut \RightNote{bryson}  \endgraf
%D }
%D \StopCouple
%D \stoptext
%D \stoptyping

%D Next we implement stream layers.

\unprotect

\startsetups streamlayer:default:settings
  % set hsize etc
\stopsetups

\startsetups streamlayer:default:extras
  % flush goodies, like local floats
\stopsetups

\startsetups streamlayer:default:place
  \setlayer
    [\currentstreamlayer]
    [\c!preset=\v!left\v!top]
    {\outputstreambox[\currentstreamlayer]}%
\stopsetups

\startsetups streamlayer:default:flush
    \tightlayer[\currentstreamlayer]
\stopsetups

\def\definestreamlayer
  {\dodoubleempty\dodefinestreamlayer}

\def\dodefinestreamlayer[#1][#2]%
  {\defineoutputstream[#1]%
   \defineoutputstream[main]%
   \definelayer[#1][\c!method=\v!fit,\c!width=\textwidth,#2]}

\def\dostreamsetups#1%
  {\doifsetupselse{streamlayer:\currentstreamlayer:#1}
     {\directsetup{streamlayer:\currentstreamlayer:#1}}
     {\directsetup{streamlayer:\s!default:#1}}}

\def\startstreamlayer[#1]%
  {\bgroup
   \edef\currentstreamlayer{#1}%
   \enableoutputstream[main]%
   \synchronizeoutput
   \enableoutputstream[\currentstreamlayer]%
   \bgroup
   \dostreamsetups{settings}}

\def\stopstreamlayer
  {\endgraf
   \egroup
   \disableoutputstream % \enableoutputstream[\s!default]%
   \outputstreambox[main]%
   \dostreamsetups{place}%
   \dostreamsetups{extras}%
   \dostreamsetups{flush}%
   \egroup}

\def\flushstreamlayer
  {\dosingleempty\doflushstreamlayer}

\def\doflushstreamlayer[#1]%
  {\expanded{\tightlayer[\iffirstargument#1\else\currentstreamlayer\fi]}}

\protect

%D Usage:

%D \starttyping
%D \setupinterlinespace[top=height]
%D
%D \setupcolors[state=start]
%D
%D \definestreamlayer[block]
%D
%D \definemeasure[localtextwidth] [\dimexpr.7\textwidth\relax]
%D \definemeasure[localfloatwidth][\dimexpr.3\textwidth-2\bodyfontsize\relax]
%D
%D \startsetups streamlayer:block:settings
%D   \hsize=\measure{localtextwidth}
%D   \setupfloat[figure][maxwidth=\measure{localfloatwidth}]
%D \stopsetups
%D
%D \startsetups streamlayer:block:extras
%D   \setuplocalfloats
%D     [before=\blank,
%D      after=\blank,
%D      inbetween=\blank]
%D   \setbox\scratchbox\vbox{\hsize\measure{localfloatwidth}\getlocalfloats}
%D   \ifdim\ht\scratchbox>\thelayerheight\currentstreamlayer\relax
%D     % more float than text
%D     \setlayerframed
%D       [\currentstreamlayer]
%D       [preset=righttop]
%D       [frame=off,
%D        offset=overlay]
%D       {\box\scratchbox}
%D   \else
%D     % more text than float
%D     \setuplocalfloats
%D       [before=\vfill,
%D        after=\removedepth\vfill,
%D        inbetween=\removedepth\vfill]
%D     \setlayerframed
%D       [\currentstreamlayer]
%D       [preset=righttop]
%D       [frame=off,
%D        offset=overlay]
%D       {\vbox to \thelayerheight\currentstreamlayer {\hsize\measure{localfloatwidth}\getlocalfloats}}
%D   \fi
%D   \resetlocalfloats
%D \stopsetups
%D
%D \startsetups streamlayer:block:place
%D   \setlayerframed
%D     [\currentstreamlayer]
%D     [preset=lefttop]
%D     [frame=off,
%D      offset=overlay]
%D     {\outputstreambox[\currentstreamlayer]}%
%D \stopsetups
%D
%D \startsetups streamlayer:block:flush
%D    \framed
%D      [offset=overlay,
%D       frame=off,
%D       background=color,
%D       backgroundcolor=red]
%D      {\tightlayer[\currentstreamlayer]}
%D \stopsetups
%D
%D \setupbodyfont[small]
%D
%D \starttext
%D
%D \dorecurse {10} {
%D     \startstreamlayer[block]
%D         \title{Sample \recurselevel}
%D         \input tufte \endgraf
%D         \placefigure[local]{}{}
%D         \placefigure[local]{}{}
%D         \ifodd\recurselevel\relax \placefigure[local]{}{} \fi
%D         \startitemize[columns]
%D             \item xxx
%D             \item xxx
%D             \item xxx
%D             \item xxx
%D             \item xxx
%D         \stopitemize
%D     \stopstreamlayer
%D }
%D
%D \dorecurse {10} {
%D     \startstreamlayer[block]
%D         \title{Sample \recurselevel}
%D         \startcolumns
%D             \input tufte
%D         \stopcolumns
%D     \stopstreamlayer
%D }
%D
%D \stoptext
%D \stoptyping

\endinput

\setupinterlinespace[top=height]

\setupcolors[state=start]

\definestreamlayer[block]

\definemeasure[localtextwidth] [\dimexpr.7\textwidth\relax]
\definemeasure[localfloatwidth][\dimexpr.3\textwidth-2\bodyfontsize\relax]

\startsetups streamlayer:block:settings
  \hsize=\measure{localtextwidth}
  \setupfloat[figure][maxwidth=\measure{localfloatwidth}]
\stopsetups

\startsetups streamlayer:block:extras
  \setuplocalfloats
    [before=\whitespace\blank,
     after=\whitespace\blank,
     inbetween=\whitespace\blank]
  \setbox\scratchbox\vbox{\hsize\measure{localfloatwidth}\getlocalfloats}
  \ifdim\ht\scratchbox>\thelayerheight\currentstreamlayer\relax
    % more float than text
    \setlayerframed
      [\currentstreamlayer]
      [preset=righttop]
      [frame=off,
       offset=overlay]
      {\box\scratchbox}
  \else
    % more text than float
    \setuplocalfloats
      [before=\vfill,
       after=\removedepth\vfill,
       inbetween=\removedepth\vfill]
    \setlayerframed
      [\currentstreamlayer]
      [preset=righttop]
      [frame=off,
       offset=overlay]
      {\vbox to \thelayerheight\currentstreamlayer {\hsize\measure{localfloatwidth}\getlocalfloats}}
  \fi
  \resetlocalfloats
\stopsetups

\startsetups streamlayer:block:place
  \setlayerframed
    [\currentstreamlayer]
    [preset=lefttop]
    [frame=off,
     offset=overlay]
    {\outputstreambox[\currentstreamlayer]}%
\stopsetups

\startsetups streamlayer:block:flush
   \framed
     [offset=overlay,
      frame=off,
      background=color,
      backgroundcolor=red]
     {\tightlayer[\currentstreamlayer]}
\stopsetups

\setupbodyfont[small]

\starttext

    \startstreamlayer[block]
        \title{Sample \recurselevel}
        \startcolumns
            \dorecurse{4}{\input tufte \par}
        \stopcolumns
    \stopstreamlayer

% \stoptext

\dorecurse {10} {
    \startstreamlayer[block]
        \title{Sample \recurselevel}
        \input tufte \endgraf
        \placefigure[local]{}{}
        \placefigure[local]{}{}
        \ifodd\recurselevel\relax \placefigure[local]{}{} \fi
        \startitemize[columns]
            \item xxx
            \item xxx
            \item xxx
            \item xxx
            \item xxx
        \stopitemize
    \stopstreamlayer
}

\dorecurse {10} {
    \startstreamlayer[block]
        \title{Sample \recurselevel}
        \startcolumns
            \input tufte
        \stopcolumns
    \stopstreamlayer
}

\stoptext
