%D \module
%D   [     file=t-gantt-tikz,
%D      version=2010.11.09,
%D        title=\CONTEXT\ User Module,
%D     subtitle=Drawing gantt diagrams,
%D       author={Adam Reviczky},
%D         date=\currentdate,
%D    copyright=Adam Reviczky,
%D      license=GNU GPL 2.0]

%D Some macros for drawing gantt diagrams using TikZ.
%D
%D Adam Reviczky, 09.11.2010 (Version 2.0)
%D Martin Kumm, 05.08.2010 (Version 1.1)

\writestatus{loading}{ConTeXt User Module / Drawing gantt diagrams}

\startmodule[gantt-tikz]
\unprotect

\def\????gantt-tikz{@@@@gantt-tikz}

\usemodule[tikz,pgffor]
\usetikzlibrary[arrows,patterns,decorations.pathmorphing]

\definesystemvariable{gantt}

\newcount\ganttnum
\newcount\gantttitlenum
\newcount\ganttwidth

\newdimen\ganttlastx \ganttlastx = 0cm
\newdimen\titleunitlength \titleunitlength = 1cm

\newdimen\gantttmpa
\newdimen\gantttmpb

\def\setupgantt
        {\bgroup
         \catcode`\#=\@@other
         \dosingleempty
         \dosetupgantt}

\def\dosetupgantt[#1]%
        {\egroup
         \getparameters[\??gantt][#1]}

\setupgantt
        [xunitlength=1cm,
         fontsize=\tf,
         titlefontsize=\tfx,
         drawledgerline=false]

\def\setupganttbar
        {\bgroup
         \catcode`\#=\@@other
         \dosingleempty
         \dosetupganttbar}

