%--------------------------------------------
%
% Package pgfplots, library for high-level coordinates.
%
% Copyright 2007/2008/2009 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/>.
%
%--------------------------------------------

\pgfutil@usemodule{pgfcalendar}

% Idea: allow
%--------------------------------------------------
% \begin{tikzpicture}
% 	\begin{axis}[
% 		date coordinates in=x,
% 		xticklabel={\day.\month.},
% 	]
% 	\addplot coordinates {
% 		(2008-01-5, 5)
% 		(2008-01-12, 10)
% 		(2008-01-16, 20)
% 	};
% 	\end{axis}
% \end{tikzpicture}
%--------------------------------------------------

\def\pgfplotslibdateplot@number@to@julian@and@time#1.#2\julianto#3\hourto#4\minuteto#5{%
	#3=#1
	\pgf@xa=0.#2pt
	\multiply\pgf@xa by24
	\afterassignment\pgfplots@gobble@until@relax
	\c@pgf@countb=\the\pgf@xa\relax
	\edef#4{\the\c@pgf@countb}%
	\advance\pgf@xa by-#4pt
	\multiply\pgf@xa by60
	\afterassignment\pgfplots@gobble@until@relax
	\c@pgf@countb=\the\pgf@xa\relax
	% round minutes (we may loose precision here)
	\advance\pgf@xa by-\the\c@pgf@countb pt
	\ifdim\pgf@xa>0.5pt
		\advance\c@pgf@countb by1
		\ifnum\c@pgf@countb=60
			\c@pgf@countb=#4 %
			\advance\c@pgf@countb by1
			\edef#4{\the\c@pgf@countb}%
			\c@pgf@countb=0
		\fi
	\fi
	\edef#5{\the\c@pgf@countb}%
}

% #1 the date
% #2 the hours
% #3 the minutes
% #4 is either empty or is the seconds.
% #5 a macro which will be filled with the date part.
% #6 the macro which will contain a number in the range [0,1]
% representing hours and minutes.
%
% If you don't have seconds, you have to provide the second ':' sign
% as dummy! In that case #4 will be empty.
\def\pgfplotslibdateplot@map@time#1 #2:#3:#4\dateto#5\timeto#6{%
	\pgf@xa=#2pt
	\divide\pgf@xa by24
	\pgf@xb=#3pt
	\divide\pgf@xb by1440
	\advance\pgf@xa by\pgf@xb
	\ifdim\pgf@xa<0pt
		\pgf@xa=0pt
	\else
		\ifdim\pgf@xa>1pt
			\pgf@xa=1pt
		\fi
	\fi
	\def#5{#1}%
	\edef#6{\pgf@sys@tonumber\pgf@xa}%
}%
\def\pgfplotslibdateplot@discard@zero@dot 0.#1\to#2{\def#2{#1}}%

