% \iffalse
% --------------------------------------------------------------------
%<*hex>
% \fi
% 
% \subsubsection{Hexes}
% \label{sec:impl:hex:hex}
%
% In this part, we make macros etc. for the hexes. 
%
% A hex shape.   We make a node of this shape if we are to give a name
% to the hex added.  We add a bunch of anchors to it so we may easily
% refer to it.   This is also where we actual fill stuff into the hex,
% such as terrain and so on. 
% 
%    \begin{macrocode}
\tikzset{%
  /hex/.cd,
  bev/.store in=\hex@bevel,               bev/.initial=,
  bevel fraction/.store in=\hex@bevel@frac,bevel fraction/.initial=10,
  bevel/.is choice,
  bevel/none/.style       = {/hex/bev=},
  bevel/north west/.style = {/hex/bev=1},
  bevel/north east/.style = {/hex/bev=2},
  bevel/south west/.style = {/hex/bev=3},
  bevel/south east/.style = {/hex/bev=4},
  bevel/NW/.style         = {/hex/bev=1},
  bevel/NE/.style         = {/hex/bev=2},
  bevel/SW/.style         = {/hex/bev=3},
  bevel/SE/.style         = {/hex/bev=4},
  bevel/.default          = {north west},
}
\def\hex@bevel@frac{10}
\tikzset{
  hex/bevel highlight/.style={fill=white,opacity=.25},
  hex/bevel shadow/.style={fill=black,opacity=.25},
}
%    \end{macrocode}
% 
%
%
%    \begin{macrocode}
\newdimen\wg@tmpe
\newdimen\wg@tmpf
\newdimen\wg@tmpg
\def\hex@bevel@path#1{%
  \scope[#1]
  \wg@tmpe=\wg@tmpa\multiply\wg@tmpe by \hex@bevel@frac
  \wg@tmpf=\wg@tmpb\multiply\wg@tmpf by \hex@bevel@frac
  \wg@tmpg=\wg@tmpc\multiply\wg@tmpg by \hex@bevel@frac
  \divide\wg@tmpe100
  \divide\wg@tmpf100
  \divide\wg@tmpg100
  % Start
  \pgfpathmoveto{\pgfqpoint{\wg@tmpa}{\wg@tmpb}}%
  % Left
  \pgfpathlineto{\pgfqpoint{-\wg@tmpa}{\wg@tmpb}}%
  % Left-down 
  \pgfpathlineto{\pgfqpoint{\wg@tmpc}{\wg@tmpd}}%
  % Right down
  \wg@tmpa=-\wg@tmpa%
  \wg@tmpb=-\wg@tmpb%
  \pgfpathlineto{\pgfqpoint{\wg@tmpa}{\wg@tmpb}}%
  % Up, in
  \advance\wg@tmpa\wg@tmpe%
  \advance\wg@tmpb\wg@tmpf%
  \pgfpathlineto{\pgfqpoint{\wg@tmpa}{\wg@tmpb}}%
  % Left-down, in
  \advance\wg@tmpc-\wg@tmpg
  \pgfpathlineto{\pgfqpoint{\wg@tmpc}{\wg@tmpd}}%
  % Left, down in
  \advance\wg@tmpb-\wg@tmpf\wg@tmpb-\wg@tmpb%
  \advance\wg@tmpb-\wg@tmpf
  \pgfpathlineto{\pgfqpoint{\wg@tmpa}{\wg@tmpb}}%
  % Start, down in
  \advance\wg@tmpa-\wg@tmpe\wg@tmpa-\wg@tmpa%
  \advance\wg@tmpa-\wg@tmpe
  \pgfpathlineto{\pgfqpoint{\wg@tmpa}{\wg@tmpb}}%
  % %
  \pgfclosepath%
  \pgfusepath{fill}
  \endscope}%
