%D \module
%D   [       file=meta-nod,
%D        version=2016.11.23,
%D          title=\METAPOST\ Graphics,
%D       subtitle=Nodes,
%D         author={Alan Braslau and 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.

\registerctxluafile{meta-nod}{}

\unprotect

\defineMPinstance
  [nodes]
  [\s!format=metafun,
   \s!extensions=\v!yes,
   \s!initializations=\v!yes,
   \c!method=\s!double]

\defineframed
  [node]
  [\c!frame=\v!off]

\defineframed
  [smallnode]
  [node]
  [\c!foregroundstyle=\small]

% \startMPdefinitions{nodes}
%     loadmodule "node" ;
% \stopMPdefinitions

\protect

%D This module provides a simple \TEX\ layer on top of the nodes library that is
%D preloaded in \METAFUN. More information can be found in the manual and article.
%D
%D We strongly advice to use the \METAPOST\ interface and only provide this \TEX\
%D variant as proof of concept. There are no plans to extend this module because we
%D see no advantage in using a \TEX\ interface over a \METAPOST\ one.
%D
%D \startbuffer
%D \startnodes
%D    \placenode[0,0]{A}
%D    \placenode[1,0]{B}
%D    \connectnodes [0,1] [option=doublearrow]
%D \stopnodes
%D
%D \startnodes[dx=2cm,rotation=45]
%D    \placenode[0,0]{A}
%D    \placenode[1,0]{B}
%D    \placenode[1,1]{C}
%D    \placenode[0,1]{D}
%D    \connectnodes [0,2] [option=doublearrow,label=a,offset=.05]
%D    \connectnodes [1,3] [option=doublearrows]
%D \stopnodes
%D
%D \startnodes[dx=2cm,dy=2cm]
%D    \nodeMPcode{ahlength  := 12pt ; ahangle := 30 ; ahvariant := 1 ;}
%D    \mpcode{ahlength  := 12pt ; ahangle := 30 ; ahvariant := 1 ;}
%D    \placenode[0,1]{\node{A}}
%D    \placenode[1,1]{\node{B}}
%D    \placenode[0,0]{\node{C}}
%D    \placenode[1,0]{\node{D}}
%D    \connectnodes [0,3] [option=arrow,label={ }]
%D    \connectnodes [1,2] [option=arrow]
%D \stopnodes
%D \stopbuffer
%D
%D \typebuffer
%D
%D \startlinecorrection \getbuffer \stoplinecorrection

\unprotect

\installcorenamespace{metanodes}
\installcorenamespace{metanodesoption}
\installcorenamespace{metanodesalternative}
\installcorenamespace{metanodesposition}

% todo: maybe instances

\installparameterhandler \??metanodes {metanodes}
\installsetuphandler     \??metanodes {metanodes}

\setupmetanodes
  [\c!option        =,
   \c!alternative   =,
   \c!offset        =0,
   \c!position      =,
   \c!label         =,
   \c!dx            =2\emwidth,
   \c!dy            =2\emwidth,
   \c!rotation      =90,
   \c!rulethickness =.5pt,
   \c!command       =]

\newtoks\t_every_meta_nodes
\newtoks\t_meta_nodes

%D Hm, we started out simple but it now quickly becomes the usual mess of \TEX,
%D \METAPOST\ and \LUA. Hard to understand.

\newinteger\c_meta_nodes_n

\lettonothing\p_meta_alternative
\lettonothing\p_meta_option

\permanent\protected\lettonothing\stopnodes

\permanent\tolerant\protected\def\startnodes[#1]#:#2\stopnodes
  {\hpack\bgroup
   \setupcurrentmetanodes[#1]%
   \edef\p_meta_option{\metanodesparameter\c!option}%
   \edef\p_meta_alternative{\metanodesparameter\c!alternative}%
   \expand\t_every_meta_nodes
   \c_meta_nodes_n\zerocount
   \t_meta_nodes\emptytoks
   #2\removeunwantedspaces
   % for alan, will be commented:
 % \writestatus{metanodes}{\detokenize\expandafter{\the\t_meta_nodes}}%
   \clf_grph_nodes_initialize
   \startMPcode
     mfun_node_init(%
        \todimension{\metanodesparameter\c!dx},%
        \todimension{\metanodesparameter\c!dy},%
        \metanodesparameter\c!rotation%
     ) ;
     \the\t_meta_nodes ;
     mfun_node_flush ;
   \stopMPcode
   \clf_grph_nodes_reset
   \egroup}

\permanent\tolerant\protected\def\grph_nodes_node[#1]#*[#2]%
  {\grph_nodes_node_indeed[#1][#2]}

\def\grph_nodes_node_indeed[#1,#2][#3]#4%
  {\begingroup
   \setupcurrentmetanodes[#3]%
   \edef\p_label{#4}%
   \edef\p_reference{\metanodesparameter\c!reference}%
   \ifempty\p_reference\else
      \clf_grph_nodes_register{\p_reference}\c_meta_nodes_n\relax
   \fi
   \expanded{\endgroup\noexpand\etoksapp\t_meta_nodes{%
     mfun_node_make(\number#1,\number#2%
       \ifempty\p_label
         ,""%
       \else
         ,"\metanodesparameter\c!command{\p_label}"%
       \fi
     );%
   }}%
   \advanceby\c_meta_nodes_n\plusone}

\permanent\protected\lettonothing\placenode

\appendtoks
   \enforced\let\placenode\grph_nodes_node
\to \t_every_meta_nodes

\permanent\tolerant\protected\def\grph_nodes_fromto[#1]#*[#2]%
  {\grph_nodes_fromto_indeed[#1][#2]}% get rid of {n,m} % todo: we can use #_ or so

\letcsname\??metanodesposition            \endcsname\empty
\defcsname\??metanodesposition         top\endcsname{.top}
\defcsname\??metanodesposition      bottom\endcsname{.bot}
\defcsname\??metanodesposition        left\endcsname{.lft}
\defcsname\??metanodesposition       right\endcsname{.rt}
\defcsname\??metanodesposition   upperleft\endcsname{.ulft}
\defcsname\??metanodesposition     topleft\endcsname{.ulft}
\defcsname\??metanodesposition     lefttop\endcsname{.ulft}
\defcsname\??metanodesposition  upperright\endcsname{.urt}
\defcsname\??metanodesposition    topright\endcsname{.urt}
\defcsname\??metanodesposition    righttop\endcsname{.urt}
\defcsname\??metanodesposition   lowerleft\endcsname{.llft}
\defcsname\??metanodesposition  bottomleft\endcsname{.llft}
\defcsname\??metanodesposition  leftbottom\endcsname{.llft}
\defcsname\??metanodesposition  lowerright\endcsname{.lrt}
\defcsname\??metanodesposition bottomright\endcsname{.lrt}
\defcsname\??metanodesposition rightbottom\endcsname{.lrt}

\def\grph_nodes_fromto_indeed[#1,#2][#3]% we can't group because etoksapp doesn't like that
  {\begingroup
   \setupcurrentmetanodes[#3]%
   \edef\p_label        {\metanodesparameter\c!label}%
   \edef\p_rulethickness{\metanodesparameter\c!rulethickness}%
   \edef\p_command      {\metanodesparameter\c!command}% better get an error early
   \expanded{\endgroup\noexpand\etoksapp\t_meta_nodes{%
     \ifcsname\??metanodesalternative\metanodesparameter\c!alternative\endcsname
       \lastnamedcs
     \else
       \csname\??metanodesalternative\endcsname
     \fi
     \space
     mfun_nodes_fromto\begincsname\??metanodesposition\metanodesparameter\c!position\endcsname(%
       \metanodesparameter\c!offset,%
     % \number#1,\number#2%
       \clf_grph_nodes_resolve{#1},\clf_grph_nodes_resolve{#2}%
       \ifempty\p_label
         ,""%
       \else
         ,"\ifempty\p_command\p_label\else\p_command{\p_label}\fi"%
       \fi
     )%
     \space
     \ifcsname\??metanodesoption\metanodesparameter\c!option\endcsname
       \lastnamedcs
     \else
       \csname\??metanodesoption\endcsname
     \fi
     \space
     \ifempty\p_rulethickness \else
       withpen pencircle scaled \todimension{\p_rulethickness} %
     \fi
     ;%
   }}}

\defcsname\??metanodesalternative             \endcsname{draw}
\defcsname\??metanodesalternative        arrow\endcsname{drawarrow}
\defcsname\??metanodesalternative  doublearrow\endcsname{drawdblarrow}
\defcsname\??metanodesalternative doublearrows\endcsname{drawdoublearrows}

\defcsname\??metanodesoption                  \endcsname{}
\defcsname\??metanodesoption            dashed\endcsname{dashed evenly}
\defcsname\??metanodesoption            dotted\endcsname{dashed withdots scaled .5}

\permanent\protected\lettonothing\connectnodes
\permanent\protected\lettonothing\mpcode
\permanent\protected\lettonothing\nodeMPcode

\appendtoks
   \enforced\let\connectnodes\grph_nodes_fromto
\to \t_every_meta_nodes

\permanent\protected\def\grph_nodes_code#1%
  {\etoksapp\t_meta_nodes{#1}}

\appendtoks
   \enforced\let\nodeMPcode\grph_nodes_code
   \enforced\let\mpcode    \grph_nodes_code
\to \t_every_meta_nodes

\protect \endinput
