% Copyright 2018 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster
% Copyright 2018 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Public License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.

\ProvidesFileRCS{pgflibrarygraphdrawing.code.tex}



% check if luatex is running

\ifx\directlua\relax%
  \pgferror{You need to run LuaTeX to use the graph drawing library}
  \expandafter\endinput
\fi
\ifx\directlua\undefined%
  \pgferror{You need to run LuaTeX to use the graph drawing library}
  \expandafter\endinput
\fi




%
% All graph drawing keys normally live in the following namespace:
% /graph drawing.
%

\def\pgfgdset{\pgfqkeys{/graph drawing}}%


% Setup a key
%
% #1 = key
%
% Description:
%
% An internal macro that sets up #1 as a graph drawing key.

\def\pgfgd@callbackkey#1{%
  \pgf@gd@setup@forwards{#1}%
  \pgfutil@g@addto@macro\pgf@gd@forwards@list{\pgf@gd@setup@forwards{#1}}%
}%
\def\pgf@gd@setup@forwards#1{%
  \let\pgf@temp\pgfutil@empty
  \foreach \pgf@gd@path in \pgf@gd@forwarding@list {%
    \ifx\pgf@gd@path\pgfutil@empty\else%
      \expandafter\pgfutil@g@addto@macro%
      \expandafter\pgf@temp\expandafter{%
        \expandafter\pgfkeys\expandafter{\pgf@gd@path#1/.forward to=/graph drawing/#1}}%
    \fi%
  }%
  \pgf@temp
}%

\let\pgf@gd@forwards@list\pgfutil@empty


% Append to the forwarding list:
%
% #1 = paths to append to the forwarding list
%
% Description:
%
% Append the paths in #1 (with trailing slashes) to the forwarding
% list.
%
% If algorithms have already been declared, forwarding will also be
% setup for them (using a bit of magic...).

\def\pgfgdappendtoforwardinglist#1{%
  \let\pgf@gd@forwarding@list@orig\pgf@gd@forwarding@list
  \def\pgf@gd@forwarding@list{#1}%
  \pgf@gd@forwards@list%
  \expandafter\def\expandafter\pgf@gd@forwarding@list\expandafter{\pgf@gd@forwarding@list@orig,#1}%
}%
\let\pgf@gd@forwarding@list\pgfutil@empty



%
%
% Callbacks
%
% The following macros are called *from* the binding layer. You do not
% call them from the pgf layer.
%
%


% Callback for declaring a graph parameter key
%
% #1 = Parameter key
% #2 = Parameter type
%
% Description:
%
% When a graph drawing algorithm starts working, a set of options,
% called "graph drawing parameters" in the following, can influence the
% way the algorithm works. For instance, an graph drawing parameter
% might be the average distance between vertices which the algorithm
% should take into account. Another example might be the fact the
% certain nodes are special nodes and that a certain edge should have
% a large label.
%
% These graph drawing parameters are different from "usual" pgf
% options: An algorithmic parameter influenced the way the algorithm
% works, while usual options normally only influence how the result
% looks like. For instance, the fact that a node is red is not an
% graph drawing parameter (usually, at least), while the shape of a node
% might be an graph drawing parameter.
%
% Graph drawing parameters are declared by the algorithmic layer
% (since only this layer "knows" which parameters there are). The
% binding to TeX will call the \pgfgddeclareparameter function
% internally.
%
% Specifying the set of graph drawing parameters for a given graph or
% node or edge works as follows: When the graph drawing engine is
% started for a graph (using \pgfgdbeginscope), a snapshot is taken of
% all graph drawing parameters currently setup at this
% point. Similarly, when a node is created inside such a scope, a
% snapshot is taken of the set of all graph drawing parameters in
% force at this point is taken and stored together with the
% node. Finally, when an edge is created, a snapshot of the setting of
% the graph drawing parameters is taken.

\def\pgfgdcallbackdeclareparameter#1#2{%
  \pgfkeysdef{/graph drawing/#1}{\pgf@gd@handle@parameter{#1}{#2}{##1}}%
  \pgfgd@callbackkey{#1}%
}%
\def\pgf@gd@handle@parameter#1#2#3{%
  \def\pgf@temp{#3}%
  \ifx\pgf@temp\pgfkeysnovalue@text%
    \let\pgfgdresult\pgfgd@niltext%
  \else%
    \pgfkeys{/graph drawing/conversions/#2={#3}}%
  \fi%
  \advance\pgf@gd@parameter@stack@height by1\relax%
  \pgf@gd@parameter@stack@height\directlua{%
    local new, main = pgf.gd.interface.InterfaceToDisplay.pushOption('\pgfutil@luaescapestring{#1}',\pgfgdresult,\the\pgf@gd@parameter@stack@height)
    tex.print(new..'\pgfutil@luaescapestring{\relax}')
    if main then
      tex.print('\pgfutil@luaescapestring{\noexpand\pgfgdtriggerrequest}')
    end}%
}%
\newcount\pgf@gd@parameter@stack@height

\def\pgfgdtriggerrequest{\pgfgdset{@request scope and layout}}%


% Conversions are used to adapt the syntactic description of a
% parameter on the TikZ layer to the one expected by Lua. The set of
% permissible conversions is described in
% InterfaceToAlgorithms.declareParameter.

\pgfgdset{
  conversions/string/.code=\def\pgfgdresult{'\pgfutil@luaescapestring{\detokenize{#1}}'},
  conversions/raw/.code=\def\pgfgdresult{#1},
  conversions/nil/.code=\let\pgfgdresult\pgfgd@niltext,
  conversions/boolean/.code=\def\pgf@test{#1}\ifx\pgf@test\pgf@truetext\def\pgfgdresult{true}\else\ifx\pgf@test\pgfkeysnovalue@text\def\pgfgdresult{true}\else\def\pgfgdresult{false}\fi\fi,
  conversions/number/.code=\pgfmathparse{#1}\let\pgfgdresult\pgfmathresult,
  conversions/length/.code=\pgfmathparse{#1}\let\pgfgdresult\pgfmathresult,
  conversions/time/.code=\pgfparsetime{#1}\let\pgfgdresult\pgftimeresult,
  conversions/direction/.code=\pgf@lib@gd@grow@dir{#1}\let\pgfgdresult\pgfmathresult,
  conversions/canvas coordinate/.code args={(#1pt,#2pt)}{\edef\pgfgdresult{pgf.gd.model.Coordinate.new(#1,#2)}},
  % deprecated, will be removed:
  conversions/coordinate/.code args={(#1pt,#2pt)}{\edef\pgfgdresult{{#1,#2}}}
}%
\def\pgf@truetext{true}%
\def\pgfgd@niltext{nil}%

\def\pgf@lib@gd@grow@dir#1{%
  \def\pgf@temp{#1}%
  \ifx\pgf@temp\pgf@gd@lib@active@bar%
    \def\pgfmathresult{-90}
  \else%
    \ifcsname pgf@orient@direction@#1\endcsname%
      \expandafter\let\expandafter\pgfmathresult\csname pgf@orient@direction@#1\endcsname%
    \else
      \pgfmathparse{#1}%
    \fi
  \fi
}%

\def\pgf@orient@direction@down{-90}%
\def\pgf@orient@direction@up{90}%
\def\pgf@orient@direction@left{180}%
\def\pgf@orient@direction@right{0}%

\def\pgf@orient@direction@south{-90}%
\def\pgf@orient@direction@north{90}%
\def\pgf@orient@direction@west{180}%
\def\pgf@orient@direction@east{0}%

\expandafter\def\csname pgf@orient@direction@north east\endcsname{45}%
\expandafter\def\csname pgf@orient@direction@north west\endcsname{135}%
\expandafter\def\csname pgf@orient@direction@south east\endcsname{-45}%
\expandafter\def\csname pgf@orient@direction@south west\endcsname{-135}%

\expandafter\def\csname pgf@orient@direction@-\endcsname{0}%
\expandafter\def\csname pgf@orient@direction@|\endcsname{-90}%

{%
  \catcode`\|=13
  \gdef\pgf@gd@lib@active@bar{|}%
}%





% Callback for starting the rendering of a collection kind
%
% #1 = Kind
% #2 = Layer
%
% Description:
%
% Executes /graph drawing/#1/begin rendering/.try
%

\def\pgfgdcallbackrendercollectionkindstart#1#2{%
  \ifnum#2<0\relax
    \setbox\pgf@gd@prekind@box=\hbox\bgroup%
    \unhbox\pgf@gd@prekind@box%
  \else%
    \setbox\pgf@gd@postkind@box=\hbox\bgroup%
    \unhbox\pgf@gd@postkind@box%
  \fi%
  \pgfgdset{/graph drawing/#1/begin rendering/.try}%
}%

% Callback for ending the rendering of a collection kind
%
% #1 = Kind
% #2 = Layer
%
% Description:
%
% Executes /graph drawing/#1/end rendering/.try
%

\def\pgfgdcallbackrendercollectionkindstop#1#2{%
  \pgfgdset{/graph drawing/#1/end rendering/.try}%
  \egroup % close box
}%



% Callback for rendering a collection
%
% #1 = Kind
% #2 = Options
%
% Description:
%
% Executes /graph drawing/#1/render/.try={#2}
%

\def\pgfgdcallbackrendercollection#1#2{
  \pgfgdset{/graph drawing/#1/render/.try={#2}}
}%





% Graph events
%
% Although a graph consists of nodes and edges, during the
% construction of the graph a lot of information concerning the
% structure of the graph is often available. For instance, as we
% specify a graph using the child-syntax, we do not only which edges
% are present, but we can implicitly specify an ordering on the
% nodes. Even more, there is even information available concerning
% nodes that are not present at all: A child[missing] is not present
% as a node or an edge, but a tree drawing algorithm will want to know
% about this child nevertheless.
%
% In order to communicate such information to the graph drawing
% engine, "events" are used. As a graph is created, in addition to
% nodes and edges, "events" may happen. The events come in a
% sequential order and they are stored together with the graph. For
% each node and each edge, its index in the event sequence is
% stored, that is, it is stored how many events happened before the
% node or edge was created.
%
% Internally, an event consists of a name and, possibly, some
% parameters. When the parameter is created on the tikz level, it will
% be a string that is passed down to Lua. Internally created events
% will also have parameters that are objects.
%
% Two events are a bit special since they get special internal
% support: The begin and end events. The first signals that some kind
% of group has started; which is closed by the corresponding end
% event. The "kind" of group is indicated by the parameter of the
% begin event.
%
%
%
% Standard events are:
%
% For each node entered into a graph, a "node" event is automatically
% created internally with the parameter being the node. However, you
% can also create this event yourself. In this case, the parameter
% will be a string and will mean that the node is "virtual" or
% "missing", but space should be reserved for it, if possible (this is
% use, for instance, by certain tree layouts).
%
% For each edge entered into a graph, an "edge" event is automatically
% created, with the edge as the parameter. Again, an event with a
% string parameter corresponds to a "non-existing" node.
%
%
% Standard event groups are:
%
%
% The "descendants" event group include a set of nodes that, at least
% inside the specification, are descendants of the last node
%
% begin descendants
% ...
% end
%
%
% The "array" event group collects together some nodes in an array of
% nodes. This can be used, for instance, to specify matrices.
%
% begin array
% ...
% end



% Create a new event
%
% #1 = event name (should be a valid lua identifier name)
% #2 = parameter (some text)
%
% Description:
%
% Adds a new event to the event sequence of the graph

\def\pgfgdevent#1#2{%
  \directlua{pgf.gd.interface.InterfaceToDisplay.createEvent('\pgfutil@luaescapestring{#1}', '\pgfutil@luaescapestring{#2}')}%
}%


% Start an event group
%
% #1 = kind of event group
%
% Description:
%
% Creates a begin event with #1 as the parameter of the begin
% event.

\def\pgfgdbegineventgroup#1{%
  \pgfgdevent{begin}{#1}%
}%

% End an event group
%
% Description:
%
% Creates an end event.

\def\pgfgdendeventgroup{%
  \pgfgdevent{end}{}%
}%


% Creates an event group for the current TeX group
%
% #1 = event group name
%
% Description:
%
% Issues a begin event for #1 and, using \aftergroup, adds an end
% event at the end of the current tex group.

\def\pgfgdeventgroup#1{%
  \pgfgdbegineventgroup{#1}%
  \aftergroup\pgfgdendeventgroup%
}%





%
% Nodes
%



%
% Callback method for \pgfpositionnodelater
%
% This function is called by \pgfnode whenever a node has been newly
% created inside a graph drawing scope. It will create a new vertex on
% the Lua layer.
%
\def\pgf@gd@positionnode@callback{%
  {%
    % evaluate coordinates
    \pgfmathsetmacro{\pgf@gd@node@minx}{\pgfpositionnodelaterminx}%
    \pgfmathsetmacro{\pgf@gd@node@miny}{\pgfpositionnodelaterminy}%
    \pgfmathsetmacro{\pgf@gd@node@maxx}{\pgfpositionnodelatermaxx}%
    \pgfmathsetmacro{\pgf@gd@node@maxy}{\pgfpositionnodelatermaxy}%
    % Assemble the Path object:
    \directlua{pgf.temp = require 'pgf.gd.model.Path'.new ()}%
    \let\pgfsyssoftpath@movetotoken\pgf@gd@movetotoken%
    \let\pgfsyssoftpath@linetotoken\pgf@gd@linetotoken%
    \let\pgfsyssoftpath@rectcornertoken\pgf@gd@rectcornertoken%
    \let\pgfsyssoftpath@curvetosupportatoken\pgf@gd@curvetosupportatoken%
    \let\pgfsyssoftpath@closepathtoken\pgf@gd@closepathtoken%
    \pgfpositionnodelaterpath%
    %
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
    %
    {%
      \pgf@process{\pgfpointanchor{\pgfpositionnodelatername}{center}}
      \pgfsettransform{\csname pgf@sh@nt@\pgfpositionnodelatername\endcsname}%
      \pgf@pos@transform{\pgf@x}{\pgf@y}%
      \global\pgf@x=\pgf@x%
      \global\pgf@y=\pgf@y%
    }%
    % call lua system library to create a lua node object
    \directlua{
      pgf.gd.interface.InterfaceToDisplay.createVertex(
        string.sub('\pgfutil@luaescapestring{\pgfpositionnodelatername}',30), % strip "not yet positionedPGFINTERNAL"
        '\pgfutil@luaescapestring{\csname pgf@sh@ns@\pgfpositionnodelatername\endcsname}',
        pgf.temp:pad((\pgf@sys@tonumber\pgf@xa+\pgf@sys@tonumber\pgf@ya)/2), % Padded path
        \the\pgf@gd@parameter@stack@height, % Stack height
        {% Binding info
          x_min = \pgf@gd@node@minx,
          y_min = \pgf@gd@node@miny,
          x_max = \pgf@gd@node@maxx,
          y_max = \pgf@gd@node@maxy,
          tex_box_number = \pgfpositionnodelaterbox
        },
        {% Anchors
          center = require 'pgf.gd.model.Coordinate'.new(\pgf@sys@tonumber\pgf@x,\pgf@sys@tonumber\pgf@y)
        }
      )
      pgf.temp = nil
    }
  }%
}%


\def\pgf@gd@movetotoken#1#2{\directlua{pgf.temp:appendMoveto(\Pgf@geT#1,\Pgf@geT#2)}}%
\def\pgf@gd@linetotoken#1#2{\directlua{pgf.temp:appendLineto(\Pgf@geT#1,\Pgf@geT#2)}}%
\def\pgf@gd@rectcornertoken#1#2#3#4#5{%
  \directlua{%
    local x,y,dx,dy=\Pgf@geT#1,\Pgf@geT#2,\Pgf@geT#4,\Pgf@geT#5
    pgf.temp:appendMoveto(x,y)
    pgf.temp:appendLineto(x,y+dy)
    pgf.temp:appendLineto(x+dx,y+dy)
    pgf.temp:appendLineto(x+dx,y)
    pgf.temp:appendClosepath()%
  }%
}%
\def\pgf@gd@curvetosupportatoken#1#2#3#4#5#6#7#8{\directlua{pgf.temp:appendCurveto(\Pgf@geT#1,\Pgf@geT#2,\Pgf@geT#4,\Pgf@geT#5,\Pgf@geT#7,\Pgf@geT#8)}}%
\def\pgf@gd@closepathtoken#1#2{\directlua{pgf.temp:appendClosepath()}}%


% Set options for an already existing node
%
% #1 = node name
%
% These node parameters of #1 will be updated with the current values
% of the node parameters. The node #1 must previously have been passed
% to the gd engine. If some of the options have already been set for
% the node, these settings will be overruled.

\def\pgfgdsetlatenodeoption#1{%
  \directlua{
    pgf.gd.interface.InterfaceToDisplay.addToVertexOptions('\pgfutil@luaescapestring{#1}',\the\pgf@gd@parameter@stack@height)
  }
}%



%
% A callback for rendering (finally positioning) a node
%
% #1 = name of the node
% #2 = x min of the bounding box
% #3 = x max of the bounding box
% #4 = y min of the bounding box
% #5 = y max of the bounding box
% #6 = desired x pos of the node
% #7 = desired y pos of the node
% #8 = box register number of the TeX node
% #9 = animation code
%
% This callback will be called by the engine for every original node
% when it finally needs to placed at a final position.

\def\pgfgdcallbackrendernode#1#2#3#4#5#6#7#8#9{%
  {%
    \def\pgfpositionnodelatername{#1}
    \def\pgfpositionnodelaterminx{#2}
    \def\pgfpositionnodelatermaxx{#3}
    \def\pgfpositionnodelaterminy{#4}
    \def\pgfpositionnodelatermaxy{#5}
    \directlua{pgf.gd.interface.InterfaceCore.binding:retrieveBox(#8,\pgfpositionnodelaterbox)}
    \def\pgf@temp{#9}%
    \ifx\pgf@temp\pgfutil@empty%
      \pgfpositionnodenow{\pgfqpoint{#6}{#7}}%
    \else%
      \pgfset{every graphdrawing animation/.try}%
      \pgfset{every graphdrawing node animation/.try}%
      #9%
      \pgfuseid{pgf@gd}%
      \pgfidscope%
        \pgfpositionnodenow{\pgfqpoint{#6}{#7}}%
      \endpgfidscope%
    \fi%
  }%
}%

\ifx\pgfanimateattribute\pgfutil@undefined
  \def\pgfanimateattribute#1#2{\tikzerror{You need to say \string\usetikzlibrary{animations} for animated graphs}}%
\fi


% Adds an edge to the graph
%
% #1 = first node
% #2 = second node
% #3 = edge direction
% #4 = edge options (will be executed in a protected environment)
% #5 = aux stuff (courtesy for TikZ -- edge nodes)
%
% Description:
%
% Creating an edge means that you tell the graph drawing algorithm
% that #1 and #2 are connected. The "kind" of connection is indicated
% by #3, which may be one of the following:
%
% ->  = a directed edge (also known as an arc) from #1 to #2
% --  = an undirected edge between #1 and #2
% <-  = a directed edge from #2 to #1, but with the "additional hint"
%       that this is a "backward" edge. A graph drawing algorithm may
%       or may not take this hint into account
% <-> = a bi-directed edge between #1 and #2.
%
%
% The parameters #4 and #5 are a bit more tricky. When an edge between
% two vertices of a graph is created via \pgfgdedge, nothing is
% actually done immediately. After all, without knowing the final
% positions of the nodes #1 and #2, there is no way of
% creating the actual drawing commands for the edge. Thus, the actual
% drawing of the edge is done only when the graph drawing algorithm is
% done (namely in the macro \pgfgdcallbackedge, see later).
%
% Because of this "delayed" drawing of edges, options that influence
% the edge must be retained until the moment when the edge is actually
% drawn. Parameters #4 and #5 store such options.
%
% Let us start with #4. This parameter should be set to a list of
% key-value pairs like
%
%   /tikz/.cd, color=red, very thick, this edge must be vertical
%
% Some of these options may be of interest to the graph drawing
% algorithm (like the last option) while others will
% only be important during the drawing of edge (like the first
% option). The options that are important for the graph drawing
% algorithm must be passed to the algorithm via setting keys that have
% been declared using the handler .edge parameter (see
% above).
%
% The tricky part is that options that are of interest to the graph
% drawing algorithm must be executed *before* the algorithm starts,
% but the options as a whole are usually only executed during the
% drawing of the edges, which is *after* the algorithm has finished.
%
% To overcome this problem, the following happens:
%
% The options in #4 are executed "tentatively" inside
% \pgfgdedge. However, this execution is done in a "heavily guarded
% sandbox" where all effects of the options (like changing the
% color or the line width) do not propagate beyond the sandbox. Only
% the changes of the graph drawing edge parameters leave the
% sandbox. These parameters are then passed down to the graph drawing
% engine.
%
% Later, when the edge is drawn using \pgfgdcallbackedge, the options #4
% are available once more and then they are executed normally.
%
% Note that when the options in #4 are executed, no path is
% preset. Thus, you typically need to start it with, say, /tikz/.cd.
%
%
% The text in #5 is some "auxiliary" text that is simply stored away
% and later directly to \pgfgdcallbackedge. This is a courtesy to TikZ,
% which can use it to store its node labels.
%
% Example:
%
% \pgfgdedge{A}{B}{->}{red}{}
%
\def\pgfgdedge#1#2#3#4#5{%
  % Ok, setup sandbox
  \begingroup%
    \setbox0=\hbox{{%
        \pgfinterruptpath%
          \pgfgdprepareedge%
          \pgfkeys{#4}%
          % create edge in Lua
          \toks0={#4}%
          \toks1={#5}%
          \directlua{
            pgf.gd.interface.InterfaceToDisplay.createEdge(
            '\pgfutil@luaescapestring{#1}','\pgfutil@luaescapestring{#2}','\pgfutil@luaescapestring{#3}',
            \the\pgf@gd@parameter@stack@height,
            { pgf_options = '\pgfutil@luaescapestring{\the\toks0}',
              pgf_edge_nodes = '\pgfutil@luaescapestring{\the\toks1}',
            })
          }%
        \endpgfinterruptpath%
      }}%
  \endgroup%
}%

\let\pgfgdprepareedge=\pgfutil@empty
\def\pgfgdaddprepareedgehook#1{\expandafter\def\expandafter\pgfgdprepareedge\expandafter{\pgfgdprepareedge#1}}%


\newif\ifpgf@gd@nodes@behind@edges



% Define a callback for rendering edges
%
% #1 = macro name
%
% Descriptions:
%
% This is a callback from the graph drawing engine. At the end of the
% creation of a graph, when the nodes have been positioned, this macro
% is called once for each edge. The macro should take the following
% parameters:
%
% #1 = from node, optionally followed by "." and the tail anchor
% #2 = to node, optionally followed by "." and the head anchor
% #3 = direction (<-, --, ->, or <->)
% #4 = original options
% #5 = aux text (typically edge nodes)
% #6 = algorithm-generated options
% #7 = bend information
% #8 = animations
%
% The first five parameters are the original values that were passed
% down to the \pgfgdedge command.
%
% #6 contains options that have been "computed by the algorithm". For
% instance, an algorithm might have determined, say, flow capacities
% for edges and it might now wish to communicate this information back
% to the upper layers. These options should be executed with the path
% /graph drawing.
%
% #7 contains algorithmically-computed information concerning how the
% edge should bend. This will be a text like
% "--(10pt,20pt)--(30pt,40pt)" in tikz-syntax, using the path
% operations "--", "..controls" and "--cycle".
%
% By default, a simple line is drawn between the nodes. Usually, you
% will wish to install a more "fancy" callback, here.

\def\pgfgdsetedgecallback#1{\let\pgfgdcallbackedge=#1}%

\def\pgfgddefaultedgecallback#1#2#3#4#5#6#7#8{%
  {%
    \def\pgf@temp{#8}%
    \ifx\pgf@temp\pgfutil@empty%
    \else%
      \pgfset{every graphdrawing animation/.try}%
      \pgfset{every graphdrawing edge animation/.try}%
      #8%
      \pgfuseid{pgf@gd}%
      \pgfidscope%
    \fi%
    \pgfscope
      \pgfpathmoveto{
        \pgfutil@in@.{#1}%
        \ifpgfutil@in@
          \pgf@gd@unravel#1\relax%
        \else
          \pgfpointshapeborder{#1}{\pgfpointanchor{#2}{center}}
        \fi
      }
      \pgfpathlineto{
        \pgfutil@in@.{#2}%
        \ifpgfutil@in@
          \pgf@gd@unravel#2\relax%
        \else
          \pgfpointshapeborder{#2}{\pgfpointanchor{#1}{center}}
        \fi
      }
      \pgfusepath{stroke}
    \endpgfscope
    \ifx\pgf@temp\pgfutil@empty%
    \else%
      \endpgfidscope%
    \fi%
  }
}%

\pgfgdsetedgecallback{\pgfgddefaultedgecallback}%

\def\pgf@gd@unravel#1.#2\relax{%
  \pgfpointanchor{#1}{#2}%
}%




% Callbacks: Called before the shipout of nodes and edges starts
%
% First, the general begin shipout is called. Then, the node shipout
% starts, the nodes are created, and then the end of the node shipout
% is signaled. Next, the edge shipout starts and ends. Finally, the
% end shipout is called.

\def\pgfgdcallbackbeginshipout{%
  \pgfscope%
    \catcode`\@=11\relax%
    \setbox\pgf@gd@prekind@box=\box\pgfutil@voidb@x%
    \setbox\pgf@gd@postkind@box=\box\pgfutil@voidb@x%
}%
\def\pgfgdcallbackendshipout{%
    \box\pgf@gd@prekind@box%
    \ifpgf@gd@nodes@behind@edges%
      \box\pgf@gd@node@box%
      \box\pgf@gd@edge@box%
    \else%
      \box\pgf@gd@edge@box%
      \box\pgf@gd@node@box%
    \fi%
    \box\pgf@gd@postkind@box%
  \endpgfscope
}%

\newbox\pgf@gd@node@box
\newbox\pgf@gd@edge@box
\newbox\pgf@gd@prekind@box
\newbox\pgf@gd@postkind@box

\def\pgfgdcallbackbeginnodeshipout{%
  \setbox\pgf@gd@node@box=\hbox\bgroup%
}%
\def\pgfgdcallbackendnodeshipout{%
  \egroup%
}%

\def\pgfgdcallbackbeginedgeshipout{%
  \setbox\pgf@gd@edge@box=\hbox\bgroup%
}%

\def\pgfgdcallbackendedgeshipout{%
  \egroup
}%




% Generate a node
%
% This callback is called from the engine whenever an algorithm
% generates a new node internally.
%
% #1 = name of the node
% #2 = shape of the node
% #3 = options generated by the algorithm in key-value syntax. The set
% of generated options is algorithm-dependent.
% #4 = text
%
% This is an internal function and will be called by the binding layer

\def\pgfgdcallbackcreatevertex#1#2#3#4{%
  {
    \pgfkeys{#3}
    \pgfnode{#2}{\pgfkeysvalueof{/graph drawing/generated
        node/anchor}}{#4}{#1}{\pgfkeysvalueof{/graph drawing/generated
        node/use path}}
  }
}%

\pgfkeys{
  /graph drawing/generated node/anchor/.initial=center,
  /graph drawing/generated node/use path/.initial=\pgfusepath{}
}%



%
% Sublayouts
%
% Description: For a general introduction to (sub)layouts, see
% Section~\ref{section-gd-sublayouts} in the manual.
%

\def\pgfgdbeginlayout{
  \begingroup
    \pgfgdlayoutscopeactivetrue
    \advance\pgf@gd@parameter@stack@height by1\relax%
    \directlua{pgf.gd.interface.InterfaceToDisplay.pushLayout(\the\pgf@gd@parameter@stack@height)}
}%

\def\pgfgdendlayout{
  \endgroup%
}%




% Creates a subgraph node
%
% #1 = name
% #2 = node options
% #3 = node text
%
% Description:
%
% A subgraph node is a node that "surrounds" the nodes of a
% subgraph. The special property of a subgraph node opposed to a
% normal node is that it is created only after the subgraph has been
% laid out. However, the difference to a collection like "hyper" is
% that the node is available immediately as a normal node in the sense
% that you can connect edges to it.
%
% What happens internally is that subgraph nodes get "registered"
% immediately both on the pgf level and on the lua level, but the
% actual node is only created inside the layout pipeline using a
% callback. The actual node creation happens when the innermost layout
% in which the subgraph node is declared has finished.
%
% When you create a subgraph node using this macro, you also start a
% collection (of an internal kind) that stores the subgraph. All
% following nodes in the current TeX scope will become part of this
% collection.
%
% See |InterfaceToDisplay.pushSubgraphVertex| for details.

\def\pgfgdsubgraphnode#1#2#3{%
  \advance\pgf@gd@parameter@stack@height by1\relax%
  {%
    % create edge in Lua
    \toks0={#2}%
    \toks1={#3}%
    \directlua{pgf.gd.interface.InterfaceToDisplay.pushSubgraphVertex%
      ('\pgfutil@luaescapestring{#1}',\the\pgf@gd@parameter@stack@height,
      {
        shape = 'rectangle', % typically overwritten by the pgf_options:
        pgf_options = '\pgfutil@luaescapestring{\the\toks0}',
        text = '\pgfutil@luaescapestring{\the\toks1}',
      })
    }%
  }
}%

\def\pgfgdsubgraphnodecontents#1{% helper function
  \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{%
    \vrule width0pt height\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\hfil}%
}%

\pgfgdset{
  subgraph point cloud/.initial=,
  subgraph bounding box width/.initial=,
  subgraph bounding box height/.initial=,
}%


%
% Requests
%
% Description:
%
% This key is used to ``request'' a graph drawing scope and a
% layout. The objective of this key is to make it easier for users and
% algorithm designers to control the slightly involved
% back-and-forth-calling between the different layers.
%
% This key does the following: When called inside a pgfpicture
% (otherwise, the call is "illegal"), it will call a call-back with
% two parameters. This callback will get passed some code that should
% be executed at the beginning of ``the next scope'' and some code
% that should be executed at the end of that scope.
%
% The code passed to the callbacks will have a different effect,
% depending on whether we are currently inside a layout scope or not
% (if no graph drawing scope is open, we are
% not inside a layout). If we are not inside a layout scope (or if the
% layout scope has been interrupted), the code will issue a
% \pgfgdbeginscope command in the opening code and a corresponding
% scope ending command in the closing code. Next, the two code pieces
% always contain \pgfgdbeginlayout and \pgfgdendlayout.
%
% Note that the "@request scope and layout" key will not immediately
% trigger a layout scope to be created; rather, the TikZ callback will
% call it only at the beginning of the scope, which will be after
% other options in the current list of options have been parsed. So,
% when you write \graph [binary tree layout, significant sep=2em] ...,
% the "significant sep" option has an effect despite being given
% *after* the "@request scope and layout" key since the actual opening
% of the scope happens only before the "..." part is parsed.

\pgfgdset{@request scope and layout/.code=\pgfgd@requestcallback{\pgfgdbeginrequest}{\pgfgdendrequest}}%

\def\pgfgd@requestcallback#1#2{%
  #1\def\pgf@gd@after@request{#2\egroup}\bgroup\aftergroup\pgf@gd@after@request%
}% Default for basic layer

\def\pgfgdbeginrequest{%
  \ifpgfgdlayoutscopeactive%
  \else%
    \expandafter\pgfgdbeginscope%
  \fi%
      \pgfgdbeginlayout%
}%
\def\pgfgdendrequest{%
      \pgfgdendlayout%
  \ifpgfgdlayoutscopeactive%
  \else%
    \expandafter\pgfgdendscope%
  \fi%
}%
\newif\ifpgfgdlayoutscopeactive


% Set the request callback
%
% #1 = A macro
%
% Description:
%
% Sets the request callback as described in the "@request scope and
% layout" key.

\def\pgfgdsetrequestcallback#1{\let\pgfgd@requestcallback#1}%




%
% An if that is true exactly if we are inside a graph drawing scope
%

\newif\ifpgfgdgraphdrawingscopeactive


% Begins a new graph drawing scope
%
% Description:
%
% Inside a graph drawing scope, all pgf nodes that are newly created
% are automatically passed to the graph drawing engine. In contrast,
% edges have to be indicated explicitly using the macro \pgfgdedge
% (this is because it is somewhat unclear what, exactly, should count
% as an edge). Naturally, users typically will not call \pgfgdedge
% explicitly, but have styles and keys invoke it internally.
%
% Usage:
%
% \pgfgdset{algorithm=somealgorithm}
% \pgfgdbeginscope
%   \pgfnode{rectangle}{center}{A}{A}{}
%   \pgfnode{rectangle}{center}{B}{B}{}
%   \pgfnode{rectangle}{center}{C}{C}{}
%   \pgfgdedge{A}{B}{->}{}{}
%   \pgfgdedge{B}{C}{->}{}{}
%   \pgfgdedge{C}{A}{->}{}{}
% \pgfgdendscope
%
% Naturally, users will typically use TikZ's somewhat simpler syntax: '
%
% \tikz \graph [some algorithm] { A -> B -> C -> A };

\def\pgfgdbeginscope{%
  \begingroup % Protecting scope
    % get options
    \directlua{
      pgf.gd.interface.InterfaceToDisplay.beginGraphDrawingScope(\the\pgf@gd@parameter@stack@height)
    }%
    \begingroup % Inner scope, the actual nodes will be inserted after
                % this scope has been closed
      % Indicate that we are now inside a graph drawing scope
      \pgfgdgraphdrawingscopeactivetrue
      % Switch on late positioning
      \pgfpositionnodelater{\pgf@gd@positionnode@callback}
      % Switch on late edges
      \pgfgd@latecallback%
      % Kill transformations (will be added by the position now
      % macros)
      \pgftransformreset
}%



% The following is used to ensure that if we need to resume the graph
% drawing (through co-routines), we pass control back to TeX
% first. Otherwise, new text input levels are created and there may be
% only 15 of these...
\newif\ifpgfgdresumecoroutine


% Ends a graph drawing scope
%
% Description:
%
% This macro invokes the selected graph drawing algorithm and
% ships out all nodes within this scope
%
% See \pgfgdbeginscope

\def\pgfgdendscope{%
      \pgfgdresumecoroutinefalse%
      \directlua{
        pgf.gd.interface.InterfaceToDisplay.runGraphDrawingAlgorithm()
      }%
      \pgfutil@loop%
      \ifpgfgdresumecoroutine%
        \pgfgdresumecoroutinefalse%
        \directlua{
          pgf.gd.interface.InterfaceToDisplay.resumeGraphDrawingCoroutine()
        }%
      \pgfutil@repeat%
    \endgroup%
    % Late positioning has ended
    \directlua{pgf.gd.interface.InterfaceToDisplay.renderGraph()}%
    \directlua{pgf.gd.interface.InterfaceToDisplay.endGraphDrawingScope()}%
  \endgroup%
}%






% Hook into graph specification
%
% #1 = code
%
% Description:
%
% Allows you to specify code that should be active while the graph
% drawing engine collects the information concerning the graph, but
% which should no longer be active when the graph is rendered.

\def\pgfgdaddspecificationhook#1{
  \expandafter\def\expandafter\pgfgd@latecallback\expandafter{\pgfgd@latecallback#1}
}%
\let\pgfgd@latecallback\pgfutil@empty








% Loading further libraries

% Include a graph drawing library file.
%
% #1 = List of names of library file.
%
% Description:
%
% This command includes a list of graph drawing library files. For
% each file X in the list, the file pgf.gd.X.lua is included using
% |require|.
%
% For the convenience of Context users, both round and square brackets
% are possible for the argument.
%
%
% Example:
%
% \usegdlibrary{trees}
% \usegdlibrary[force,circular]

\def\usegdlibrary{\pgfutil@ifnextchar[{\use@gdlibrary}{\use@@gdlibrary}}%}%
\def\use@gdlibrary[#1]{\use@@gdlibrary{#1}}%
\def\use@@gdlibrary#1{%
  \edef\pgf@list{#1}%
  \pgfutil@for\pgf@temp:=\pgf@list\do{%
    \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}%
    \ifx\pgf@temp\pgfutil@empty
    \else
      \directlua{if not pgf_lookup_and_require('\pgf@temp') then
        tex.print('\pgfutil@luaescapestring{\noexpand\pgferror{Graph drawing library '\pgf@temp' not found}}')
      end}
    \fi
  }
}%

% LaTeX uses kpathsea for file lookup while ConTeXt uses its
% resolvers. Luckily, kpathsea is still accessible in ConTeXt in a
% subtable kpse.original which we use if kpse.find_file is nil.
{%
\catcode`\%=11
\directlua{
    function pgf_lookup_and_require(name)
        local sep = package.config:sub(1,1)
        local function lookup(name)
            local sub = name:gsub('%.',sep)
            local find_file = context and
                resolvers.findfile or
                kpse.find_file
            if find_file(sub, 'lua') then
                require(name)
            elseif find_file(sub, 'clua') then
                collectgarbage('stop')
                require(name)
                collectgarbage('restart')
            else
                return false
            end
            return true
        end
        return
            lookup('pgf.gd.' .. name .. '.library') or
            lookup('pgf.gd.' .. name) or
            lookup(name .. '.library') or
            lookup(name)
    end
}
}%


%
% Ok, fire up the system by creating the binding!
%
\directlua{
  require 'pgf.gd.interface.InterfaceToDisplay'
  pgf.gd.interface.InterfaceToDisplay.bind(require 'pgf.gd.bindings.BindingToPGF')
}%



%
% Special setup for keys that are declared by the above libraries, but
% that have a special meaning on the display layer.
%

\pgfkeys{/graph drawing/nodes behind edges/.append code=\csname pgf@gd@nodes@behind@edges#1\endcsname}%
\pgfkeys{/graph drawing/nodes behind edges/.default=true}%




\endinput
