\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{cntperchap}[2015/05/03 v0.1 -- store counter values per chapter]%
%%
%% License: LaTeX Project Public License version 1.3 
%% Copyright (2015) Dr. Christian Hupfer 
%% Author: Christian Hupfer christian.hupfer@yahoo.de
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%%   http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
%% This work has the LPPL maintenance status `maintained'.
%%
%% This work consists of all files listed in README
%%
%%%%


\RequirePackage{ifthen}
\RequirePackage{assoccnt}
\RequirePackage{morewrites}
\RequirePackage{xpatch}
\RequirePackage{xparse}



%%%% Command options

\define@boolkey{cpskeys}{autodefine}[false]{}

\presetkeys{cpskeys}{autodefine=false}{}%


%%%% Package options
\newif\ifcpsautodefine
\cpsautodefinefalse
\newif\ifcpsdraftmode
\cpsdraftmodetrue

\DeclareOptionX{draft}{\cpsdraftmodetrue}
\DeclareOptionX{final}{\cpsdraftmodefalse}
\DeclareOptionX{autodefine}{\cpsautodefinetrue\presetkeys{cpskeys}{autodefine=true}{}}

\ProcessOptionsX*

\newcommand{\cpscounterlistname}{@counterstowatch}

\listcsadd{\cpscounterlistname}{}



%%%% Internal commands

\newcounter{cps@@currentchapter}
\newcounter{cps@@togglecounter}
\newcounter{cps@@tempcounter}
\newcounter{cps@@cpscounters}

\NewDocumentCommand{\cpschapterstarthook}{}{%
  \stepcounter{cps@@currentchapter}%
  \ifnumgreater{\value{cps@@currentchapter}}{0}{%
    \StoreCountersPerChapter%
  }{}%
  \ResetTotalCounters%
}


% Prepending the \chapter command with some starter hook

\xpretocmd{\chapter}{\cpschapterstarthook}{}{}


% This is a modified version from \@starttoc, being defined in latex.ltx
\newcommand{\@startcountertoc}[1]{%
  \begingroup%
  % Generate the file handle first
  \expandafter\newwrite\csname tf@cps#1\endcsname%
  \makeatletter
  % Read first before deleting it
  \ifcsdef{tf@cps#1}{%
    \IfFileExists{\jobname.cps#1}{%
      \immediate\openin\csname tf@cps#1\endcsname \jobname.cps#1\relax%
      \@readcounternumbersfromfile{#1}%
    }{%
      % Oops, the file is not there :-(
    }%
  }{%
    \typeout{No #1{} counter values so far}%
  }%
  \if@filesw
  % Write only if not `\nofiles` is specified
  \immediate\openout \csname tf@cps#1\endcsname \jobname.cps#1\relax%
  \fi%
  \@nobreakfalse%
  \endgroup%
}


\newcommand{\@readcounternumbersfromfile}[1]{%
  \setcounter{cps@@togglecounter}{0}%  
  \whiledo {\value{cps@@togglecounter} < 1}{%
    \expandafter\read\csname tf@cps#1\endcsname to \cps@@numberfromfile%
    \ifeof\csname tf@cps#1\endcsname%
    \stepcounter{cps@@togglecounter}%
    \else%
    \listcsxadd{#1countlist}{\cps@@numberfromfile}%
    \fi%
  }%
}

\newcommand{\@cpsstorecounter}[1]{%
  \addtocontents{cps#1}{%
    \number\value{cps@total#1}%
  }%
}


\newcommand{\@cpscsloop}[1]{%
  \ifnumgreater{\value{cps@@cpscounters}}{0}{%
    \expandafter\forlistcsloop{\csname #1\endcsname}{\cpscounterlistname}
  }{%
  }%
}

\newcommand{\@cpsloopstorecounters}{%
  \ifnumgreater{\value{cps@@cpscounters}}{0}{%
    \forlistcsloop{\@cpsstorecounter}{\cpscounterlistname}%
  }{%
  }%
}

\newcommand{\@registercounterperchapter}[1]{%
  \listcsxadd{\cpscounterlistname}{#1}%
  \stepcounter{cps@@cpscounters}%
  \listcsxadd{#1countlist}{}%
  \newcounter{cps@total#1}%
  \DeclareAssociatedCounters{#1}{cps@total#1}%
}

%% Searches the list of counter values for the correct chapter 
\newcommand{\@cpssearchcountervalue}[3]{%
  \ifnumequal{#1}{\value{#2}}{%
    #3\listbreak%
  }{%
    \stepcounter{#2}%
  }%
}


%%%%%%%%%%%%%% User commands  %%%%%%%%%%%%%%%%%%%%


\newcommand{\RegisterCounterPerChapter}[2][]{%
  \begingroup
  \setkeys{cpskeys}{#1}%
  \ifltxcounter{#2}{%
    \@registercounterperchapter{#2}%
  }{%
    \ifKV@cpskeys@autodefine
    \newcounter{#2}%
    \@registercounterperchapter{#2}%
    \else%
    % Ignore non existing counters
    \fi
  }%
  \endgroup
}

\newcommand{\RegisterCountersPerChapter}[1]{%
  \forcsvlist{\RegisterCounterPerChapter}{#1}%
}

% Prevent usage later in document body
\@onlypreamble{\RegisterCounterPerChapter}
\@onlypreamble{\RegisterCountersPerChapter}

\newcommand{\ResetTotalCounter}[1]{%
  \setcounter{cps@total#1}{0}%
}


% Reset all total counters
\newcommand{\ResetTotalCounters}{%
  \ifnumgreater{\value{cps@@cpscounters}}{0}{%
    \forlistcsloop{\ResetTotalCounter}{\cpscounterlistname}%
  }{}%	
}

%% Only for statistical purposes. Do not use it in a production run
\newcommand{\IndividualCounterStatistics}[2][\number\value{cps@@currentchapter}]{%
  \ifcpsdraftmode
  \noindent Chapter #1~ has \GetTotalCounter[#1]{#2} #2(s)\par 
  \fi  
}%




%% Only for statistical purposes. Do not use it in a production run
\newcommand{\ShowStatistics}[1][\number\value{cps@@currentchapter}]{%
  \ifcpsdraftmode%
  \ifnumgreater{\value{cps@@cpscounters}}{0}{%
    \forlistcsloop{\IndividualCounterStatistics[\number#1]}{\cpscounterlistname}%
  }{%
    \typeout{No counters registered}%
  }%
  \fi%
}

\newcommand{\GetTotalCounter}[2][\number\value{cps@@currentchapter}]{%
  \setcounter{cps@@tempcounter}{0}%
  \ifcsdef{#2countlist}{%
    \forlistcsloop{\@cpssearchcountervalue{#1}{cps@@tempcounter}}{#2countlist}%
  }{%
    \typeout{Warning: List for counter #2 not defined}%
  }% Failure branch should be improved 
}

\newcommand{\StartCounterToc}{%
  \ifnumgreater{\value{cps@@cpscounters}}{0}{%
    \forlistcsloop{\@startcountertoc}{\cpscounterlistname}%
  }{%
  }%
}

\newcommand{\StoreCountersPerChapter}{%
  \@cpsloopstorecounters%
}

\AtBeginDocument{%
  % Grab the counter 'tocs' 
  \StartCounterToc%
}


\AtEndDocument{%
  % Write the counter values to the file
  \StoreCountersPerChapter%
}


\endinput
