% Copyright 2007 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.

% This file loads all the parsing, functions and operator stuff
%
% Version 0.0 08/03/2007

\input pgfmathutil.code.tex
\input pgfmathparser.code.tex
\input pgfmathoperations.code.tex
\input pgfmathbase.code.tex


% \pgfmathsetlength, \pgfmathaddtolength
%
% #1 = dimension register
% #2 = expression
%
% Description:
%
% These functions work similar to \setlength and \addtolength. Only,
% they allow #2 to contain an expression, which is evaluated before
% assignment. Furthermore, the font is setup before the assignment is
% done, so that dimensions like 1em are evaluated correctly.
%
% If #2 starts with "+", then a simple assignment is done (but the
% font is still setup). This is orders of magnitude faster than a
% parsed assignment.

\def\pgfmathsetlength#1#2{%
  \expandafter\pgfmath@onquick#2\pgfmath@%
 {%
 	 % Ok, quick version:
 	 \begingroup%
 	 	\pgfutil@selectfont%
    	\pgfmath@x#2\unskip%
    	\pgfmath@returnone\pgfmath@x%
    \endgroup%
    #1\pgfmathresult pt\relax%
  }%
  {%
   \pgfmathparse{#2}#1\pgfmathresult pt\relax%
}%
}
\def\pgfmathaddtolength#1#2{%
	 \expandafter\pgfmath@onquick#2\pgfmath@%
  {%
  	\begingroup%
  		\pgfutil@selectfont%
  		\pgfmath@x#1\relax%
  		\advance\pgfmath@x#2\unskip%
  		\pgfmath@returnone\pgfmath@x%
    \endgroup%
    #1\pgfmathresult pt\relax%
  }%
  {\pgfmathparse{#2}\advance#1\pgfmathresult pt\relax}%
}

% Not really needed and does not work in plain TeX:
%\def\pgfmathnewcounter#1{%
%	\expandafter\let\expandafter\pgfmath@register\csname c@#1\endcsname%
%	\expandafter\ifx\pgfmath@register\relax%
%    	\expandafter\newcount\csname c@#1\endcsname%
%    	\csname c@#1\endcsname0\relax%
%		\expandafter\def\csname the#1\endcsname{\expandafter\the\csname c@#1\endcsname}%
%	\else% Do nothing.
%   \fi}%
   
% \pgfmathsetcounter, \pgfmathaddtocounter
%
% Results of parsing are truncated.
%
\def\pgfmathsetcounter#1#2{%
  \expandafter\pgfmath@onquick#2\pgfmath@%
  {%
    \csname c@#1\endcsname=#2\relax%
  }%
  {%
    \pgfmath@ifundefined{c@#1}{\pgfmath@error{No counter named '#1' is known}{}}{%
      \pgfmathparse{#2}%
      \afterassignment\pgfmath@gobbletilpgfmath@%
      \csname c@#1\endcsname\pgfmathresult\relax\pgfmath@%
    }%
  }%
}

\def\pgfmathaddtocounter#1#2{%
  \expandafter\pgfmath@onquick#2\pgfmath@%
  {%
    \advance\csname c@#1\endcsname by#2\relax%
  }%
  {%
    \pgfmath@ifundefined{c@#1}{\pgfmath@error{No counter named '#1' is known}{}}{%
      \edef\pgfmath@addtocountertemp{\expandafter\the\csname c@#1\endcsname}%
      \pgfmathparse{#2}%
      \afterassignment\pgfmath@gobbletilpgfmath@%
      \csname c@#1\endcsname\pgfmathresult\relax\pgfmath@%
      \expandafter\advance\csname c@#1\endcsname\pgfmath@addtocountertemp%
    }%
  }%
}

% \pgfmathsetcount, \pgfmathaddtocount
%
% Results of parsing are truncated.
%
\def\pgfmathsetcount#1#2{%
  \expandafter\pgfmath@onquick#2\pgfmath@%
  {%
    #1#2\relax%
  }%
  {%
    \pgfmathparse{#2}%
    \afterassignment\pgfmath@gobbletilpgfmath@%
    #1\pgfmathresult\relax\pgfmath@%
  }%
}

\def\pgfmathaddtocount#1#2{%
  \expandafter\pgfmath@onquick#2\pgfmath@%
  {%
    \advance#1 by#2\relax%
  }%
  {%
    \edef\pgfmath@addtocounttemp{\the#1}%
    \pgfmathparse{#2}%
     \afterassignment\pgfmath@gobbletilpgfmath@%
     #1\pgfmathresult\relax\pgfmath@%
     \advance#1\pgfmath@addtocounttemp%
  }%
}

\def\pgfmathsetmacro#1#2{%
	\expandafter\pgfmath@onquick#2\pgfmath@%
  {%
  		\begingroup%
    		\afterassignment\pgfmath@gobbletilpgfmath@%
    		\pgfmath@x#2pt\relax\pgfmath@%
    		\edef#1{\pgfmath@tonumber{\pgfmath@x}}%
    		\pgfmath@smuggleone{#1}
    	\endgroup%
  }%
  {%
    \pgfmathparse{#2}%
    \edef#1{\pgfmathresult}%
  }%
}

\def\pgfmathtruncatemacro#1#2{%
	\expandafter\pgfmath@onquick#2\pgfmath@%
  {%
  		\begingroup%
    		\afterassignment\pgfmath@gobbletilpgfmath@%
    		\c@pgfmath@counta#2\relax\pgfmath@%
    		\edef#1{\the\c@pgfmath@counta}%
    		\pgfmath@smuggleone{#1}
    	\endgroup%
  }%
  {%
    \pgfmathparse{#2}%
    \edef#1{\pgfmathresult}%
  }%
}

% Check whether a given parameter starts with quick.
%
% The command should be followed by nonempty text, ending with
% \pgfmath@ as a stop-token. Then should follow
%
% #1 = code to execute if text starts with +
% #2 = code to execute if text does not
%
% Example:
%
% \pgfmath@onquick+0pt\pgfmath@{is quick}{is slow}

\def\pgfmath@onquick{%
  \afterassignment\pgfmath@afterquick%
  \let\pgfmath@next=%
}

\def\pgfmath@afterquick#1\pgfmath@{%
  \ifx\pgfmath@next+%
    \expandafter\pgfmath@firstoftwo%
  \else%
    \expandafter\pgfmath@secondoftwo%
  \fi%
}