\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{problemset}[2012/01/19 Problem Set For ACM-Style Programming Contests]


\newif\ifplastex
\plastexfalse

\newif\if@footer\@footertrue
\DeclareOption{nofooter}{\@footerfalse}

\newif\if@problemnumbers\@problemnumberstrue
\DeclareOption{noproblemnumbers}{\@problemnumbersfalse}

\newif\if@problemids\@problemidstrue
\DeclareOption{noproblemids}{\@problemidsfalse}

\newif\if@samplenumbers\@samplenumberstrue
\DeclareOption{nosamplenumbers}{\@samplenumbersfalse}

\newif\if@clearevenpages\@clearevenpagestrue

\newif\if@autoincludesamples\@autoincludesamplestrue
\DeclareOption{noautoincludesamples}{\@autoincludesamplesfalse}

\DeclareOption{plainproblems}{
  \@footerfalse
  \@problemnumbersfalse
  \@clearevenpagesfalse
}

\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions\relax

\LoadClass{article}

\RequirePackage{newtxtext}
\RequirePackage{newtxmath}
\RequirePackage{amsmath}          % AMS
\RequirePackage{amssymb}          % AMS
\RequirePackage[OT2,T1]{fontenc}  % Cyrillic and standard % TODO: make alphabet options more general
\RequirePackage[utf8]{inputenc}   % UTF-8 support
\RequirePackage{fancyhdr}         % Headers
\RequirePackage{graphicx}         % Graphics
\RequirePackage{subfigure}        % Subfigures
\RequirePackage{wrapfig}          % Illustrations
\RequirePackage{import}           % Proper file inclusion
\RequirePackage{fancyvrb}         %
\RequirePackage{listingsutf8}     % For samples
\RequirePackage[left=1in,right=1in,top=0.75in,bottom=0.75in]{geometry}
%\RequirePackage{fullpage}        % Set up margins for full page
\RequirePackage{url}              % Urls
\RequirePackage[normalem]{ulem}   % \sout
\RequirePackage[colorlinks=true,implicit=false]{hyperref}
\ifplastex\else
\RequirePackage{xparse}
\RequirePackage{xifthen}
\RequirePackage[abs]{overpic}
\setlength{\unitlength}{1pt}
\newcommand\PrintPieces[1]{#1 }
\DeclareDocumentCommand\RemoveSlashes{>{\SplitList{\\}}m}
     {\ProcessList{#1}\PrintPieces}
\RequirePackage{pgffor}
\RequirePackage{pbox}
\fi

%% Commands used to set name, logo, etc of contest
\newcommand*{\contestshortname}[1]{\def\@contestshortname{#1}}
\newcommand*{\contestlogo}[1]{\def\@contestlogo{#1}}
\newcommand*{\location}[1]{\def\@location{#1}}
\newcommand*{\licenseblurb}[1]{\def\@licenseblurb{#1}}
\newcommand*{\problemlanguage}[1]{\def\@problemlanguage{#1}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Modified to generate custom sponsor logos as in Bill Poucher's 
%% example. -- Larry Pyeatt

% Commands related to the banner
\addtolength{\headheight}{0.25in}
\addtolength{\textheight}{-0.25in}
\setlength{\headsep}{12pt}
\newsavebox{\PS@headerbox}
\savebox{\PS@headerbox}{}
\newlength{\PS@headerboxheight}
\setlength{\PS@headerboxheight}{0pt}

\newif\if@haveheaderlogo
\@haveheaderlogofalse
\def\@headerlogo{}
\newcommand*{\headerlogo}[1]{
  \@haveheaderlogotrue
  \def\@headerlogo{#1}
}

% Command to build the banner
\newcommand{\make@PS@headerbox}{
  \if@haveheaderlogo
  \definecolor{ACMblue}{RGB}{83,127,201}
  \savebox{\PS@headerbox}{\includegraphics[width=\textwidth]{\@headerlogo}}
  \settoheight{\PS@headerboxheight}{\usebox\PS@headerbox}%
  \savebox{\PS@headerbox}{\noindent
    \begin{minipage}{\textwidth}\noindent
      \begin{overpic}[unit=1pt,width=\textwidth]{\@headerlogo}%
        \put(0,5){\makebox[\textwidth]{\centerline{\fontsize{10.5}{12}\fontfamily{phv}\selectfont\textcolor{white}{\@contestheadername}}}}
      \end{overpic}
      \ifnum\value{nr@sp}>0
      \makebox[\textwidth]{\hfill\resizebox{!}{\@headerlogoheight}{\make@logos}}
      \else
      \makebox[\textwidth]{\hfill\resizebox{!}{\@headerlogoheight}{\strut}}
      \fi
      \textcolor{ACMblue}{\rule{\textwidth}{2pt}}
    \end{minipage}%
  }
  \addtolength{\textheight}{\headheight}
  \setlength{\headheight}{\PS@headerboxheight}
  \addtolength{\headheight}{2\@headerlogoheight}
  \addtolength{\headheight}{20pt}
  \addtolength{\textheight}{-\headheight}
  \else
  \savebox{\PS@headerbox}{}
  \fi
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Commands for generating frontpage from a PDF page -- Larry Pyeatt.
% default vertical skip before customizations begin
\def\@headskip{0in}
\def\@nameskip{0in}
\def\@dateskip{0in}
\def\@sponsorskip{0in}
\def\@bottomskip{4.5in}

% this gets rid of some plastex errors
\ifplastex\newcommand{\ifthenelse}[2]{}\newcommand{\isempty}[1]{}\else\fi

\newsavebox{\@tmpbox}
\newlength{\@logoheight}
\setlength{\@logoheight}{0.5in}
\newlength{\@headerlogoheight}
\setlength{\@headerlogoheight}{0.125in}

\newcounter{nr@sp}
\setcounter{nr@sp}{0}

% command to change the height of logos on front page
\newcommand{\frontlogoheight}[1]{\setlength{\@logoheight}{#1}}

% command to change the height of logos on banner
\newcommand{\headerlogoheight}[1]{\setlength{\@headerlogoheight}{#1}}

%% command to set contest name for front page and optionally adjust vertical skip
\newcommand{\contestname}[2][]{\ifthenelse{\isempty{#1}}{}{\def\@nameskip{#1}}\def\@contestname{#2}\def\@contestheadername{\RemoveSlashes{#2}}}

%% command to set contest date and optionally adjust vertical skip
\newcommand{\contestdate}[2][]{\ifthenelse{\isempty{#1}}{}{\def\@dateskip{#1}}\def\@contestdate{#2}}

%% command to add a sponsor logo - first arg is the text to show second arg is filename
\newcommand{\sponsorlogo}[3][]{\stepcounter{nr@sp}\g@addto@macro\make@logos{\make@logoentry{#2}{#3}{#1}}}

%% command to show the PDF front page and insert region and site customization
\newcommand{\makefrontpage}{
\thispagestyle{empty}
\definecolor{ACMblue}{RGB}{83,127,201}
\includepdf[pagecommand={\vspace*{\@headskip}\centerline{\fontsize{22}{25}\bfseries\fontfamily{phv}\selectfont\textcolor{ACMblue}{}}\vfill\centerline{\fontsize{22}{25}\fontfamily{phv}\selectfont\textcolor{red}{}}\vfill\vspace*{\@nameskip}%
%\begin{minipage}{\textwidth}\centering\fontsize{30}{36}\bfseries\fontfamily{phv}\selectfont\textcolor{ACMblue}{\@contestname}\end{minipage}%
\vfill\vspace*{\@dateskip}\centerline{\LARGE%\bfseries
\fontfamily{phv}\selectfont\textcolor{ACMblue}{\@contestdate}}\vfill\vspace*{\@sponsorskip}\ifnum\value{nr@sp}>0\centering\make@logos\fi\vfill\vspace*{\@bottomskip}}]{\@contestfrontpage}
\clearpage
\cleardoublepage
}

% Initialize everything
\contestname{}
\contestshortname{}
\contestlogo{}
\location{}
\licenseblurb{}
\problemlanguage{}
\newcommand{\contestfrontpage}[1]{
  \def\@contestfrontpage{#1}
}
\contestfrontpage{}

% internal macros for building the list of logos
\newcommand{\make@logoentry}[3]{%
\definecolor{baryellow}{RGB}{250,180,29}%
\definecolor{textred}{RGB}{177,33,28}%
\ifthenelse{\isempty{#3}}{\def\scale{1.0}}{\def\scale{#3}}
\hspace*{10pt}\ %
$\vcenter{\hbox{\includegraphics[height=\scale\@logoheight]{#2}}}$%
\parbox[c][\@logoheight][c]{11pt}{\hspace{5pt}\textcolor{baryellow}{\rule{2pt}{\@logoheight}}}\fontsize{12}{13}\fontfamily{phv}\selectfont\textcolor{textred}{\pbox[c]{2in}{#1}}}
  
\newcommand{\make@logos}{}


% End of Larry Pyeatt's additions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Typesetting sections in a problem

\renewcommand\section{\@startsection{section}{1}{\z@}%
                                   {-3ex}%
                                   {1ex}%
                                   {\normalfont\large\sf\bfseries}}

\renewcommand\subsection{\@startsection{subsection}{2}{\z@}%
                                     {-3.55ex}%
                                     {1.7ex}%
                                     {\normalfont\normalsize\sf\bfseries}}

\renewcommand{\contentsname}{Problems}

% TODO: make last command of illustration optional
\newcommand{\illustration}[3]{
  \begin{wrapfigure}{r}{#1\textwidth}
    \includegraphics[width=#1\textwidth]{#2}
    \begin{flushright}
      \vspace{-9pt}
      \tiny #3
    \end{flushright}
    \vspace{-15pt}
  \end{wrapfigure}
  \par
  \noindent
}


%% Redefine cleardoublepage to put a text on even-numbered empty
%% pages.
\newcommand{\makeemptypage}{
  ~\thispagestyle{empty}
  \vfill
  \centerline{\Large \textsf{ This page is intentionally left blank.}}
  \vfill
  \clearpage
}
\renewcommand{\cleardoublepage}{
  \clearpage%
  \ifodd\value{page}\else\makeemptypage\fi%
}

\newcommand{\clearproblemsetpage}{
  \if@clearevenpages
  \cleardoublepage
  \else
  \clearpage
  \fi
}


%% Set up a problem counter and number problems A B C ...
\newcounter{problemcount}
\setcounter{problemcount}{0}
\newcommand{\problemnumber}{\Alph{problemcount}}

%% Number figures as A.1 A.2... B.1 B.2...
%% (except if we're converting to HTML or if we're not using problem numbers)
\ifplastex\else
\if@problemnumbers
\renewcommand{\thefigure}{\problemnumber.\arabic{figure}}
\fi
\fi


%% Command for starting new problem

%% Problem inclusion
\newcommand{\includeproblem}[1]{
  \startproblem{#1}
  \import{#1/problem_statement/}{problem\@problemlanguage.tex}

  %% Automatically include samples 1..9, if enabled
  \ifplastex\else
  \if@autoincludesamples
  \foreach \SampleNum in {1,...,9} {
    \IfFileExists{\@problemid/data/sample/\SampleNum.in}{
      \displaysample{\@problemid/data/sample/\SampleNum}
    }
  }
  \fi
  \fi
}

\newcommand{\startproblem}[1]{
  \clearproblemsetpage
  \refstepcounter{problemcount}
  \setcounter{samplenum}{0}
  \setcounter{figure}{0}%
  \def\@problemid{#1}
}

\newcommand{\problemname}[1]{
  \def\@problemname{#1}
  \problemheader{\@problemname}{\@problemid}
}

\newcommand{\ps@formattime}[1]{
  #1\ifdim#1in=1in second \else seconds \fi
}

\newread\ps@timelimitfile
\newcommand{\problemheader}[2]{
  \begin{center}
    \vspace*{-10pt} % Added by Larry Pyeatt
    \textsf{
      \if@problemnumbers {\huge Problem \problemnumber\\[3mm]}  \fi
      {\LARGE #1}
      \if@problemids {\\[2mm]{\Large Problem ID: #2}} \fi
      \IfFileExists{#2/.timelimit}{
        \openin\ps@timelimitfile=#2/.timelimit
        \read\ps@timelimitfile to\ps@timelimit
        \\[2mm]{\Large Time limit:\ps@formattime{\ps@timelimit}}
      }{}
      \\[5mm]
    }
  \end{center}
  \addtocontents{toc}{
    \if@problemnumbers \problemnumber \fi
    & \@problemname \\}%
}

%% Commands related to sample data

\newcommand{\sampleinputname}{Sample Input}
\newcommand{\sampleoutputname}{Sample Output}

%% Sample counter
\newcounter{samplenum}
\newcommand{\sampleid}{\arabic{samplenum}}

%% Define the command used to give sample data
%% Takes filename as parameter
\newcommand{\includesample}[1]{
  \displaysample{\@problemid/data/sample/#1}
}

\newcommand{\displaysample}[1]{
  \IfFileExists{#1.in}{}{\ClassError{problemset}{Can't find file '#1.in'}{}}
  \IfFileExists{#1.ans}{}{\ClassError{problemset}{Can't find file '#1.ans'}{}}
  \refstepcounter{samplenum}
  \vspace{0.4cm}
  \sampletable
      {\sampleinputname{} \if@samplenumbers\sampleid\fi}{#1.in}
      {\sampleoutputname{} \if@samplenumbers\sampleid\fi}{#1.ans}
}

\newlength{\PS@sampleidealwidth}
\setlength{\PS@sampleidealwidth}{0.473\textwidth}
\newsavebox{\PS@sampleinbox}
\newsavebox{\PS@sampleoutbox}
\newlength{\PS@sampleinwidth}
\newlength{\PS@sampleoutwidth}
\newlength{\PS@sampletotwidth}

\newcommand{\sampletable}[4]{
  % First find widths of the two files
  \savebox{\PS@sampleinbox}{\lstinputlisting[inputencoding=utf8/latin1,basicstyle=\ttfamily]{#2}}
  \savebox{\PS@sampleoutbox}{\lstinputlisting[inputencoding=utf8/latin1,basicstyle=\ttfamily]{#4}}
  \settowidth{\PS@sampleoutwidth}{\usebox{\PS@sampleoutbox}}
  \settowidth{\PS@sampleinwidth}{\usebox{\PS@sampleinbox}}
  \setlength{\PS@sampletotwidth}{\PS@sampleinwidth}
  \addtolength{\PS@sampletotwidth}{\PS@sampleoutwidth}
  % Check if too wide for side-by-side
  \ifdim\PS@sampletotwidth>2\PS@sampleidealwidth
    \par
    \noindent
    \begin{tabular}{|l|}
      \multicolumn{1}{l}{\textsf{\textbf{#1}}}\\
      \hline
      \parbox[t]{0.968\textwidth}{\vspace{-0.3cm}\usebox{\PS@sampleinbox}}\\
      \hline
    \end{tabular}
    \par
    \vspace{0.25cm}
    \noindent
    \begin{tabular}{|l|}
      \multicolumn{1}{l}{\textsf{\textbf{#3}}}\\
      \hline
      \parbox[t]{0.968\textwidth}{\vspace{-0.3cm}\usebox{\PS@sampleoutbox}}\\
      \hline
    \end{tabular}
  \else
  % Side by side possible, figure out if adjustments are needed.
    \ifdim\PS@sampleoutwidth>\PS@sampleidealwidth% Sample out too large
      \setlength{\PS@sampleinwidth}{2\PS@sampleidealwidth}
      \addtolength{\PS@sampleinwidth}{-\PS@sampleoutwidth}
    \else
      \ifdim\PS@sampleinwidth>\PS@sampleidealwidth% Sample in too large
         \setlength{\PS@sampleoutwidth}{2\PS@sampleidealwidth}
         \addtolength{\PS@sampleoutwidth}{-\PS@sampleinwidth}
      \else% Ideal case: neither sample in nor sammple out too large
         \setlength{\PS@sampleinwidth}{\PS@sampleidealwidth}
         \setlength{\PS@sampleoutwidth}{\PS@sampleidealwidth}
      \fi
    \fi
    \par
    \noindent
    \begin{tabular}{|l|l|}
      \multicolumn{1}{l}{\textsf{\textbf{#1}}} &
      \multicolumn{1}{l}{\textsf{\textbf{#3}}} \\
      \hline
      \parbox[t]{\PS@sampleinwidth}{\vspace{-0.3cm}\usebox{\PS@sampleinbox}}
      &
      \parbox[t]{\PS@sampleoutwidth}{\vspace{-0.3cm}\usebox{\PS@sampleoutbox}}
      \\
      \hline
    \end{tabular}
  \fi
  \par
}

% Remaining part of file is headers and toc, not tested with plasTeX
% and should not be used in plastex mode
\ifplastex\else

\AtBeginDocument{
  %% Set up headers
  \fancypagestyle{problem}{
    \make@PS@headerbox % Added by Larry Pyeatt
    \fancyhf{} % Clear old junk
    \fancyhead[C]{\usebox{\PS@headerbox}}
    \if@footer
    \fancyfoot[L]{
      \emph{
        \@contestshortname{}
        \ifdefined\@problemname
          \if@problemnumbers Problem \problemnumber:{} \fi
          \@problemname
        \fi
        \ifx\@licenseblurb\@empty\relax\else
        \\\@licenseblurb
        \fi
      }
    }
    \fancyfoot[R]{\thepage}
    \fi
  }
  \renewcommand{\headrulewidth}{0pt}
  \pagestyle{problem}
  % Set up table of contents for cover page
  \addtocontents{toc}{\protect\begin{tabular}{cl}}
}

\AtEndDocument{
  \clearproblemsetpage
  % Annoyingly enough addtocontents won't work at end of doc
  \immediate\write\@auxout{%
    \string\@writefile{toc}{\string\end{tabular}}%
  }
}

\fi
