% Copyright 2008 by Mark Wibrow
%
% 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.

\usepgfmodule{decorations}


% A marking decoration is used to add markings (which are just pgf
% scopes, essentially) at certain positions of a path.

\pgfkeys{
  /pgf/decoration/reset marks/.code=\let\pgf@lib@dec@mark@marks=\pgfutil@empty,
  /pgf/decoration/mark/.code=\pgf@lib@dec@parsemark#1\pgf@lib@dec@stop,
}

\let\pgf@lib@dec@mark@marks=\pgfutil@empty

\def\pgf@lib@dec@parsemark at position#1with#2\pgf@lib@dec@stop{%
  \expandafter\def\expandafter\pgf@lib@dec@mark@marks\expandafter{\pgf@lib@dec@mark@marks%
    \pgf@lib@dec@domark{#1}{#2}%
  }%
}

\def\pgf@lib@dec@arrowhead#1#2{%
  \expandafter\ifx\csname tikz@special@arrow@end#2\endcsname\relax% be nice to TikZ
    \pgfsetarrowsend{#2}
  \else%
    \pgfsetarrowsend{\csname tikz@special@arrow@end#2\endcsname}%
  \fi%
  \pgf@x=0pt%
  \pgf@shorten@end%
  \pgftransformxshift{-\pgf@x}
  \pgftransformxscale{#1}
  \pgflowlevelsynccm%
  \pgflowlevelobj{}{\pgf@endarrow}%
}

\def\pgf@lib@dec@doarrowhead#1{%
  \pgf@lib@dec@arrowhead{1}{#1}%
}
\def\pgf@lib@dec@doarrowheadrev#1{%
  \pgf@lib@dec@arrowhead{-1}{#1}%
}


\pgfdeclaredecoration{markings}{pre}
{
  \state{pre}
  [
    width=0pt,
    persistent precomputation={%
      \pgf@lib@dec@mark@marks\pgf@lib@dec@mark@last%
      \let\arrow=\pgf@lib@dec@doarrowhead%
      \let\arrowreversed=\pgf@lib@dec@doarrowheadrev%
    },
    next state=skipper
  ]
  {}

  \state{skipper}[width=\pgf@lib@dec@computed@width-\pgfdecoratedcompleteddistance-1sp,
                  next state=\pgf@lib@dec@next@state]{}
  
  \state{main}
  [
    width=1sp,
    next state=pre
  ]
  {%
    \pgfinterruptpath%
      \pgfscope%
        \let\pgf@lib@dec@mark@marks=\pgfutil@empty%
        \pgf@lib@dec@computed@action%
      \endpgfscope%
    \endpgfinterruptpath%
  }%

  \state{final}[width=\pgfdecoratedremainingdistance]{}
}

\def\pgf@lib@dec@domark#1#2#3\pgf@lib@dec@mark@last{%
  \def\pgf@lib@dec@mark@marks{#3}%
  \pgf@lib@dec@parsenum{#1}%
  \def\pgf@lib@dec@computed@action{#2}%
  \def\pgf@lib@dec@next@state{main}%
}

\def\pgf@lib@dec@parsenum#1{%
  \pgfmathparse{#1}%
  \ifpgfmathunitsdeclared%
    \ifdim\pgfmathresult pt<0pt\relax%
      \edef\pgf@lib@dec@computed@width{\pgfdecoratedpathlength\pgfmathresult pt}%
    \else%
      \edef\pgf@lib@dec@computed@width{\pgfmathresult pt}%
    \fi%
  \else%  
    \ifdim\pgfmathresult pt<0pt\relax%
      \edef\pgf@lib@dec@computed@width{\pgfdecoratedpathlength\pgfmathresult*\pgfdecoratedpathlength}%
    \else%
      \edef\pgf@lib@dec@computed@width{\pgfmathresult*\pgfdecoratedpathlength}%
    \fi%
  \fi%
}

\def\pgf@lib@dec@mark@last{%
  \def\pgf@lib@dec@next@state{final}%
}


\endinput