


% ==========================================================================================================
% Absolute Textpositioning
% ----------------------------------------------------------------------------------------------------------
% see http://www.tex.ac.uk/ctan/macros/latex/contrib/textpos/textpos.pdf
\ProvidesPackage{cxltx-style-position-absolute}
\usepackage[absolute,overlay,quiet]{textpos}
\usepackage{calc}%                  http://ctan.org/pkg/calc
\usepackage[nomessages]{fp}%        http://ctan.org/pkg/fp
\usepackage{changepage}%            http://ctan.org/pkg/changepage
\usepackage{cxltx-style-equals}%
\usepackage{cxltx-style-oddeven}%
\usepackage{cxltx-style-trm}%

\makeatletter


% Commands / values to keep track of coordinates origin characteristics:
\newcommand{\@paOddLeftMargin}{null}
\newcommand{\@paEvenLeftMargin}{null}
\newcommand{\@paTopMargin}{null}
\newcommand{\@paTemp}{null}

% Records type of origin (`paper`, `text`, or `custom ($x,$y)`)
\newcommand{\paOriginIs}{null}

% An alias for `textpos` `\textblockorigin`:
\newcommand{\paOriginTo}[2]{%
  \textblockorigin{#1}{#2}%
  \renewcommand{\paOriginIs}{custom (#1,#2)}%
  }

% Set origin to paper edge:
\newcommand{\paOriginToPaper}{%
  \textblockorigin{0mm}{0mm}%
  \renewcommand{\paOriginIs}{paper}%
  }

% ----------------------------------------------------------------------------------------------------------
% http://tex.stackexchange.com/a/51750/28067
\def\gnewcommand{\g@star@or@long\gnew@command}
\def\grenewcommand{\g@star@or@long\grenew@command}
\def\g@star@or@long#1{%
  \@ifstar{\let\l@ngrel@x\global#1}{\def\l@ngrel@x{\long\global}#1}}
\def\gnew@command#1{\@testopt{\@gnewcommand#1}0}
\def\@gnewcommand#1[#2]{%
  \kernel@ifnextchar [{\@gxargdef#1[#2]}%
                {\@argdef#1[#2]}}
\let\@gxargdef\@xargdef
\patchcmd{\@gxargdef}{\def}{\gdef}{}{}
\let\grenew@command\renew@command
\patchcmd{\grenew@command}{\new@command}{\gnew@command}{}{}

% ----------------------------------------------------------------------------------------------------------
% Check whether we're on an odd or an even page, and set `\paCurrentOddEven` to `odd` or `even`:
\newcommand{\@paSetOriginIfOriginIsText}{
  % ........................................................................................................
  % Check that origin is set to `text`; otherwise, do nothing:
  \eqIfTextEqualsThen{\paOriginIs}{text}{%
    % ......................................................................................................
    % Calculate top margin if it is 'null':
    \eqIfTextEqualsThen{\@paTopMargin}{null}{%
      \typeout{\trmSolBlue{(eq: Calculating top margin}}%
      \FPeval{\@paTemp}{(\number\headsep+\number\headheight+\number\topmargin+\number\voffset+4736286)/186467}%
      \global\let\@paTopMargin\@paTemp%
      \typeout{\trmSolBlue{eq: -> @paTopMargin: \@paTopMargin)}}%
      }%
    % ......................................................................................................
    \oeIfOddPage{% If this is an odd page:
      % Re-calculate odd left margin if it is 'null':
      \eqIfTextEqualsThen{\@paOddLeftMargin}{null}{%
        \typeout{\trmSolBlue{(eq: Calculating odd left margin}}%
        \FPeval{\@paTemp}{(\number\hoffset+\number\oddsidemargin+4736286)/186467}%
        \global\let\@paOddLeftMargin\@paTemp%
        \typeout{\trmSolBlue{eq: -> @paOddLeftMargin: \@paOddLeftMargin)}}%
        }%
      % Set origin for odd page:
      \textblockorigin{\@paOddLeftMargin mm}{\@paTopMargin mm}%
    % ......................................................................................................
    }{% If this is an even page:
      % Re-calculate even left margin if it is 'null':
      \eqIfTextEqualsThen{\@paEvenLeftMargin}{null}{%
        \typeout{\trmSolBlue{(eq: Calculating even left margin}}%
        \FPeval{\@paTemp}{(\number\evensidemargin+4736286)/186467}%
        \global\let\@paEvenLeftMargin\@paTemp%
        \typeout{\trmSolBlue{eq: -> @paEvenLeftMargin: \@paEvenLeftMargin)}}%
        }%
      % Set origin for even page:
      \textblockorigin{\@paEvenLeftMargin mm}{\@paTopMargin mm}%
    % ......................................................................................................
    }
    }
  }%

% ----------------------------------------------------------------------------------------------------------
% Set origin to top left corner of text area:
\newcommand{\paOriginToText}{%
  % Set origin to 'text':
  \renewcommand{\paOriginIs}{text}%
  % Set margins to 'null', awaiting call to `\@paSetOriginIfOriginIsText`:
  \renewcommand{\@paOddLeftMargin}{null}%
  \renewcommand{\@paEvenLeftMargin}{null}%
  \renewcommand{\@paTopMargin}{null}%
  }


% Define strut dimensions:
\newdimen\@paStrutHeight
\newdimen\@paStrutWidth
\newdimen\@paStrutDepth
\@paStrutWidth=0mm
\@paStrutHeight=0mm
\@paStrutDepth=0mm

% Define text dimensions:
\newdimen\@paTextWidth

% Remove horizontal and vertical spacing from paragraphs; curiously, we have to use a negative value for
% `\parskip` (see http://http://tex.stackexchange.com/questions/167628):
\newcommand{\@paNoSpacing}{\setlength{\parskip}{-\baselineskip}\setlength{\parindent}{0pt}}

% Determine locally valid strut dimensions:
\newcommand{\paGauge}[1]{%
  \settoheight{\@paStrutHeight}{#1}%
  \settodepth{\@paStrutDepth}{#1}%
  \@paSetHeightDepthRatio%
  }

\newcommand{\@paSetHeightDepthRatio}{%
  \FPeval{\paHeightDepthRatio}{\number\@paStrutHeight/(\number\@paStrutHeight+\number\@paStrutDepth)}%
  }

% Run gauging macro once to set default values:
\newcommand{\paGaugeSample}{\paGauge{abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!?§\$}}%

% Manually adjust strut dimensions:
\newcommand{\paSetStrut}[2]{%
  \@paStrutHeight=#1%
  \@paStrutDepth=#2%
  \@paSetHeightDepthRatio%
  }


% ==========================================================================================================
%
% ----------------------------------------------------------------------------------------------------------
% Define a strut with the desired dimensions:
\newcommand{\paStrut}{{\color{blue}\vrule height\@paStrutHeight width\@paStrutWidth depth\@paStrutDepth}}

% ----------------------------------------------------------------------------------------------------------
\newcommand{\paLeft}[3]{{%
  \@paSetOriginIfOriginIsText%
  \settowidth{\@paTextWidth}{#3{\paStrut}}
  \begin{textblock*}{\@paTextWidth}[0,\paHeightDepthRatio](#1,#2)%
    \@paNoSpacing%
    \flushleft% needed although it should be gratuitous
    #3%
    {\paStrut}%
    \end{textblock*}%
  }}

% ----------------------------------------------------------------------------------------------------------
\newcommand{\paCenter}[3]{{%
  \@paSetOriginIfOriginIsText%
  \settowidth{\@paTextWidth}{{\paStrut}#3{\paStrut}}
  \begin{textblock*}{\@paTextWidth}[0.5,\paHeightDepthRatio](#1,#2)%
    \@paNoSpacing%
    \center%
    {\paStrut}%
    #3%
    {\paStrut}%
    \end{textblock*}%
  }}

% ----------------------------------------------------------------------------------------------------------
\newcommand{\paRight}[3]{{%
  \@paSetOriginIfOriginIsText%
  \settowidth{\@paTextWidth}{{\paStrut}#3}
  \begin{textblock*}{\@paTextWidth}[1,\paHeightDepthRatio](#1,#2)%
    \@paNoSpacing%
    \flushright% needed although it should be gratuitous
    {\paStrut}%
    #3%
    \end{textblock*}%
  }}


% ==========================================================================================================
%
% ----------------------------------------------------------------------------------------------------------
\newcommand{\paLeftGauge}[3]{{%
  \paGauge{#3}%
  \paLeft{#1}{#2}{#3}%
  }}

% ----------------------------------------------------------------------------------------------------------
\newcommand{\paCenterGauge}[3]{{%
  \paGauge{#3}%
  \paCenter{#1}{#2}{#3}%
  }}

% ----------------------------------------------------------------------------------------------------------
\newcommand{\paRightGauge}[3]{{%
  \paGauge{#3}%
  \paRight{#1}{#2}{#3}%
  }}

% ==========================================================================================================
%
% ----------------------------------------------------------------------------------------------------------
\def\paTopLeft{\@ifstar\@@paTopLeft\@paTopLeft}

% ----------------------------------------------------------------------------------------------------------
\newcommand{\@paTopLeft}[3]{{%
  \@paSetOriginIfOriginIsText%
  \settowidth{\@paTextWidth}{#3{\paStrut}}
  \begin{textblock*}{\@paTextWidth}[0,0](#1,#2)%
    \@paNoSpacing%
    \flushleft% needed although it should be gratuitous
    #3%
    {\paStrut}%
    \end{textblock*}%
  }}

% ----------------------------------------------------------------------------------------------------------
\newcommand{\@@paTopLeft}[3]{{%
  \@paSetOriginIfOriginIsText%
  \settowidth{\@paTextWidth}{#3}
  \begin{textblock*}{\@paTextWidth}[0,0](#1,#2)%
    \@paNoSpacing%
    \flushleft% needed although it should be gratuitous
    #3%
    \end{textblock*}%
  }}

% ----------------------------------------------------------------------------------------------------------
\newcommand{\paShow}{%
  \textblockrulecolour{orange}
  \TPboxrulesize=0.2mm%
  \TPshowboxestrue%
  \@paStrutWidth=0.8mm%
  }

% ==========================================================================================================
%
% ----------------------------------------------------------------------------------------------------------
% It would appear there is a bug / arcane and undocumented feature in `textpos` which causes boxes to
% vertically shift upon execution of `\TPshowboxesfalse`. We remedy that by *always* 'showing' boxes but
% setting rule width to zero:
\newcommand{\paHide}{%
  \TPboxrulesize=0mm%
  \TPshowboxestrue%
  \@paStrutWidth=0mm%
  }

% ----------------------------------------------------------------------------------------------------------
% Default settings:
\paHide%
\paGaugeSample%
\paOriginToText%

% ##########################################################################################################
% kthxbye:
\makeatother
