%D \module
%D   [       file=wolf-rul,
%D        version=2006.11.04,
%D          title=\CONTEXT\ User Module,
%D       subtitle=Ruled Stuff Handling,
%D         author=Wolfgang Schuster,
%D           date=\currentdate,
%D      copyright=Wolfgang Schuster]

\writestatus{loading}{Context User Module / Ruled Stuff Handling}

\unprotect

%D Needed because I defined a few constants and variables that
%D are currently only stored in my private macros files.
%D To prevent double loading on my system I put
%D \tex{enablemode[wolf]} in my \type{cont-sys.tex} file
%D and let \CONTEXT\ load the \type{wolf-con.tex} file only
%D on third party systems.

\doifnotmode{wolf}{\readfile{wolf-con}\donothing\donothing}

%D This module was created to allow different offsets
%D on all for sides in a frame.
%D
%D The development had shown I can intagrate more options:
%D
%D \startitemize
%D \item including offsets for the top, bottom, left and right
%D \item I intagrated also the option to use a different
%D       to use a different rulethickness for every frame
%D \item after a questions on the mailing list I tried to
%D       add another option, you can now select a dashed
%D       frame and set the dashpattern
%D \item the methods for dashed and solid rules has been merged
%D \stopitemize
%D
%D What need to be done on the module:
%D
%D \startitemize
%D \item is the beagaviour with \type{frame=overlay} oder
%D       \type{offset=overlay} with with different rulethickness
%D       correct or need it to be changed
%D \item dash parameter in combination with rules produce
%D       a dashed border and no round corners, should I give
%D       give round corner a higher priority
%D \item my long if test for every offset and rule need to
%D       cleaned up or nested in a macro, something that is
%D       faster than the current solution
%D \item the module need a big test with existing document
%D       to find bugs or wrong behaviours/presets
%D \item use less parameters to control the rulethickness,
%D       enabling and disabling the frame with processaction
%D \item use leaders for solid and dashed lines and not two
%D       seperate ways
%D \item give the use a message in the log that it is not
%D       possible to used dashed lines and round corners at
%D       the same time, the better solution would be using
%D       \METAPOST\ or asking Hans as long as he integrates
%D       this feature with \PDF\ specials
%D \stopitemize
%D
%D my first example (and my own testcase) shows all new options:
%D
%D \starttyping
%D \startTEXpage
%D
%D \framed
%D  [linestyle=dashed,
%D   leftrule=\linewidth,
%D   toprule=2\linewidth,
%D   rightrule=3\linewidth,
%D   bottomrule=4\linewidth,
%D   leftoffset=16mm,
%D   topoffset=8mm,
%D   rightoffset=4mm,
%D   bottomoffset=2mm,
%D   %topframe=off,
%D   %bottomframe=off,
%D   %leftframe=off,
%D   %rightframe=off,
%D   %corner=round,
%D   strut=no]
%D  {\framed[width=1cm,height=1cm]{}}
%D
%D \stopTEXpage
%D \stoptyping
%D
%D my second example shows why we realy need these extensions:
%D
%D \starttyping
%D \setupTABLE[frame=off,topframe=on,bottomframe=on]
%D \setupTABLE[row][first][toprule=1pt]
%D \setupTABLE[row][last][bottomrule=1pt]
%D
%D \setupTABLE[column][leftoffset=1em,rightoffset=1em]
%D \setupTABLE[column][first][leftoffset=0em,rightoffset=1em]
%D \setupTABLE[column][last][leftoffset=1em,rightoffset=0em]
%D
%D \setupTABLE[style={\switchtobodyfont[small]}] % why now bodyfont option?
%D
%D \bTABLE
%D   \bTR
%D     \bTH Knuth \eTH
%D     \bTH Zapf  \eTH
%D     \bTH Tufte \eTH
%D   \eTR
%D   \bTR
%D     \bTD \input knuth \eTD
%D     \bTD \input zapf  \eTD
%D     \bTD \input tufte \eTD
%D   \eTR
%D \eTABLE
%D \stoptyping