\def\dosetupganttbar[#1]%
        {\egroup
         \getparameters[\??gantt][#1]}

\setupganttbar
        [pattern=north east lines,
         color=black]

% The gantt environment draws the canvas of a gantt figure (realized as tikzpicture)
% The usage is \startgantt[...]{no of Tasks to plot}{no of time slots}
% The optional argument [...] can be filled in a key=value syntax, using one or more of the following keys:
%
% xunitlength - length of one time slot (default: 1 cm)
% fontsize - fontsize of labels (default: \tf)
% titlefontsize - fontsize of title section (default: \tfx)
% drawledgerline  - Switch to enable/disable the drawing of horizontal ledger lines (default value: false)

\long\def\dostartgantt[#1]#2#3%
  {\getparameters[\??gantt][#1]%
   \gdef\v!xunitlength{\@@ganttxunitlength}
   \gdef\v!fontsize{\getvalue{@@ganttfontsize}}
   \gdef\v!titlefontsize{\getvalue{@@gantttitlefontsize}}
   \gdef\v!drawledgerline{\@@ganttdrawledgerline}

   \bgroup
   \tikzstyle{time}=[coordinate]

   \newcount\ganttx \ganttx=0
   \newcount\ganttheight

   \def\ganttxstringtop{}
   \def\ganttxstringbottom{}

   \global\ganttwidth=#3
   \global\ganttnum=0

   \ganttheight=#2
   \advance\ganttheight by 1;

   % LEFT CANVAS EDGE 
   \draw[white] (0,0.5) node[above] {\ganttxstringtop} -- (0,1.4-\ganttheight)  node[below] {\ganttxstringbottom};
   % RIGHT CANVAS EDGE
   \draw[white] (\ganttwidth*\v!xunitlength,0.5) node[above] {\ganttxstringtop} -- (\ganttwidth*\v!xunitlength,1.4-\ganttheight)  node[below] {\ganttxstringbottom};

   % draw grid
   \foreach \!!t in {1,2,...,\ganttwidth}{
     \draw[dotted, color=gray] (\v!xunitlength*\!!t,-0.5) node[above] {\ganttxstringtop} -- (\v!xunitlength*\!!t,1.4-\ganttheight)  node[below] {\ganttxstringbottom};
   }

   % draw x axis
   \draw[] (0,-#2+0.4) -- (\ganttwidth*\v!xunitlength,-#2+0.4);
   \egroup
  }

\def\startgantt%
  {\starttikzpicture[draw=black, line width=0.5pt,yscale=.7,xscale=1]
   \dosingleempty\dostartgantt}

\def\stopgantt%
  {\stoptikzpicture}

% ganttitle is the environment for drawing the title section
\definestartstop[ganttitle][
  before={
    \ganttlastx = 0cm
  },
  after={
    \ganttlastx = 0cm
    \doglobal\decrement\ganttnum 
  }
  ]

% TITLE ELEMENT
% \titleelement draws one element of the title
% usage: \titleelement{label}{length}
\long\def\dotitleelement#1#2%
  {\gantttmpa=\dimexpr\v!xunitlength*#2\relax
   \divide\gantttmpa by 2;

   \def\!!xoffset{1.5}

   \filldraw[fill=white] (\ganttlastx,\ganttnum-0.5) rectangle (\ganttlastx+#2*\v!xunitlength,\ganttnum+0.75);
   \node at (\ganttlastx+\gantttmpa-\!!xoffset,\ganttnum+0.1) {%
     \getvalue{v!titlefontsize} #1%
   };

   \ganttlastx=\dimexpr\ganttlastx+\v!xunitlength*#2\relax
  }

\def\titleelement%
  {\dotitleelement}


% SUBTITLE ELEMENT
% \subtitleelement draws one element of the title
% usage: \subtitleelement{label}{length}
\long\def\dosubtitleelement#1#2%
  {\gantttmpa=\dimexpr\v!xunitlength*#2\relax
   \divide\gantttmpa by 2;

   \def\!!xoffset{1.5}

   \draw (\ganttlastx,\ganttnum+0.5) rectangle (\ganttlastx+#2*\v!xunitlength,\ganttnum+0);
   \node at (\ganttlastx+\gantttmpa-\!!xoffset+1,\ganttnum+0.25) {%
     \getvalue{tfx} #1%
   };

   \ganttlastx=\dimexpr\ganttlastx+\v!xunitlength*#2\relax
  }

\def\subtitleelement%
  {\dosubtitleelement}


% NUMTITLE
% \numtitle draws a numbered sequence of title elements
% usage: \numtitle{start number}{increment}{end number}{length of each title element}
\long\def\donumtitle#1#2#3#4%
  {\gantttitlenum=#1
   \dostepwiserecurse{#1}{#3}{#2}{
     \subtitleelement{\the\gantttitlenum}{#4} 
     \advance\gantttitlenum by #2;
   }
  }

\def\numtitle%
  {\donumtitle}


% GANTBAR
% \ganttbar draws a single, unconnected bar for representing a task
% usage: \ganttbar[pattern=<pattern>,color=<color>]{label}{start}{length}
% where the optional comma separated arguments are:
% pattern - is a tikz pattern (e.g. north east lines (default), north west lines, crosshatch, crosshatch dots, grid, ...)
% color - a tikz color of the pattern (e.g. red, green blue gray, dark gray)
% for more information see the tikz documentation
\long\def\doganttbar[#1]#2#3#4%
  {\bgroup
   \getparameters[\??gantt][#1]%
   \edef\v!pattern{\@@ganttpattern}
   \edef\v!color{\@@ganttcolor}

   \gantttmpa=\dimexpr\v!xunitlength*#3\relax
   \gantttmpb=\dimexpr\v!xunitlength*#4+\gantttmpa\relax

   \doif{\v!drawledgerline}{true}{
     \draw[dotted, color=gray!25] (0,\ganttnum-0.2) -- (\ganttwidth*\v!xunitlength,\ganttnum-0.2);
   }
   % ROW TITLE
   \node at (\gantttmpa,\ganttnum+0.2) [anchor=base east] {%
     \getvalue{v!fontsize} #2%
   };
   \draw[pattern=\v!pattern,pattern color=\v!color] (\gantttmpa,\ganttnum+0.1) rectangle (\gantttmpb,\ganttnum+0.5);
   \global\ganttlastx=\gantttmpb
   \doglobal\decrement\ganttnum
   \egroup
  }

\def\ganttbar
        {\dosingleempty\doganttbar}



% GANTCON 
% \ganttcon draws an arrow between to bars with specified coordinates
% usage: \ganttcon{startx}{starty}{endx}{endy}
\long\def\doganttcon#1#2#3#4%
  {\bgroup
   \draw[-angle 45, decorate, decoration={coil, aspect=1}] (#1*\v!xunitlength-5,-#2+0.1+0.2) -- (#1*\v!xunitlength-0.5*\v!xunitlength,-#4+0.1+0.2);
   \egroup
  }

\def\ganttcon
        {\doganttcon}



% GANTCON EXTRA
% \ganttcon draws an arrow between to bars with specified coordinates
% usage: \ganttconExtra{startx}{starty}{endx}{endy}
\long\def\doganttconExtra#1#2#3#4%
  {\bgroup
   %\draw[-angle 45, decorate, decoration={snake}] (#1*\v!xunitlength-5,-#2+0.1+0.2) -- (#1*\v!xunitlength-0.5*\v!xunitlength,-#4+0.1+0.2);
   \draw[->, decorate, decoration={snake, amplitude=0.25mm}] (#1*\v!xunitlength-5,-#2+0.1+0.2) --  (#3*\v!xunitlength-5,-#4+0.1+0.2);
   \egroup
  }

\def\ganttconExtra
        {\doganttconExtra}



% GANTBARCON
% \ganttbarcon draws a single bar *and* connects the bar with the previous bar for
% consecutive tasks
% usage: \ganttbarcon[pattern=<pattern>,color=<color>]{label}{start}{length}
% where the optional pattern argument are the same as for \ganttbar
\long\def\doganttbarcon[#1]#2#3#4%
  {\bgroup
   \getparameters[\??gantt][#1]%
   \edef\v!pattern{\@@ganttpattern}
   \edef\v!color{\@@ganttcolor}

   \doifelse{\the\ganttlastx}{\the\dimexpr\v!xunitlength*#3\relax}{
     \draw[->, angle 45] (\ganttlastx,\ganttnum+1.1+0.2) -- (\ganttlastx+0.4*\v!xunitlength,\ganttnum+1.1+0.2) -- (\ganttlastx+0.4*\v!xunitlength,\ganttnum+0.6+0.2) -- (\ganttlastx-0.4*\v!xunitlength,\ganttnum+0.6+0.2) -- (\ganttlastx-0.4*\v!xunitlength,\ganttnum+0.1+0.2) -- (#3*\v!xunitlength,\ganttnum+0.1+0.2);
   }{ 
     \draw[-angle 45] (\ganttlastx,\ganttnum+1.1+0.2) -- (\ganttlastx+0.4*\v!xunitlength,\ganttnum+1.1+0.2) -- (\ganttlastx+0.4*\v!xunitlength,\ganttnum+0.1+0.2) -- (#3*\v!xunitlength,\ganttnum+0.1+0.2);
   }

   %hbox overfull!
   \ganttbar[#1]{#2}{#3}{#4} 
   \egroup
  }

\def\ganttbarcon
        {\dosingleempty\doganttbarcon}



% GANTTGROUP
% \ganttgroup draws a bar to group tasks
% usage: \ganttgroup{label}{start}{length}
\long\def\doganttgroup#1#2#3%
  {\bgroup
   \gantttmpa=\dimexpr\v!xunitlength*#2\relax
   \gantttmpb=\dimexpr\v!xunitlength*#3+\gantttmpa\relax

   \doif{\v!drawledgerline}{true}{
     \draw[loosely dotted] (0,\ganttnum-0.2) -- (\ganttwidth*\v!xunitlength,\ganttnum-0.2);
   }
   \node at (\gantttmpa/2+\gantttmpb/2,\ganttnum+0.7) {%
     \getvalue{v!fontsize} #1%
   };
   \draw[pattern=crosshatch dots,pattern color=black, draw=none] (\gantttmpa,\ganttnum+0.1) rectangle (\gantttmpb,\ganttnum+0.5);
   %\fill[black] (\gantttmpa-0.14cm,\ganttnum+0.2) rectangle (\gantttmpb+0.14cm,\ganttnum+0.4);
   %\draw[diamond-diamond] (\gantttmpa-0.14cm,\ganttnum+0.2) -- (\gantttmpb+0.14cm,\ganttnum+0.2);

   \global\ganttlastx=\gantttmpb
   \doglobal\decrement\ganttnum
   \egroup
  }

\def\ganttgroup
        {\doganttgroup}

\protect \endinput
