\NeedsTeXFormat{LaTeX2e}[1995/12/01]%
\ProvidesPackage{tikz-uml-divider}
%
% define a uml divider for sequence diagrams
% args : call sender
%        call receiver
% optional : dt: time delay from precedent event end
%            name: name of the call
%            op: operation name and input args
%            draw, fill, text: colors
%            padding: time padding from call start and to call end
\newenvironment{umldivider}[3][]{%
  \stepcounter{tikzumlCallNum}%
  \edef\tikzumlCall@lastchildNum{\thetikzumlCallNum}% for testing presence of sub-calls
  \gdef\tikzumlCallBottom{0}%
  %
  \pgfkeys{/tikzuml/call/.cd, dt/.initial=\tikzumlCallDefaultDT, name/.initial={call-\thetikzumlCallNum},%
                              op/.initial={},%
                              draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlCallDefaultFillColor,%
                              text/.initial=\tikzumlDefaultTextColor,%
                              padding/.initial=\tikzumlCallDefaultPadding,%
                              .unknown/.code={%
                                \let\keyname=\pgfkeyscurrentname%
                                \let\keyvalue=\pgfkeyscurrentvalue%
                                \ifthenelse{\equal{\keyname}{with return}}{%
                                  \def\tikzumlCallWithReturn{tikzumlTrue}%
                                }{%
                                  \errmessage{TIKZUML ERROR : in umlcall,  invalid option \keyname}%
                                }%
                              }%
  }%
  \pgfkeys{/tikzuml/call/.cd, #1}%
  \pgfkeys{/tikzuml/call/.cd, dt/.get=\tikzumlCallDT, name/.get=\tikzumlCallName, op/.get=\tikzumlCallOp,%
                              padding/.get=\tikzumlCallPadding,%
                              draw/.get=\tikzumlCallDrawColor, fill/.get=\tikzumlCallFillColor,%
                              text/.get=\tikzumlCallTextColor%
  }%
  %
  \edef\tikzumlfillcall{\tikzumlCallFillColor}%
  \edef\tikzumldrawcall{\tikzumlCallDrawColor}%
  \edef\tikzumltextcall{\tikzumlCallTextColor}%
  %
  \ifthenelse{\equal{\tikzumlCallDT}{tikzumlEmpty}}{%
    \ifnum\thetikzumlCallNum=1%
      \def\tikzumlCallDT{2}%
      \def\tikzumlcallSrc{2}%
    \else%
      \def\tikzumlCallDT{2}%
      \def\tikzumlcallSrc{1}%
    \fi%
  }{%
    \def\tikzumlcallSrc{0}%
  }%
  %
  \let\tikzumlCallStartNodeNameold\tikzumlCallStartNodeName%
  \def\tikzumlCallStartNodeName{#2}%
  \let\tikzumlCallEndNodeNameold\tikzumlCallEndNodeName%
  \def\tikzumlCallEndNodeName{#3}%
  \def\tikzumlcallheight{\tikzumlCallPadding}%
  %
  % managing time delays from previous/parent fragments 
  \ifnum\thetikzumlCallStartFragmentNum>0%
    \let\tikzumlCallDTold\tikzumlCallDT%
    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCallDTold}%
    \edef\tikzumlCallDT{\pgfmathresult}%
    \addtocounter{tikzumlCallStartFragmentNum}{-1}
  \fi%
  \ifnum\thetikzumlCallEndFragmentNum>0%
    \let\tikzumlCallDTold\tikzumlCallDT%
    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCallDTold}%
    \edef\tikzumlCallDT{\pgfmathresult}%
    \addtocounter{tikzumlCallEndFragmentNum}{-1}
  \fi%
  \ifnum\thetikzumlFragmentPartNum>0%
    \let\tikzumlCallDTold\tikzumlCallDT%
    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCallDTold}%
    \edef\tikzumlCallDT{\pgfmathresult}%
  \fi%
  %
  % managing parent-child structure
  \ifnum\thetikzumlCallLevel>0%
    \let\tikzumlCall@nameold\tikzumlCall@name%
    \edef\tikzumlCall@name{\tikzumlCallName}%
    \let\tikzumlCall@parentold\tikzumlCall@parent%
    \edef\tikzumlCall@parent{\tikzumlCall@parentold @@\tikzumlCall@nameold}%
  \else%
    \edef\tikzumlCall@parent{}%
    \edef\tikzumlCall@parentold{}%
    \edef\tikzumlCall@nameold{}
    \edef\tikzumlCall@name{\tikzumlCallName}%
  \fi%
  %
  \begingroup%
    \def\_{_}\edef\x{\endgroup%
      \def\noexpand\tikzumlCall@nodeName{\tikzumlCall@name}}\x%
  %
  \let\tikzumlCall@nodeNameold\tikzumlCall@nodeName%
  %
  %
  % top node of activity period of call sender
  \begin{pgfonlayer}{connections}%
  \pgfmathparse{\tikzumlCallDT+\tikzumlcallSrc}%
  \draw (\csname tikzumlLastChild@\tikzumlCallStartNodeName \endcsname)+(0,-\pgfmathresult ex) node[coordinate, name=tikzumlTmpNode] {};%
  \node[tikzuml activity style] (st-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};%
  %
  % update last node drawn on sender lifeline
  \expandafter\xdef\csname tikzumlLastChild@\tikzumlCallStartNodeName \endcsname{st-\tikzumlCall@nodeName}%
  %
  % top node of activity period of call receiver
  \ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
    \draw (st-\tikzumlCall@nodeName)+(0,-0.75*\tikzumlCallPadding ex) node[coordinate, name=tikzumlTmpNode] {};%
    \node[tikzuml activity style] (et-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};%
  }{%
    \node[tikzuml activity style] (et-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- st-\tikzumlCall@nodeName) {};%
  }%
  %
  % update last node drawn on receiver lifeline
  \expandafter\xdef\csname tikzumlLastChild@\tikzumlCallEndNodeName \endcsname{et-\tikzumlCall@nodeName}%
  \xdef\tikzumlCallBottomSrc{et-\tikzumlCall@nodeName}%
  \end{pgfonlayer}%
  %
  \stepcounter{tikzumlCallLevel}%
}{%
  \addtocounter{tikzumlCallLevel}{-1}%
  %
  % bottom nodes of activity periods of call sender and receiver
  \begin{pgfonlayer}{connections}%
  \ifnum\tikzumlCall@lastchildNum=\thetikzumlCallNum%
    %
    % this test occurs a bug with latex package preview
    \ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
      \draw (\tikzumlCallBottomSrc)+(0,-\tikzumlCallPadding ex) node[coordinate, name=tikzumlTmpNode] {};%
      \node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};% 
      \draw (eb-\tikzumlCall@nodeName)+(0,-0.75*\tikzumlCallPadding ex) node[coordinate, name=tikzumlTmpNode] {};%
      \node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};% 
    }{%
      \pgfmathsetmacro{\tikzumlCallPaddingd}{0.5*\tikzumlCallPadding}%
      \draw (\tikzumlCallBottomSrc)+(0,-\tikzumlCallPaddingd ex) node[coordinate, name=tikzumlTmpNode] {};%
      \node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};%
      \node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- eb-\tikzumlCall@nodeName) {};%
    }%
    \xdef\tikzumlCallBottomSrc{sb-\tikzumlCall@nodeName}%
  \else%
    %
    % managing time delays from previous/parent fragments
    \ifnum\thetikzumlCallStartFragmentNum>0%
      \let\tikzumlcallheightold\tikzumlCallPadding%
      \pgfmathparse{\tikzumlcallheightold+0.5*\tikzumlFragment@paddingy}%
      \edef\tikzumlcallheight{\pgfmathresult}%
      \addtocounter{tikzumlCallStartFragmentNum}{-1}%
    \fi%
    \ifnum\thetikzumlCallEndFragmentNum>0%
      \let\tikzumlcallheightold\tikzumlCallPadding%
      \pgfmathparse{\tikzumlcallheightold+0.5*\tikzumlFragment@paddingy}%
      \edef\tikzumlcallheight{\pgfmathresult}%
      \addtocounter{tikzumlCallEndFragmentNum}{-1}%
    \fi%
    %
    \ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
      \draw (\tikzumlCallBottomSrc)+(0,-\tikzumlcallheight ex) node[coordinate, name=tikzumlTmpNode] {};%
      \node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};%
      \draw (eb-\tikzumlCall@nodeName)+(0,-0.75*\tikzumlCallPadding ex) node[coordinate, name=tikzumlTmpNode] {};%
      \node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};%
    }{%
      \draw (\tikzumlCallBottomSrc)+(0,-\tikzumlcallheight ex) node[coordinate, name=tikzumlTmpNode] {};%
      \node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};%
      \node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- eb-\tikzumlCall@nodeName) {};%
    }%
    %
    \xdef\tikzumlCallBottomSrc{sb-\tikzumlCall@nodeName}%
  \fi%
  \end{pgfonlayer}%
  %
  %
  % update last nodes drawn on sender and receiver lifelines
  \expandafter\xdef\csname tikzumlLastChild@\tikzumlCallEndNodeName \endcsname{eb-\tikzumlCall@nodeName}%
  \expandafter\xdef\csname tikzumlLastChild@\tikzumlCallStartNodeName \endcsname{sb-\tikzumlCall@nodeName}%
  %
  % draw call arrows
  \begin{pgfonlayer}{connections}%
  {%
    % draw call arrows
    \pgfextractx{\tikzumlCall@xa}{\pgfpointanchor{\tikzumlCallStartNodeName}{center}}%
    \pgfextractx{\tikzumlCall@xb}{\pgfpointanchor{\tikzumlCallEndNodeName}{center}}%
    %
    \draw[thick,double] (st-\tikzumlCall@nodeName.west) -- (et-\tikzumlCall@nodeName.east) node[pos=.5, draw, fill=white,align=center] {\tikzumlCallOp};
    %
  }%
  \end{pgfonlayer}%
}%