%--------------------------------------------------
%This here extends it to SECONDS, but the precision is too low
% \def\pgfplotslibdateplot@map@time#1 #2:#3:#4\dateto#5\timeto#6{%
% 	\pgf@xa=#2pt
% 	\divide\pgf@xa by24
% 	%
% 	\pgf@xb=#3pt
% 	\divide\pgf@xb by1440
% 	\advance\pgf@xa by\pgf@xb
% 	%
% 	\def\pgfplots@loc@TMPc{#4}%
% 	\ifx\pgfplots@loc@TMPc\pgfutil@empty
% 	\else
% 		\edef\pgfplots@loc@TMPc{\pgfplotslibdateplot@discard@trailing@colon #4}%
% 		\pgf@xb=\pgfplots@loc@TMPc pt
% 		\divide\pgf@xb by1440
% 		\divide\pgf@xb by60
% 		\advance\pgf@xa by\pgf@xb
% 	\fi
% 	%
% 	\ifdim\pgf@xa<0pt
% 		\pgf@xa=0pt
% 	\else
% 		\ifdim\pgf@xa>1pt
% 			\pgf@xa=1pt
% 		\fi
% 	\fi
% 	\def#5{#1}%
% 	\edef#6{\pgf@sys@tonumber\pgf@xa}%
% }%
% \def\pgfplotslibdateplot@discard@trailing@colon#1:{#1}%
%--------------------------------------------------

\let\pgfplots@calender@ZEROSHIFT=\pgfutil@empty
\def\pgfplots@dateplot@ensure@ZEROSHIFT#1{%
	\ifx\pgfplots@calender@ZEROSHIFT\pgfutil@empty
		\ifx\pgfplots@global@dateplot@defaultshift\pgfutil@empty
			\pgfplots@log4{dateplot: setting 'date ZERO={#1}' for this axis.}%
			\pgfplots@dateplot@parse@ZEROSHIFT{#1}%
			\global\let\pgfplots@global@dateplot@defaultshift=\pgfmathresult
		\fi
		%
		\let\pgfplots@calender@ZEROSHIFT=\pgfplots@global@dateplot@defaultshift
	\fi
}%
% defines \pgfplots@calender@ZEROSHIFT to be the zero shift
\def\pgfplots@dateplot@get@ZEROSHIFT{%
	\ifx\pgfplots@calender@ZEROSHIFT\pgfutil@empty
		\ifx\pgfplots@global@dateplot@defaultshift\pgfutil@empty
			% should never happen
			\pgfplots@error{Illegal internal state: no 'date ZERO' value found}%
			\def\pgfplots@calender@ZEROSHIFT{0}%
		\else
			\let\pgfplots@calender@ZEROSHIFT=\pgfplots@global@dateplot@defaultshift
		\fi
	\fi
}%

\def\pgfplots@dateplot@parse@ZEROSHIFT#1{%
	\begingroup
	\pgfcalendardatetojulian{#1}\c@pgf@counta
	\edef\pgfmathresult{\the\c@pgf@counta}%
	\pgfmath@smuggleone\pgfmathresult
	\endgroup
}%

\expandafter\def\expandafter\pgfplots@notify@options@are@set\expandafter{\pgfplots@notify@options@are@set
	\global\let\pgfplots@global@dateplot@defaultshift=\pgfutil@empty
}

\pgfplotsset{
	/pgfplots/date ZERO/.code={%
		\pgfplots@dateplot@parse@ZEROSHIFT{#1}%
		\let\pgfplots@calender@ZEROSHIFT=\pgfmathresult
	},
	/pgfplots/date coordinates in/.code={%
		\pgfkeysdef{/pgfplots/#1 coord trafo}{%
			\begingroup
			\edef\pgfplotstempjuliandate{##1}%
			% check if we also have a TIME like '2006-01-01 11:21'
			\expandafter\pgfutil@in@\expandafter:\expandafter{\pgfplotstempjuliandate}%
			\ifpgfutil@in@
				% we have a TIME!
				\expandafter\pgfplotslibdateplot@map@time\pgfplotstempjuliandate:\dateto\pgfplotstempjuliandate\timeto\pgfplotstemptime
			\else
				\let\pgfplotstemptime=\pgfutil@empty
			\fi
			%
			\expandafter\pgfplots@dateplot@ensure@ZEROSHIFT\expandafter{\pgfplotstempjuliandate}%
			%
			\expandafter\pgfcalendardatetojulian\expandafter{\pgfplotstempjuliandate}\c@pgf@counta
			\advance\c@pgf@counta by-\pgfplots@calender@ZEROSHIFT\relax
			\ifx\pgfplotstemptime\pgfutil@empty
				% no time:
				\edef\pgfmathresult{\the\c@pgf@counta}%
			\else
				% add time fraction (which should be in the range
				% [0,1]).
				\ifdim\pgfplotstemptime pt<1pt
					% discard prefix '0.':
					\expandafter\pgfplotslibdateplot@discard@zero@dot\pgfplotstemptime\to\pgfplotstemptime
					\edef\pgfmathresult{\the\c@pgf@counta.\pgfplotstemptime}%
				\else
					% assume \pgfplotstemptime=1pt :
					\advance\c@pgf@counta by1
					\edef\pgfmathresult{\the\c@pgf@counta}%
				\fi
			\fi
			\pgfmath@smuggleone\pgfmathresult
			\endgroup
		}%
		\pgfkeysdef{/pgfplots/#1 coord inv trafo}{%
			\edef\pgfplotstempjuliandatenumeric{##1}%
			\begingroup
				\pgfplots@dateplot@get@ZEROSHIFT
				%
				\expandafter\pgfplotslibdateplot@number@to@julian@and@time\pgfplotstempjuliandatenumeric\julianto{\c@pgf@counta}\hourto\Hour\minuteto\Minute%
				\advance\c@pgf@counta by\pgfplots@calender@ZEROSHIFT\relax
				\expandafter\pgfcalendarjuliantodate\expandafter{\the\c@pgf@counta}\year\month\day
				\xdef\pgfplotslibdateplot@TMP{%
					\noexpand\def\noexpand\year{\year}%
					\noexpand\def\noexpand\month{\month}%
					\noexpand\def\noexpand\day{\day}%
					\noexpand\def\noexpand\Hour{\Hour}%
					\noexpand\def\noexpand\Minute{\Minute}%
				}%
			\endgroup
			\pgfplotslibdateplot@TMP
			\let\hour=\Hour
			\let\minute=\Minute
			\ifnum\hour<10
				\edef\hour{0\hour}%
			\fi
			\ifnum\minute<10
				\edef\minute{0\minute}%
			\fi
			\def\Second{0}%
			\def\second{00}%
			\edef\lowlevel{##1}%
			\pgfkeysifdefined{/pgfplots/date default inv/#1}{%
				\edef\pgfmathresult{\pgfkeysvalueof{/pgfplots/date default inv/#1}}%
			}{%
				\edef\pgfmathresult{\year-\month-\day\space\hour:\minute:\second}%
			}%
		}%
		\pgfkeysifdefined{/pgfplots/#1ticklabel/.@cmd}{%
			\pgfkeysalso{%
				/pgfplots/#1ticklabel={\tick},%
				/pgfplots/scaled #1 ticks=false,%
				/pgfplots/plot coordinates/math parser=false,%
			}%
		}{%
			% OK. The style can be used for other coordinates as well
			% (like hist/data)
		}%
		%
		\pgfkeysifdefined{/pgfplots/#1 is expr}{%
			\pgfkeyssetvalue{/pgfplots/#1 is expr}{0}%
		}{}%
		%
		% Allow a callback (optional)
		\pgfkeysifdefined{/pgfplots/#1/@execute on coord trafo changed/.@cmd}{%
			\pgfkeysalso {/pgfplots/#1/@execute on coord trafo changed}%
		}{}%
	},
	/pgfplots/date coordinates in/.value required,
	%
	% #1: the argument for 'data coordinates in={#1}
	% #2: the default for the inverse transformation. If there is
	% none, a default will be chosen automatically (with full
	% information)
	/pgfplots/date coordinates default inverse/.style 2 args={%
		/pgfplots/date default inv/#1/.initial=#2,
	},
	/pgfplots/date coordinates default inverse={x}{\year-\month-\day},
	/pgfplots/date coordinates default inverse={y}{\year-\month-\day},
	/pgfplots/date coordinates default inverse={z}{\year-\month-\day},
}
