%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% This is a helper package with an elementary array datastructure,
% featuring O(1) index access and O(N) creation, deletion, copy.
%
% The following macros are supplied:
%
% \pgfplotsarraynewempty
% \pgfplotsarraynew
% \pgfplotsarraycopy
% \pgfplotsarraypushback
% \pgfplotsarraysize
% \pgfplotsarrayselect
% \pgfplotsarrayletentry
% \pgfplotsarraycheckempty
% \pgfplotsarrayforeach
%
% Copyright 2007/2008 by Christian Feuersänger.
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
% 
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
% 
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.
%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcount\c@pgfplotsarray@tmp
\newif\ifpgfplotsarrayempty

% Creates a new, empty array.
\long\def\pgfplotsarraynewempty#1{%
	\pgfplotsarray@@def{#1@size}{0}%
}

% Invokes code '#2' if the array named '#1' exists and '#3' if it does
% not exist.
\def\pgfplotsarrayifdefined#1#2#3{%
	\pgfutil@ifundefined{#1@size}{#3}{#2}%
}%

% Creates a new array with an abirtrary number of elements.
% Arguments:
% #1: the array's name (a macro name)
% #2: the elements in the form 
%     first\\second\\third\\ ...\\
%     like in tabular with one column.
%
% Example:
% \pgfplotsarraynew\fooarray{First Element\\Second Element\\Third Element\\}
%
% WARNING: do NOT forget the final '\\'!
\long\def\pgfplotsarraynew#1#2{%
	\pgfplotsarraynewempty{#1}%
	\long\def\pgfplotsarraynew@impl@rest{#2}%
	\pgfutil@loop
	\ifx\pgfplotsarraynew@impl@rest\pgfutil@empty
		\pgfplots@loop@CONTINUEfalse
	\else
		\pgfplots@loop@CONTINUEtrue
	\fi
	\ifpgfplots@loop@CONTINUE
		\expandafter\pgfplotsarraynew@impl\pgfplotsarraynew@impl@rest\toarray#1\relax
	\pgfutil@repeat
}

% helper macro for \pgfplotsarraynew
\long\def\pgfplotsarraynew@impl#1\\#2\toarray#3{%
	\pgfplotsarraypushback#1\to#3\relax%
	\def\pgfplotsarraynew@impl@rest{#2}%
}


\def\pgfplotsarray@@let#1=#2{%
	\def\pgfplotsarray@TMP@@{\expandafter\let\csname\string#1\endcsname}%
	\expandafter\pgfplotsarray@TMP@@\expandafter=\csname\string#2\endcsname
}%

\def\pgfplotsarray@@def#1{%
	\expandafter\def\csname\string#1\endcsname
}%
\def\pgfplotsarray@@edef#1{%
	\expandafter\edef\csname\string#1\endcsname
}%

\def\pgfplotsarray@@getsizeto#1#2{%
	\pgfplotsarraysize{#1}\to\c@pgfplotsarray@tmp
	\edef#2{\the\c@pgfplotsarray@tmp}%
}%

% Copies array #1 to array #2.
\def\pgfplotsarraycopy#1\to#2{%
	\pgfplotsarray@@let{#2@size}={#1@size}%
	\pgfplotsarray@@getsizeto{#1}{\pgfplotsarray@TMP}%
	\c@pgfplotsarray@tmp=0
	\pgfutil@loop
	\ifnum\c@pgfplotsarray@tmp<\pgfplotsarray@TMP
	\pgfplotsarray@@let{#2@\the\c@pgfplotsarray@tmp}={#1@\the\c@pgfplotsarray@tmp}%
	\advance\c@pgfplotsarray@tmp by1
	\pgfutil@repeat
}



% #1: the item to append
% #2: the array as macro name
% Example:
% \pgfplotsarraypushback Next last element\to\fooarray
\long\def\pgfplotsarraypushback#1\to#2{%
	\pgfplotsarraysize{#2}\to\c@pgfplotsarray@tmp
	\pgfplotsarray@@def{#2@\the\c@pgfplotsarray@tmp}{#1}%
	\advance\c@pgfplotsarray@tmp by1
	\pgfplotsarray@@edef{#2@size}{\the\c@pgfplotsarray@tmp}%
}


% Counts the number of elements in array #1, storing it into the count
% register #2.
% Example:
% \pgfplotsarraysize\foo\to{\count0}%
% \the\count0
\long\def\pgfplotsarraysize#1\to#2{%
	#2=\csname\string#1@size\endcsname\relax
}
\long\def\pgfplotsarraysizetomacro#1\to#2{%
	\expandafter\let\expandafter#2\csname\string#1@size\endcsname
}


% Returns the #1th element of array #2 into macro #3
% Arguments:
% #1: a count 0,...,N-1 where N is the array size.
%     You may specify a number of a count.
% #2: a array
% #3: a macro name
% Example:
%   Element 0:
%   \pgfplotsarrayselect0\of\foo\to\elem
%   \elem
%   Element \count1:
%   \pgfplotsarrayselect\count1\of\foo\to\elem
\long\def\pgfplotsarrayselect#1\of#2\to#3{%
	\c@pgfplotsarray@tmp=#1\relax
	\expandafter\let\expandafter#3\expandafter=\csname\string#2@\the\c@pgfplotsarray@tmp\endcsname%
}
\long\def\pgfplotsarrayletentry#1\of#2=#3{%
	\c@pgfplotsarray@tmp=#1\relax
	\expandafter\let\csname\string#2@\the\c@pgfplotsarray@tmp\endcsname=#3\relax
}

% Sets the boolean \ifpgfplotsarrayempty depending on whether array #1 is empty
% or not.
% Example:
%
% \pgfplotsarraycheckempty\fooarray
% \ifpgfplotsarrayempty
%    List fooarray is empty!
% \else
%    List is not empty.
% \fi
\def\pgfplotsarraycheckempty#1{%
	\ifnum\csname\string#1@size\endcsname=0
		\pgfplotsarrayemptytrue
	\else
		\pgfplotsarrayemptyfalse
	\fi
}


% Iterates through each array element, names it #2 and calls code #3.
% Example:
% \pgfplotsarraynew\fooarray{Eins\\Zwei\\Drei\\}%
% \pgfplotsarrayforeach\fooarray\as\foo{Element \foo\par}%
% results in
%  Element Eins
%  Element Zwei
%  Element Drei
% Each single element will be grouped with TeX groups.
\long\def\pgfplotsarrayforeach#1\as#2#3{%
	\pgfplotsarray@@getsizeto{#1}{\pgfplotsarray@TMP}%
	\c@pgfplotsarray@tmp=0\relax
	\pgfutil@loop
	\ifnum\c@pgfplotsarray@tmp<\pgfplotsarray@TMP\relax
	\begingroup
	\expandafter\let\expandafter#2\expandafter=\csname\string#1@\the\c@pgfplotsarray@tmp\endcsname%
	#3%
	\endgroup
	\advance\c@pgfplotsarray@tmp by1
	\pgfutil@repeat
}

% The same but without groups around #3.
\long\def\pgfplotsarrayforeachungrouped#1\as#2#3{%
	\pgfplotsarray@@getsizeto{#1}{\pgfplotsarray@TMP}%
	\c@pgfplotsarray@tmp=0\relax
	\pgfutil@loop
	\ifnum\c@pgfplotsarray@tmp<\pgfplotsarray@TMP\relax
	\expandafter\let\expandafter#2\expandafter=\csname\string#1@\the\c@pgfplotsarray@tmp\endcsname%
	#3%
	\advance\c@pgfplotsarray@tmp by1
	\pgfutil@repeat
}