%\def\copylocalframed[#1]#2[#3]%
%  {\copyparameters[#1][#3]%
%     [\c!width,\c!height,\c!autowidth,\c!offset,\c!empty,\c!rulethickness,%
%      \c!radius,\c!corner,\c!depth,\c!frame,\c!framecolor,%
%      \c!foregroundstyle,\c!foregroundcolor,\c!lines,\c!orientation,%
%      \c!topframe,\c!bottomframe,\c!leftframe,\c!rightframe,%
%      \c!rulethickness,\c!frameoffset,\c!background,\c!component,%
%      \c!backgroundoffset,\c!backgroundscreen,\c!backgroundcolor,%
%      \c!align,\c!bottom,\c!top,\c!strut,\c!autostrut,\c!location,\c!setups,\c!extras]%
%   \copyparameters[#1\c!background][#1]%
%     [\c!radius,\c!corner,\c!depth]%
%   \copyparameters[#1\c!frame][#1]%
%     [\c!radius,\c!corner,\c!depth]}

\def\copylocalframed[#1]#2[#3]%
  {\copyparameters[#1][#3]%
     [\c!width,\c!height,\c!autowidth,\c!offset,\c!empty,\c!linestyle,%
      \c!radius,\c!corner,\c!depth,\c!frame,\c!framecolor,%
      \c!foregroundstyle,\c!foregroundcolor,\c!lines,\c!orientation,%
      \c!toprule,\c!bottomrule,\c!leftrule,\c!rightrule,% \c!...rulethickness!!!!!
      \c!topframe,\c!bottomframe,\c!leftframe,\c!rightframe,%
      \c!rulethickness,\c!frameoffset,\c!background,\c!component,%
      \c!leftoffset,\c!rightoffset,\c!topoffset,\c!bottomoffset,%
      \c!backgroundoffset,\c!backgroundscreen,\c!backgroundcolor,%
      \c!align,\c!bottom,\c!top,\c!strut,\c!autostrut,\c!location,\c!setups,\c!extras]%
   \copyparameters[#1\c!background][#1]%
     [\c!radius,\c!corner,\c!depth]%
   \copyparameters[#1\c!frame][#1]%
     [\c!radius,\c!corner,\c!depth]}

\setvalue{t\@@frame@@\v!on \v!on}{\hrule\!!height\ruledtoplinewidth\kern-\ruledtoplinewidth}
\setvalue{t\@@frame@@\v!off\v!on}{\hrule\!!height\ruledtoplinewidth\kern-\ruledtoplinewidth}
\setvalue{t\@@frame@@\v!on      }{\hrule\!!height\ruledtoplinewidth\kern-\ruledtoplinewidth}
\setvalue{b\@@frame@@\v!on \v!on}{\kern-\ruledbottomlinewidth\hrule\!!height\ruledbottomlinewidth}
\setvalue{b\@@frame@@\v!off\v!on}{\kern-\ruledbottomlinewidth\hrule\!!height\ruledbottomlinewidth}
\setvalue{b\@@frame@@\v!on      }{\kern-\ruledbottomlinewidth\hrule\!!height\ruledbottomlinewidth}
\setvalue{l\@@frame@@\v!on \v!on}{\vrule\!!width\ruledleftlinewidth\kern-\ruledleftlinewidth}
\setvalue{l\@@frame@@\v!off\v!on}{\vrule\!!width\ruledleftlinewidth\kern-\ruledleftlinewidth}
\setvalue{l\@@frame@@\v!on      }{\vrule\!!width\ruledleftlinewidth\kern-\ruledleftlinewidth}
\setvalue{r\@@frame@@\v!on \v!on}{\kern-\ruledrightlinewidth\vrule\!!width\ruledrightlinewidth}
\setvalue{r\@@frame@@\v!off\v!on}{\kern-\ruledrightlinewidth\vrule\!!width\ruledrightlinewidth}
\setvalue{r\@@frame@@\v!on      }{\kern-\ruledrightlinewidth\vrule\!!width\ruledrightlinewidth}

%D Before we start with the main thing let us introduce a few
%D \DIMENSIONS\ to save all new defined offsets and rule
%D parameters.

\newdimen\@@localleftoffset
\newdimen\@@localrightoffset
\newdimen\@@localtopoffset
\newdimen\@@localbottomoffset

\newdimen\ruledleftlinewidth
\newdimen\ruledrightlinewidth
\newdimen\ruledtoplinewidth
\newdimen\ruledbottomlinewidth

\def\startlocalframed[#1][#2]%
  {\bgroup
   \inframedtrue
   \edef\@@framed{#1}%
   % this piece of pre expansion is needed (sometimes used in frameoffset)
   % \doifvaluesomething{\@@framed\c!rulethickness}         % obsolete
   %   {\ruledlinewidth\getvalue{\@@framed\c!rulethickness}}% obsolete
   % this piece of pre expansion is needed (sometimes used circular)
   \setevalue{\@@framed\c!frameoffset}{\the\dimexpr\framedparameter\c!frameoffset\relax}%
   \doifnotvalue{\@@framed\c!backgroundoffset}\v!frame
     {\setevalue{\@@framed\c!backgroundoffset}{\the\dimexpr\framedparameter\c!backgroundoffset\relax}}%
   % to prevent deadlock in case of self refering
   \ifsecondargument % faster
     \getparameters[\@@framed][#2]% here !
   \fi
   % new, experimental dirty hook
   \framedparameter\c!extras
   % we need to register the (outer) color
   \startregistercolor[\framedparameter\c!foregroundcolor]%
   % to get the right spacing
   \doifvaluesomething{\@@framed\c!foregroundstyle}
     {\@EA\doconvertfont\csname\@@framed\c!foregroundstyle\endcsname\empty}%
   % beware, both the frame and background offset can be overruled
   %
   \edef\doframedsetups{\framedparameter\c!setups}%
   \ifx\doframedsetups\empty\else
     \edef\doframedsetups{\noexpand\setups[\doframedsetups]}%
   \fi
   % the next macros are visible
   \edef\localoffset      {\framedparameter\c!offset}%
   \edef\localleftoffset  {\framedparameter\c!leftoffset}%
   \edef\localrightoffset {\framedparameter\c!rightoffset}%
   \edef\localtopoffset   {\framedparameter\c!topoffset}%
   \edef\localbottomoffset{\framedparameter\c!bottomoffset}%
   % begin wolf: offset test for definition and presets
   \checkoffset\localleftoffset\c!leftoffset
   \checkoffset\localrightoffset\c!rightoffset
   \checkoffset\localtopoffset\c!topoffset
   \checkoffset\localbottomoffset\c!bottomoffset
   % end wolf
   \edef\localwidth {\framedparameter\c!width}%
   \edef\localheight{\framedparameter\c!height}%
   \edef\localformat{\framedparameter\c!align}%
   \edef\localstrut {\framedparameter\c!strut}%
   % these are not
   \edef\@@localautostrut  {\framedparameter\c!autostrut}%
   \edef\@@localframing    {\framedparameter\c!frame}%
   \edef\@@locallocation   {\framedparameter\c!location}%
   \edef\@@localorientation{\framedparameter\c!orientation}%
   %
   \edef\@@localautowidth  {\framedparameter\c!autowidth}%
   %
   \edef\localrule      {\framedparameter\c!rulethickness}%
   \edef\localleftrule  {\framedparameter\c!leftrule}%
   \edef\localrightrule {\framedparameter\c!rightrule}%
   \edef\localtoprule   {\framedparameter\c!toprule}%
   \edef\localbottomrule{\framedparameter\c!bottomrule}%
   %
   \ifx\@@localframing\v!overlay   % no frame, no offset, no framewidth
     \boxhasframefalse
     \let\localoffset\v!overlay
     % !!! to be fixed: wolf
     % !!! need a solution for this situation
     % !!! where is \v!overlay expanded into a real dimension
     % !!! causes a problem with \docollectortext in the details manual
     %\let\localleftoffset\v!overlay
     %\let\localrightoffset\v!overlay
     %\let\localtopoffset\v!overlay
     %\let\localbottomoffset\v!overlay
   \else\ifx\@@localframing\v!none % no frame, no framewidth
     \boxhasframefalse
   \else
     \boxhasframetrue
   \fi\fi
   \ifboxhasframe
     \doifvaluesomething{\@@framed\c!rulethickness}
       {\ruledlinewidth\framedparameter\c!rulethickness\relax
        \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi}%
     % begin wolf: test for rulethickness
     \checkrule\localleftrule\ruledleftlinewidth\c!leftrule
     \checkrule\localrightrule\ruledrightlinewidth\c!rightrule
     \checkrule\localtoprule\ruledtoplinewidth\c!toprule
     \checkrule\localbottomrule\ruledbottomlinewidth\c!bottomrule
     % end wolf
   \else
     \ruledlinewidth\zeropoint
     \ruledleftlinewidth\zeropoint
     \ruledrightlinewidth\zeropoint
     \ruledtoplinewidth\zeropoint
     \ruledbottomlinewidth\zeropoint
   \fi
   \ifx\localformat\empty
     \boxhasformatfalse
   \else
     \boxhasformattrue
     \dosetraggedcommand\localformat
     \edef\dobeforeframedbox{\raggedtopcommand\framedparameter\c!top}%
     \edef\doafterframedbox {\framedparameter\c!bottom\raggedbottomcommand}%
   \fi
   \ifx\localoffset\v!none
     \boxhasoffsetfalse
     \boxhasstrutfalse
     \boxisoverlaidfalse
     %\@@localoffset\ruledlinewidth % wolf: obsolete
     \@@localleftoffset\ruledleftlinewidth
     \@@localrightoffset\ruledrightlinewidth
     \@@localtopoffset\ruledtoplinewidth
     \@@localbottomoffset\ruledbottomlinewidth
   \else\ifx\localoffset\v!overlay
   % \ifx\@@localframing\v!no \boxhasframefalse \fi % test first
     \boxhasoffsetfalse
     \boxhasstrutfalse
     \boxisoverlaidtrue
     %\@@localoffset\zeropoint % wolf: obsolete
     \@@localleftoffset\zeropoint
     \@@localrightoffset\zeropoint
     \@@localtopoffset\zeropoint
     \@@localbottomoffset\zeropoint
   \else
     \boxhasoffsettrue
     \boxhasstruttrue
     \boxisoverlaidfalse
     \ifx\localoffset\v!default % new per 2-6-2000
       %\let\localoffset\defaultframeoffset % wolf: obsolete
       \let\localleftoffset\defaultframeoffset
       \let\localrightoffset\defaultframeoffset
       \let\localtopoffset\defaultframeoffset
       \let\localbottomoffset\defaultframeoffset
       % wolf: why this double setting?
       %\letvalue{\@@framed\c!offset}\defaultframeoffset
       %\letvalue{\@@framed\c!leftoffset}\defaultframeoffset
       %\letvalue{\@@framed\c!rightoffset}\defaultframeoffset
       %\letvalue{\@@framed\c!topoffset}\defaultframeoffset
       %\letvalue{\@@framed\c!bottomoffset}\defaultframeoffset
     \else
       \let\defaultframeoffset\localoffset
     \fi
     %\@@localoffset\dimexpr\localoffset+\ruledlinewidth\relax
     \@@localleftoffset\dimexpr\localleftoffset+\ruledleftlinewidth\relax
     \@@localrightoffset\dimexpr\localrightoffset+\ruledrightlinewidth\relax
     \@@localtopoffset\dimexpr\localtopoffset+\ruledtoplinewidth\relax
     \@@localbottomoffset\dimexpr\localbottomoffset+\ruledbottomlinewidth\relax
   \fi\fi
   \!!framedheight\zeropoint
   \!!framedwidth \zeropoint
   \ifx\localwidth\v!fit
     \ifboxhasformat
       \boxhaswidthtrue
       \!!framedwidth\hsize
     \else
       \boxhaswidthfalse
     \fi
   \else\ifx\localwidth\v!fixed % equals \v!fit but no shapebox
     \ifboxhasformat
       \boxhaswidthtrue
       \!!framedwidth\hsize
     \else
       \boxhaswidthfalse
     \fi
   \else\ifx\localwidth\v!broad
     \boxhaswidthtrue
     \!!framedwidth\hsize
   \else\ifx\localwidth\v!local
     \boxhaswidthtrue
     \setlocalhsize
     \!!framedwidth\localhsize
   \else
     \boxhaswidthtrue
     \!!framedwidth\localwidth
   \fi\fi\fi\fi
   \ifx\localheight\v!fit
     \boxhasheightfalse % no longer: \boxhasstrutfalse
   \else\ifx\localheight\v!broad
     \boxhasheightfalse
   \else
     \boxhasheighttrue
     \!!framedheight\localheight
   \fi\fi
   \ifboxhasheight
     % obey user set height, also downward compatible
   \else
     \doifvaluesomething{\@@framed\c!lines}
       {\ifcase\framedparameter\c!lines\else
          \!!framedheight\framedparameter\c!lines\lineheight
          \edef\localheight{\the\!!framedheight}%
          \boxhasheighttrue
        \fi}%
   \fi
   % this is now an option: width=local
   %
   % \ifdim\!!framedwidth=\hsize
   %   \parindent\zeropoint
   %   \setlocalhsize
   %   \!!framedwidth\localhsize
   % \fi
   % i.e. disable (colsetbackgroundproblemintechniek)
   %\advance\!!framedwidth  -2\@@localoffset % wolf: obsolete
   %\advance\!!framedheight -2\@@localoffset % wolf: obsolete
   \advance\!!framedwidth  -\@@localleftoffset
   \advance\!!framedwidth  -\@@localrightoffset
   \advance\!!framedheight -\@@localtopoffset
   \advance\!!framedheight -\@@localbottomoffset
   \ifx\localstrut\v!no
     \boxhasstrutfalse
   \else\ifx\localstrut\v!global
     \setstrut
   \else\ifx\localstrut\v!local
     \setfontstrut
   \else
   \fi\fi\fi
   \ifboxhasstrut
     \setstrut
     \let\localbegstrut\begstrut
     \let\localendstrut\endstrut
     \let\localstrut   \strut
   \else
     \let\localbegstrut\pseudobegstrut % was: \relax
     \let\localendstrut\pseudoendstrut % was: \relax
     \let\localstrut   \pseudostrut    % was: \relax
    %\ifboxhasheight\ifdim\!!framedheight<\strutht % saveguard
    %  \let\localbegstrut\relax               % but not that
    %  \let\localstrut   \relax               % save after all
    %\fi\fi
   \fi
   \ifx\@@localautostrut\v!yes
     \let\delayedbegstrut\relax
     \let\delayedendstrut\relax
     \let\delayedstrut   \relax
   \else
     \let\delayedbegstrut\localbegstrut
     \let\delayedendstrut\localendstrut
     \let\delayedstrut   \localstrut
     \let\localbegstrut  \relax
     \let\localendstrut  \relax
     \let\localstrut     \relax
   \fi
   \ifboxhasheight
     \let\\\vboxednewline
     \ifboxhaswidth
       \let\hairline\vboxedhairline
       \ifboxhasformat
         \let\next\doformatboxSomeFormat
       \else
         \let\next\doformatboxNoFormat
       \fi
     \else
       \let\hairline\hboxedhairline
       \ifboxhasformat
         \let\next\doformatboxHeight
       \else
         \let\next\doformatboxVSize
       \fi
     \fi
   \else
     \ifboxhaswidth
       \ifboxhasformat
         \let\hairline\vboxedhairline
         \let\\\vboxednewline
         \let\next\doformatboxWidth
       \else
         \let\hairline\hboxedhairline
         \let\\\hboxednewline
         \let\next\doformatboxHSize
       \fi
     \else
       \let\hairline\hboxedhairline
       \let\\\hboxednewline
       \let\next\doformatboxNoSize
     \fi
   \fi
   \edef\framedwidth % a new feature, visible for user
     {\ifdim\!!framedwidth >\zeropoint\the\!!framedwidth \else\zeropoint\fi}%
   \edef\framedheight% a new feature, visible for user
     {\ifdim\!!framedheight>\zeropoint\the\!!framedheight\else\zeropoint\fi}%
   % first alternative
   %\def\dowithframedbox%
   %  {\let\postprocessframebox\relax %new
   %   \aftergroup\stoplocalframed}%
   % \afterassignment\dowithframedbox
   % \setbox\framebox=\next}
   % second alternative
   %\dowithnextbox
   %  {\setbox\framebox\flushnextbox
   %   \let\postprocessframebox\relax %new
   %   \stoplocalframed}
   %  \next}
   % third alternative
   \@@startframedorientation
   \afterassignment\dodowithframebox
   \setbox\framebox\next}

%\def\dowidenframebox#1%
%  {\setbox\framebox\vbox
%     {\kern#1\hbox{\kern#1\box\framebox\kern#1}\kern#1}}

\def\dowidenframebox#1#2#3#4%
  {\setbox\framebox\vbox
     {\kern#1\hbox{\kern#2\box\framebox\kern#3}\kern#4}}

%\def\dooffsetframebox{\dowidenframebox\localoffset}
%\def\dolocateframebox{\dowidenframebox\ruledlinewidth}

\def\dooffsetframebox%
  {\dowidenframebox\localtopoffset\localleftoffset\localrightoffset\localbottomoffset}

\def\dolocateframebox%
  {\dowidenframebox\ruledtoplinewidth\ruledleftlinewidth\ruledrightlinewidth\ruledbottomlinewidth}

%D Using the offsets and rulethickness check is slower than
%D than using them directly in the \tex{localframed} macros.
%D Although I know this problem i will use the current method
%D an accept a few more microseconds processing time. 

\def\checkoffset#1#2%
  {\ifx#1\v!offset
     \edef#1{\framedparameter\c!offset}%
   \else
     \if#1\relax
       \edef#1{\framedparameter\c!offset}%
     \else
       \edef#1{\framedparameter#2}%
     \fi
   \fi}

\def\checkrule#1#2#3%
  {\ifx#1\v!rule
       \ifx\localrule\empty
     \else
       #2\localrule\relax
     \fi
   \else
     \if#1\relax
       #2\localrule\relax
     \else
       #2\the\dimexpr\framedparameter#3\relax
     \fi
   \fi}

\protect \endinput