%    \end{macrocode}
% 
%
%
%    \begin{macrocode}
\hex@dbg{5}{Base vertex: \hex@xx,\hex@yy}
\hex@dbg{5}{Base edges: \hex@e@xx,\hex@e@yy}
\pgfdeclareshape{hex/hex}{%
  \saveddimen\radius{\pgf@x=\hex@radius}
  \savedanchor{\east}{         \pgfqpoint{ \hex@radius}{0cm}}
  \savedanchor{\west}{         \pgfqpoint{-\hex@radius}{0cm}}
  \savedanchor{\northeast}{    \pgfqpoint{ \hex@dx}{ \hex@dy}}
  \savedanchor{\northwest}{    \pgfqpoint{-\hex@dx}{ \hex@dy}}
  \savedanchor{\southwest}{    \pgfqpoint{-\hex@dx}{-\hex@dy}}
  \savedanchor{\southeast}{    \pgfqpoint{ \hex@dx}{-\hex@dy}}
  \savedanchor{\northedge}{    \pgfqpoint{     0cm}{ \hex@dy}}
  \savedanchor{\southedge}{    \pgfqpoint{     0cm}{-\hex@dy}}
  \savedanchor{\northeastedge}{\pgfqpoint{ \hex@e@dx}{ \hex@e@dy}}
  \savedanchor{\northwestedge}{\pgfqpoint{-\hex@e@dx}{ \hex@e@dy}}
  \savedanchor{\southwestedge}{\pgfqpoint{-\hex@e@dx}{-\hex@e@dy}}
  \savedanchor{\southeastedge}{\pgfqpoint{ \hex@e@dx}{-\hex@e@dy}}
  \savedmacro\init{%
    \def\hexpath{%
      \pgfpathmoveto{\east}%
      \pgfpathlineto{\northeast}%
      \pgfpathlineto{\northwest}%
      \pgfpathlineto{\west}%
      \pgfpathlineto{\southwest}%
      \pgfpathlineto{\southeast}%
      \pgfpathclose}
  }
%    \end{macrocode}
% 
% These are the actual user callable anchors.   We make anchors for
% each vertex and mid points on each edge.
%
%    \begin{macrocode}
%% 
  \anchor{center}{         \pgfpointorigin}
  \anchor{east}{           \east}
  \anchor{west}{           \west}
  \anchor{north east}{     \northeast}
  \anchor{north west}{     \northwest}
  \anchor{south west}{     \southwest}
  \anchor{south east}{     \southeast}
  \anchor{north edge}{     \northedge}
  \anchor{south edge}{     \southedge}
  \anchor{north east edge}{\northeastedge}
  \anchor{north west edge}{\northwestedge}
  \anchor{south west edge}{\southwestedge}
  \anchor{south east edge}{\southeastedge}
%    \end{macrocode}
%
% Next we make some short hand aliases for each of these anchors.
%
%    \begin{macrocode}
  \anchor{E}{      \east}
  \anchor{W}{      \west}
  \anchor{NE}{     \northeast}
  \anchor{NW}{     \northwest}
  \anchor{SW}{     \southwest}
  \anchor{SE}{     \southeast}
  \anchor{N edge}{ \northedge}
  \anchor{S edge}{ \southedge}
  \anchor{NE edge}{\northeastedge}
  \anchor{NW edge}{\northwestedge}
  \anchor{SW edge}{\southwestedge}
  \anchor{SE edge}{\southeastedge}
%    \end{macrocode}
%
% The next part is commented out because its not obvious we'll use
% these.
% 
%    \begin{macrocode}
  %%
  \savedanchor{\chitnorth}{    \pgfqpoint{ 0cm}{   0.6cm}}
  \savedanchor{\chitsouth}{    \pgfqpoint{ 0cm}{  -0.6cm}}
  \savedanchor{\chiteast}{     \pgfqpoint{ 0.6cm}{ 0cm}}
  \savedanchor{\chitwest}{     \pgfqpoint{-0.6cm}{ 0cm}}
  \savedanchor{\chitnortheast}{\pgfqpoint{ 0.6cm}{ 0.6cm}}
  \savedanchor{\chitnorthwest}{\pgfqpoint{-0.6cm}{ 0.6cm}}
  \savedanchor{\chitsouthwest}{\pgfqpoint{-0.6cm}{-0.6cm}}
  \savedanchor{\chitsoutheast}{\pgfqpoint{ 0.6cm}{-0.6cm}}
  % 
  \anchor{chit north}{\chitnorth}
  \anchor{chit south}{\chitsouth}
  \anchor{chit east}{\chiteast}
  \anchor{chit west}{\chitwest}
  \anchor{chit north east}{\chitnortheast}
  \anchor{chit north west}{\chitnorthwest}
  \anchor{chit south west}{\chitsouthwest}
  \anchor{chit south east}{\chitsoutheast}
  % 
  \anchor{chit N}{\chitnorth}
  \anchor{chit S}{\chitsouth}
  \anchor{chit E}{\chiteast}
  \anchor{chit W}{\chitwest}
  \anchor{chit NE}{\chitnortheast}
  \anchor{chit NW}{\chitnorthwest}
  \anchor{chit SW}{\chitsouthwest}
  \anchor{chit SE}{\chitsoutheast}
  %
%    \end{macrocode}
%    
% The background path.  This path may be drawn when the node is
% drawn.  However, we will do most of the work in the
% \cs{behindbackgroundpath} which gets drawn \emph{after} this path.
% 
%    \begin{macrocode}  
  \backgroundpath{\init\hexpath}
%    \end{macrocode}
%    
% The \emph{behind} background path, where we do most of the work. 
% 
%    \begin{macrocode}  
  \behindforegroundpath{%
    \hex@dbg{2}{Hex behind foreground path:
      ^^JTerrain:       `\meaning\hex@terrain'
      ^^JRidges:        `\meaning\hex@ridges'
      ^^JTown:          `\meaning\hex@town'
      ^^JExtra clipped: `\meaning\hex@extra@clip'
      ^^JLabel:         `\meaning\hex@label'
      ^^JExtra:         `\meaning\hex@extra'
      ^^JLast node name:`\meaning\tikzlastnode'
      ^^JHex row:       `\meaning\hex@row'
      ^^JHex col:       `\meaning\hex@col'
    }%
    \init%
%    \end{macrocode}
%    
% We start a scope and clip to the hex path first. 
% 
%    \begin{macrocode}  
    \scope%
      \hexpath%
      \pgfusepath{clip}%
%    \end{macrocode}
%    
% Anything inside this scope is clipped to the hex path.  The next
% step is to see if we have a specified terrain for the hex.
%
%    \begin{macrocode}
      \@ifundefined{hex@terrain}{\let\hex@terrain\empty}{}%
      \ifx\hex@terrain\empty\else\hex@do@terrain\fi%
%    \end{macrocode}
%
% This concludes the processing of the terrain of the hex.  Next, we
% must see if the user specified ridges. 
% 
%    \begin{macrocode}
      \@ifundefined{hex@ridges}{\let\hex@ridges\empty}{}%
      \ifx\hex@ridges\empty\else\hex@do@ridges\fi%
%    \end{macrocode}
%
% This concludes the processing of the ridges of the hex.  Next, we
% should process any extra (clipped) stuff specified. The user may
% pass options to each \spec{pic}ture by preceding it with
% \oarg{options}.
% 
%    \begin{macrocode}
      \@ifundefined{hex@extra@clip}{\let\hex@extra@clip\empty}{}
      \ifx\hex@extra@clip\empty\else%
         \hex@dbg{5}{Extra clipped: `\meaning\hex@extra'}
         \pgfpointorigin\wg@tmpa=\pgf@x\wg@tmpb=\pgf@y%
         \wg@pic@all{\hex@extra@clip}{}{\the\wg@tmpa,\the\wg@tmpb}{}%
      \fi%
%    \end{macrocode}
%
% This concludes the extra stuff put in the hex.   Next, we should
% place the label is specified.   Note, we may know the hex row and
% column at this point, stored in \cs{hex@row} and \cs{hex@column},
% respectively.   We may want to name the generated node from these if
% the user specified that option (perhaps use \cs{pgfnoderename} or
% similar). 
% 
%    \begin{macrocode}
      \@ifundefined{hex@label}{\let\hex@label\empty}{}
      \ifx\hex@label\empty\else\hex@do@label\fi%
%    \end{macrocode}
% 
%    \begin{macrocode}
    \@ifundefined{hex@bevel}{\let\hex@bevel\empty}{}
    \ifx\hex@bevel\empty\else%
      \northeast
      \wg@tmpa=\pgf@x\wg@tmpb=\pgf@y%
      \west
      \wg@tmpc=\pgf@x\wg@tmpd=\pgf@y%
      \ifcase\hex@bevel\relax
      \or%1
      \or\wg@tmpa=-\wg@tmpa\wg@tmpc=-\wg@tmpc%2
      \or\wg@tmpb=-\wg@tmpb\wg@tmpd=-\wg@tmpd%3
      \or% 4
        \wg@tmpa=-\wg@tmpa\wg@tmpc=-\wg@tmpc%
        \wg@tmpb=-\wg@tmpb\wg@tmpd=-\wg@tmpd%
      \fi                                
      \hex@bevel@path{chit/bevel highlight}
      \northeast
      \wg@tmpa=-\pgf@x\wg@tmpb=-\pgf@y%
      \west
      \wg@tmpc=-\pgf@x\wg@tmpd=-\pgf@y%
      \ifcase\hex@bevel\relax
      \or%1
      \or\wg@tmpa=-\wg@tmpa\wg@tmpc=-\wg@tmpc%2
      \or\wg@tmpb=-\wg@tmpb\wg@tmpd=-\wg@tmpd%3
      \or% 4
        \wg@tmpa=-\wg@tmpa\wg@tmpc=-\wg@tmpc%
        \wg@tmpb=-\wg@tmpb\wg@tmpd=-\wg@tmpd%
      \fi                                
      \hex@bevel@path{chit/bevel shadow}
    \fi      
%    \end{macrocode}
%    \begin{macrocode}
    \endscope%
%    \end{macrocode}
%
% This concludes the label processing, and stuff that should be
% clipped to the hex shape.  If the user specified a town, we can now
% make that. 
% 
%    \begin{macrocode}
    \@ifundefined{hex@town}{\let\hex@town\empty}{}
    \@ifundefined{hex@c@pic}{\let\hex@c@pic\empty}{}
    \ifx\hex@town\empty\else\hex@do@town\fi%
%    \end{macrocode}
% 
% We can now add extra (non-clipped) stuff.  We assume that extra
% stuff is \spec{pic}tures.  The user may pass options to each
% \spec{pic}ture by preceding it with \oarg{options}.
%
%    \begin{macrocode}
    \@ifundefined{hex@extra}{\let\hex@extra\empty}{}
    \ifx\hex@extra\empty\else%
       \hex@dbg{5}{Extra: `\meaning\hex@extra'}
       \pgfpointorigin\wg@tmpa=\pgf@x\wg@tmpb=\pgf@y%
       \wg@pic@all{\hex@extra}{}{\the\wg@tmpa,\the\wg@tmpb}{}%
    \fi%
  }
}
%    \end{macrocode}
%
% \begin{HexKey*}{
%   /hex/terrain,
%   /hex/town,
%   /hex/label,
%   /hex/ridges,
%   /hex/extra,
%   /hex/extra clipped}
% 
% Next, we set up the name space for hex keys.  This is the top level
% name space for hexes.  Sub keys \spec{terrain}, \spec{ridges},
% \spec{town}, \spec{extra}, \spec{label}, and \spec{extra clipped},
% store their arguments in macros and we expand these later on.  This
% allows us to scope some of the keys given to those specific parts.
% 
% Define keys for hexagon options.  These are
% 
% \begin{tabular}{|l|p{.7\linewidth}|} 
%   \hline
%   \rowcolor{headbg}
%   {\color{headfg}\textbf{Name}}
%   & {\color{headfg}\textbf{Description}}\\
%   \hline 
%   \spec{terrain} & Terrain\\
%   \spec{label} & Label on hex\\
%   \spec{town} & Town in hex. Optionally with a name\\
%   \spec{ridges} & Ridge markings on hex\\
%   \spec{extra} & More \\
%   \spec{extra clipped} & More clipped to hex\\
%   \hline
% \end{tabular}
% 
%    \begin{macrocode}
\tikzset{%
  /hex/.search also={/tikz},%
  /hex/.cd,%
  terrain/.store in=\hex@terrain,%
  ridges/.store in=\hex@ridges,%
  town/.store in=\hex@town,%
  extra/.store in=\hex@extra,%
  label/.store in=\hex@label,%
  extra clipped/.store in=\hex@extra@clip%
}
%    \end{macrocode}
% \end{HexKey*}
%
% \begin{TikzKey}{hex}
%   The next key is the real work horse of the show.  Specifying the
%   \spec{hex} key to a node effectively creates a hex for us.  Now,
%   there are some things we cannot do outright in the node shape
%   code.  For example, we cannot set the name of the node created
%   from the shape code.  Therefore, the use of \cs{hex} is often the
%   right choice.
% 
%    \begin{macrocode}  
\tikzset{%
  hex/hex/.style={
    transform shape,
    anchor=center,
    draw=pgfstrokecolor,
    fill=none,
    thick,
    solid},
  hex/.code={%
    \hex@dbg{1}{=== Hex with options: `#1'}%
    \pgfkeys{/tikz/transform shape,/tikz/shape=hex/hex}
    \pgfkeys{/hex/.cd,/tikz/hex/hex,/tikz/every hex/.try,#1}}}
%    \end{macrocode}
% \end{TikzKey}
% 
% The first thing is to set the default graphics options.  The key
% \spec{every hex} can be set to hex options to be used for all hexes.
% For example, if one want to label all hexes with an auto-generated
% label, one can do
%
% \begin{Syntax}
%   \cs{tikzset}\{every hex/.style=\{label=\{auto=numbered\}\}\}
% \end{Syntax}
%
% This, coupled with the \spec{hex/label is name} option allows us to
% set up the board with really minimal effort.  We can then use the
% board coordinates when placing units, and other things.
% 
%
% Now we have set up these tools we can go on and define the user
% facing macro.
% 
% \begin{Macro}{\hex,\hex@,\hex@@}
%
%   This will add a hex to the output graphics.   Note, the macro
%   need not be followed by a semi-colon (\spec{;}). 
%
%   First argument is optional options. 
%
%    \begin{macrocode}
\def\hex{%
  \@ifnextchar[{\hex@}{\hex@[]}%]
}
%    \end{macrocode}
%
% Second optional argument is the coordinates.  These should be given
% in the hex coordinate system. 
%
%    \begin{macrocode}
\def\hex@[#1]{%
  \@ifnextchar({\hex@@{#1}}{%
    \hex@@{#1}(c=0,r=0)}%)
}
%    \end{macrocode}
%
% Third argument is the name to be used. 
%
%    \begin{macrocode}
\def\hex@@#1(#2){%
  \@ifnextchar({\hex@@@{#1}{#2}}{\hex@@@{#1}{#2}()}%)
}
%    \end{macrocode}
%
% Now for the real work-horse.  First thing is to reset keys and parse
% them out from the arguments.
% 
%    \begin{macrocode}
%      Third argument is name
\def\hex@@@#1#2(#3){%
  \node[hex={#1}] (tmp) at (hex cs:#2) {};%
  \hex@dbg{8}{=== Label text: `\meaning\hex@l@text'}
  \ifx|#3|\relax%
    \@ifundefined{hex@l@text}{%
      \hex@dbg{8}{=== Label text of hex (#2) not defined}%
      \let\hex@l@text\empty%
    }{}
    \ifhex@label@is@name%
      \hex@dbg{5}{=== Use label text of hex (#2) as name}%
      \ifx\hex@l@text\@empty%
        \hex@dbg{8}{=== Argh! Label text is empty! `\meaning\hex@l@text'}
      \else%
        \hex@dbg{3}{=== Renaming hex to label text `\hex@l@text'}
        \pgfnoderename{\hex@l@text}{tmp}%
      \fi%
    \fi%
  \else%
    \hex@dbg{3}{=== Renaming hex to user defined name `#3'}%
    \pgfnoderename{#3}{tmp}%
  \fi%
  \@ifnextchar;{\@gobble}{}%
}
%    \end{macrocode}
% \end{Macro}
% \iffalse
%</hex>
% --------------------------------------------------------------------
% \fi
