%D \module
%D   [       file=core-nav,
%D        version=1998.01.15,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Navigation,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%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 Core Macros / Navigation}

\unprotect

%D Support for interactive document is very present in
%D \CONTEXT\ and interwoven in many modules. This means that in
%D this module, where we deal with some common navigational
%D features, there will be quite some forward references.
%D
%D When I started implementing hypertext support, the macros
%D were mostly dealing with things related to locations, that
%D is click in this location and goto that one. The
%D functionality of many macro depends on the output medium:
%D paper or screen. The next boolean holds the state:

\newif\iflocation  \def\ifinteractief{\iflocation} % upw comp

%D We also allocate a scratchbox:

\newbox\locationbox

%D There is no interaction at all unless enabled by saying:
%D
%D \starttyping
%D \setupinteraction[state=start]
%D \stoptyping
%D
%D The other settings are:
%D
%D \showsetup{setupinteraction}
%D
%D In the special driver modules we introduced a switch that
%D forces page destinations (instead of named ones). We set
%D this switch here.

\def\setinteractionparameter#1#2% use with case, no checking done
  {\setvalue{\??ia#1}{#2}}      % pass #2, can be \blabla

\def\resetinteractionparameter#1% use with case, no checking done
  {\letvalue{\??ia#1}\empty}

% \def\interactionparameter#1%
%   {\csname\??ia#1\endcsname}

\newtoks\everysetupinteraction

\def\setupinteraction
  {\dosingleargument\dodosetupinteraction}

\def\dodosetupinteraction[#1]% % \dosetupinteraction == special
  {\getparameters[\??ia][#1]%
   \the\everysetupinteraction}

% todo, move partial append to where the action happens

\appendtoks
  \doifelse\@@iastate\v!start
    {\iflocation\else
       \showmessage\m!interactions2{\ifusepagedestinations\space(PAGE)\fi}%
       \global\locationtrue
     \fi}
    {\iflocation
       \showmessage\m!interactions3{\ifusepagedestinations\space(PAGE)\fi}%
       \global\locationfalse
     \fi}%
  \iflocation
    \setsystemmode  \v!interaction
  \else
    \resetsystemmode\v!interaction
  \fi
  \dosetuppageview\@@iafocus
  \doifsomething\@@iacalculate
    {\doregistercalculationset\@@iacalculate}%
  \doifelse\@@iastrut\v!yes
    \locationstruttrue
    \locationstrutfalse
  \doifelse\@@iaclick\v!yes
    \highlighthyperlinkstrue
    \highlighthyperlinksfalse
  \doifelse\@@iasplit\v!yes
    \locationsplittrue
    \locationsplitfalse
  \doifelse\@@iadisplay\v!new
    \gotonewwindowtrue
    \gotonewwindowfalse
  \doifelse\@@iapage\v!yes
    {\global\usepagedestinationstrue}
    {\global\usepagedestinationsfalse}%
\to \everysetupinteraction

%D We have to make sure of some settings:

\def\dolocationstartup
  {\iflocation
     \dosetupinteraction
     \handlereferenceactions\@@iaopenaction \dosetupopenaction
     \handlereferenceactions\@@iacloseaction\dosetupcloseaction
     \setupinteractionscreens
     \global\let\dolocationstartup\relax
   \fi}

\appendtoks \dolocationstartup \to \everyshipout

\def\dolocationpagecheck % brr pdf dependent
  {\iflocation
     \handlereferenceactions\@@iaopenpageaction \dosetupopenpageaction
     \handlereferenceactions\@@iaclosepageaction\dosetupclosepageaction
   \fi}

\appendtoks \dolocationpagecheck \to \everyshipout

%D The next few macros are really horrible. For proper
%D navigation a in||line hypertext fragment must have
%D comfortable properties, so we must force some minimal
%D dimensions. On the other hand button, and here I mean those
%D pieces of text with fancy outlines and/or backgrounds, often
%D have fixed, preset dimensions.
%D
%D To make things even worse, if we choose to let the optimal
%D dimensions depend on the height and depth of a strut, a not
%D too uncommon practice in \TEX, we have to deal with the fact
%D that such a strut, set inside a box, is unknown too the
%D outside world.
%D
%D The solution lays in passing the strut characteristics in
%D a proper way, in our case by applying \type{\presetgoto}:
%D
%D \starttyping
%D {some piece of text \presetgoto}
%D \stoptyping
%D
%D This macro stores the current strut values.

\newif\iflocationstrut
\newif\iflocationsplit

\def\resetgoto
  {\globallet\@@ia@@hoogte\!!zeropoint
   \globallet\@@ia@@diepte\!!zeropoint}

\resetgoto

\def\presetgoto
  {\iflocationstrut
     \setstrut
    %\xdef\@@ia@@hoogte{\the\strutht}%
    %\xdef\@@ia@@diepte{\the\strutdp}%
     \globallet\@@ia@@hoogte\strutheight
     \globallet\@@ia@@diepte\strutdepth
   \else
     \globallet\@@ia@@hoogte\@@iaheight
     \globallet\@@ia@@diepte\@@iadepth
   \fi}

%D In the macros that deal with making areas into hyperlinks,
%D we use:

\newbox\driverresources

\def\collectdriverresource#1%
  {\global\setbox\driverresources\hbox{\box\driverresources#1}}

\def\flushdriverresources
  {\ifvoid\driverresources\else\box\driverresources\fi}

\def\dohandlegoto#1#2#3%
  {\ifsecondaryreference
     \bgroup\setbox0\hbox{#2#3}\egroup
   \else
     \hbox
       {\setbox0\hbox{#1}%
        \ifdim\wd0<\@@iawidth\relax
          \buttonwidth\@@iawidth\relax
        \else
          \buttonwidth\wd0
        \fi
        \ifdim\ht0<\@@ia@@hoogte\relax
          \buttonheight\@@ia@@hoogte\relax
        \else
          \buttonheight\ht0
        \fi
        \ifdim\dp0<\@@ia@@diepte\relax
          \dimen0=\@@ia@@diepte\relax % = !
        \else
          \dimen0\dp0
        \fi
        \advance\buttonheight \dimen0
        \setbox2\hbox
          {\lower\dimen0\hbox
             {\dontcomplain
              \dimen0=.5\wd0 % direct skipping is faster of course
              \advance\dimen0 -.5\buttonwidth % buts this is nicer
              \hskip\dimen0#2#3}}% when visualizing things
        \naturalhbox % needed for omega / moved from plus-omg
          {\ifreversegoto
             \dimen0\wd0\box0\kern-\dimen0\smashbox2\box2\kern\dimen0
           \else
             \smashbox2\box2\box0
           \fi
           \flushdriverresources}%
        \resetgoto}%
   \fi}

%D The secondary references are processed but not typeset. The
%D special driver must collect the data needed.

%D The width of the active area depends on the dimensions
%D preset, the actual dimens and/or the height and depth of the
%D strut.
%D
%D Normally the hyper active area is laid on top of the text.
%D This enables stacking hyperlinks on top of each other. When,
%D for some reason the opposite is prefered, one can use the
%D next boolean to signal this wish.

\newif\ifreversegoto \reversegotofalse

%D As long as there a natural feeling of what can be considered
%D hyper active or not, we have to tell users where they can
%D possibly click. We've already seen a few macros that deal
%D with this visualization, something we definitely do not let
%D up to the viewer. One way of telling is using a distinctive
%D typeface, another way is using color.
%D
%D There are two colors involved: one for normal hyperlinks,
%D and one for those that point to the currentpage, the
%D contrast color.

\definecolor [interactioncolor]         [r=0,  g=.6, b=0]
\definecolor [interactioncontrastcolor] [r=.8, g=0,  b=0]

\definecolor [interactiekleur]          [interactioncolor]
\definecolor [interactiecontrastkleur]  [interactioncontrastcolor]

%D The next few macros are responsible for highlighting hyper
%D links. The first one, \type{\showlocation}, is used in those
%D situations where the typeface is handled by the calling
%D macro.

\def\interactioncolor
  {\iflocation
     \ifrealreferencepage
       \@@iacontrastcolor
     \else
       \@@iacolor
     \fi
   \fi}

%D CHECK WHERE USED / CONSISTENCY

\def\showlocation#1%
  {\iflocation\color[\@@iacolor]{#1\presetgoto}\else#1\fi}

%D When local color settings are to be used, we can use the
%D next macro, where \type{#1} is a tag like \type{\??tg} and
%D \type{#2} some text.

\def\showcoloredlocation#1#2%
  {\iflocation
     \color[\getvalue{#1\c!color}]{#2\presetgoto}%
   \else
     #2%
   \fi}

%D When we're dealing with pure page references, contrast
%D colors are used when we are already at the page mentioned.

\def\showcontrastlocation#1#2#3% the \@EA is needed
  {\iflocation
     \ifnum#2=\realpageno\relax
       \doifelsevaluenothing{#1\c!color}
         {#3\presetgoto}
         {\color[\getvalue{#1\c!contrastcolor}]{#3\presetgoto}}%
     \else
       \color[\getvalue{#1\c!color}]{#3\presetgoto}%
     \fi
   \else
     #3%
   \fi}

%D The next simple macro can be used in color specifications,
%D like \type{\color[\locationcolor{green}]}.

\def\locationcolor#1%
  {\iflocation#1\fi}

%D More tokens are spend when we want both typeface and color
%D highlighting.

\def\dolocationattributes#1#2#3#4%
  {\bgroup
   \let\fontattribute\empty
   \let\colorattribute\empty
   \doifdefined{#1#2}{\def\fontattribute{\getvalue{#1#2}}}%
   \iflocation
     \doifdefined{#1#3}{\def\colorattribute{\getvalue{#1#3}}}%
   \fi
   \startcolor[\colorattribute]%
   \@EA\doconvertfont\@EA{\fontattribute}{#4}% no \edef, but \@EA here
   \stopcolor
   \egroup}

\def\navigating
  {\dolocationattributes\??ia\c!style\c!color}

%D Although not decently supported in current viewers, a
%D provisory hiding mechanims is implemented. Areas marked as
%D such, are visible on screen, but invisible on paper. Don't
%D trust this mechanism yet!

\def\dostartinteraction
  {\bgroup
   \let\stopinteraction\egroup
   \dowithnextbox{\dostarthide\flushnextbox\dostophide\egroup}\hbox}

\let\startinteraction = \relax
\let\stopinteraction  = \relax

% in the future:
%
% eerst boolean invoeren bij menu, achtergrond, balk, button
% enz; verder startinteractie een argument meegeven {#1} ->
% \getvalue{#1\c!print}=={\v!ja} enz. Consequent menubutton
% gebruiken!

\def\@@iatimestamp
  {\the\normalyear
   \ifnum\normalmonth<10 0\fi\the\normalmonth
   \ifnum\normalday  <10 0\fi\the\normalday}

% happens in core-fld
%
% \definereference [AtOpenInitializeForm] [\v!geen]

\setupinteraction % start fit page and reset form
  [\c!state=\v!stop,
   \c!page=\v!no,
   \c!click=\v!yes,
   \c!display=,
  %\c!openaction={\v!firstpage,AtOpenInitializeForm},
  %\c!openaction={\v!firstpage,\v!ResetForm},
  %\c!openaction=\v!ResetForm, % too buggy in reader 4.05
   \c!openaction=,
   \c!closeaction=,
   \c!openpageaction=,
   \c!closepageaction=,
   \c!display=\v!normal,
   \c!focus=\v!fit,
   \c!menu=\v!off,
   \c!style=\v!bold,
   \c!calculate=,
   \c!strut=\v!yes,
   \c!split=\v!yes,
   \c!color=interactioncolor,
   \c!contrastcolor=interactioncontrastcolor,
   \c!symbolset=,
   \c!width=1em,
   \c!height=\!!zeropoint,
   \c!depth=\!!zeropoint,
   \c!title=\jobname, % needed for fdf/x
   \c!subtitle=,
   \c!author=,
   \c!keyword=,
   \c!date=\@@iatimestamp]

\protect \endinput
