% Copyright (c) 2026 Chris McComb. MIT License.
\NeedsTeXFormat{LaTeX2e}[2020-10-01]
\ProvidesPackage{statusstamp}[2026/09/12 v0.1.0 Distressed document status stamps]
\RequirePackage{xcolor}
\RequirePackage{graphicx}
\RequirePackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
% Declare T1 when needed without changing the document's default encoding.
% The qhv family uses legacy encodings even in a Unicode-engine document.
\@ifundefined{T@T1}{\input{t1enc.def}}{}

\definecolor{statusstampred}{RGB}{205,32,32}
\newif\ifstatusstamp@enabled
\newif\ifstatusstamp@distressed
\newif\ifstatusstamp@selected
\newif\ifstatusstamp@ready
\newsavebox{\statusstamp@box}
\newdimen\statusstamp@x
\newdimen\statusstamp@y
\newdimen\statusstamp@halfheight
\def\statusstamp@text{SUBMITTED}
\def\statusstamp@date{}
\def\statusstamp@color{statusstampred}
\def\statusstamp@papercolor{white}
\def\statusstamp@angle{11}
\def\statusstamp@scale{1}
\def\statusstamp@opacity{.82}
\def\statusstamp@seed{7319}
\def\statusstamp@margin{1cm}
\def\statusstamp@xshift{0pt}
\def\statusstamp@yshift{0pt}
\def\statusstamp@position{center}
\def\statusstamp@layer{background}
\def\statusstamp@select{\statusstamp@selectedtrue}
\statusstamp@enabledtrue
\statusstamp@distressedtrue

\pgfkeys{
  /statusstamp/.is family, /statusstamp,
  text/.code={%
    \if\relax\detokenize{#1}\relax
      \PackageError{statusstamp}{Stamp text must not be empty}{Use enabled=false to hide page stamps.}%
    \else\def\statusstamp@text{#1}\fi},
  date/.store in=\statusstamp@date,
  color/.store in=\statusstamp@color,
  paper-color/.store in=\statusstamp@papercolor,
  angle/.store in=\statusstamp@angle,
  scale/.code={%
    \pgfmathparse{#1}%
    \ifdim\pgfmathresult pt>0pt
      \let\statusstamp@scale\pgfmathresult
    \else
      \PackageError{statusstamp}{Scale must be positive}{Use scale=1 for the original size.}%
    \fi},
  opacity/.code={%
    \pgfmathparse{#1}%
    \ifdim\pgfmathresult pt<0pt
      \PackageError{statusstamp}{Opacity must be between 0 and 1}{Use opacity=.82 for the original appearance.}%
    \else\ifdim\pgfmathresult pt>1pt
      \PackageError{statusstamp}{Opacity must be between 0 and 1}{Use opacity=.82 for the original appearance.}%
    \else
      \let\statusstamp@opacity\pgfmathresult
    \fi\fi},
  seed/.store in=\statusstamp@seed,
  margin/.store in=\statusstamp@margin,
  xshift/.store in=\statusstamp@xshift,
  yshift/.store in=\statusstamp@yshift,
  enabled/.is if=statusstamp@enabled,
  enabled/.default=true,
  distressed/.is if=statusstamp@distressed,
  distressed/.default=true,
  position/.is choice,
  position/center/.code={\def\statusstamp@position{center}},
  position/top-left/.code={\def\statusstamp@position{top-left}},
  position/top-right/.code={\def\statusstamp@position{top-right}},
  position/bottom-left/.code={\def\statusstamp@position{bottom-left}},
  position/bottom-right/.code={\def\statusstamp@position{bottom-right}},
  layer/.is choice,
  layer/background/.code={\def\statusstamp@layer{background}},
  layer/foreground/.code={\def\statusstamp@layer{foreground}},
  pages/.is choice,
  pages/all/.code={\def\statusstamp@select{\statusstamp@selectedtrue}},
  pages/first/.code={\def\statusstamp@select{%
    \ifnum\ReadonlyShipoutCounter=1 \statusstamp@selectedtrue\fi}},
  pages/odd/.code={\def\statusstamp@select{%
    \ifodd\ReadonlyShipoutCounter \statusstamp@selectedtrue\fi}},
  pages/even/.code={\def\statusstamp@select{%
    \ifodd\ReadonlyShipoutCounter\else\statusstamp@selectedtrue\fi}}
}
\newcommand{\statusstampsetup}[1]{%
  \pgfkeys{/statusstamp/.cd,#1}%
  \ifstatusstamp@ready\statusstamp@build\fi
}
\DeclareOption*{\expandafter\statusstampsetup\expandafter{\CurrentOption}}
\ProcessOptions\relax

% Keep the original drawing coordinates and random-call order. TeX Gyre Heros
% is selected locally; loading this package does not change \sfdefault.
\newcommand{\statusstamp@drawing}{%
  \begin{tikzpicture}[x=1cm,y=1cm,baseline=(current bounding box.center)]
    \begin{scope}[rotate=\statusstamp@angle,transform shape]
      \ifx\statusstamp@date\@empty
        \node[inner sep=0pt,text=\statusstamp@color,opacity=\statusstamp@opacity]
          at (0,0) {\resizebox{6.8cm}{1.65cm}{%
            \fontencoding{T1}\fontfamily{qhv}\fontseries{b}\selectfont\statusstamp@text}};
      \else
        \node[inner sep=0pt,text=\statusstamp@color,opacity=\statusstamp@opacity]
          at (0,.30) {\resizebox{6.8cm}{1.0cm}{%
            \fontencoding{T1}\fontfamily{qhv}\fontseries{b}\selectfont\statusstamp@text}};
        \node[inner sep=0pt,text=\statusstamp@color,opacity=\statusstamp@opacity]
          at (0,-.73) {\resizebox{!}{.30cm}{%
            \fontencoding{T1}\fontfamily{qhv}\fontseries{b}\selectfont\statusstamp@date}};
      \fi
      \pgfmathsetmacro{\statusstamp@inneropacity}{\statusstamp@opacity*0.46/0.82}
      \ifstatusstamp@distressed
        \draw[\statusstamp@color,opacity=\statusstamp@opacity,line width=2.5pt,
          decorate,decoration={random steps,segment length=2.3pt,amplitude=.55pt}]
          (-3.82,-1.15) rectangle (3.82,1.15);
        \draw[\statusstamp@color,opacity=\statusstamp@inneropacity,line width=.9pt,
          decorate,decoration={random steps,segment length=1.7pt,amplitude=.35pt}]
          (-3.73,-1.06) rectangle (3.73,1.06);
        \ifdim\statusstamp@opacity pt>0pt
        \begin{scope}
          \clip (-3.95,-1.28) rectangle (3.95,1.28);
          \foreach \i in {1,...,120} {
            \pgfmathsetmacro{\sx}{-3.82 + 7.64*rnd}
            \pgfmathsetmacro{\sy}{-1.15 + 2.30*rnd}
            \pgfmathsetmacro{\slen}{0.04 + 0.30*rnd}
            \pgfmathsetmacro{\sang}{-32 + 64*rnd}
            \pgfmathsetmacro{\slw}{0.40 + 1.35*rnd}
            \draw[\statusstamp@papercolor,opacity=.96,line width=\slw pt,line cap=round]
              (\sx,\sy) -- ++(\sang:\slen);
          }
          \foreach \i in {1,...,70} {
            \pgfmathsetmacro{\cx}{-3.82 + 7.64*rnd}
            \pgfmathsetmacro{\cy}{-1.15 + 2.30*rnd}
            \pgfmathsetmacro{\rx}{0.012 + 0.055*rnd}
            \pgfmathsetmacro{\ry}{0.006 + 0.025*rnd}
            \pgfmathsetmacro{\rang}{180*rnd}
            \fill[\statusstamp@papercolor,opacity=.97,rotate around={\rang:(\cx,\cy)}]
              (\cx,\cy) ellipse[x radius=\rx,y radius=\ry];
          }
        \end{scope}
        \fi
      \else
        \draw[\statusstamp@color,opacity=\statusstamp@opacity,line width=2.5pt]
          (-3.82,-1.15) rectangle (3.82,1.15);
        \draw[\statusstamp@color,opacity=\statusstamp@inneropacity,line width=.9pt]
          (-3.73,-1.06) rectangle (3.73,1.06);
      \fi
    \end{scope}
  \end{tikzpicture}%
}

\newcommand{\statusstamp@render}{%
  \begingroup
    % PGF's generator state is global even inside a TeX group. Restore it so
    % the stamp cannot change random diagrams elsewhere in the document.
    \let\statusstamp@savedseed\pgfmath@rnd@z
    \pgfmathsetseed{\statusstamp@seed}%
    \scalebox{\statusstamp@scale}{\statusstamp@drawing}%
    \global\let\pgfmath@rnd@z\statusstamp@savedseed
  \endgroup
}
\newcommand{\statusstamp}[1][]{%
  \begingroup\pgfkeys{/statusstamp/.cd,#1}\statusstamp@render\endgroup
}

% Prepare PDF resources before shipout (especially important for XeTeX).
% Cache the drawing once per setup change rather than drawing 190 wear marks
% again on every page. The box and settings obey ordinary TeX grouping.
\newcommand{\statusstamp@build}{\sbox{\statusstamp@box}{\statusstamp@render}}
\AtBeginDocument{\statusstamp@readytrue\statusstamp@build}
\newcommand{\statusstamp@place}{%
  \statusstamp@x=.5\paperwidth
  \statusstamp@y=-.5\paperheight
  \statusstamp@halfheight=\dimexpr(\ht\statusstamp@box+\dp\statusstamp@box)/2\relax
  \csname statusstamp@position@\statusstamp@position\endcsname
  \advance\statusstamp@x by \statusstamp@xshift\relax
  \advance\statusstamp@y by \statusstamp@yshift\relax
  \put(\statusstamp@x,\statusstamp@y){\makebox(0,0){\usebox{\statusstamp@box}}}%
}
\expandafter\def\csname statusstamp@position@center\endcsname{}
\expandafter\def\csname statusstamp@position@top-left\endcsname{%
  \statusstamp@x=\dimexpr\statusstamp@margin+\wd\statusstamp@box/2\relax
  \statusstamp@y=\dimexpr-\statusstamp@margin-\statusstamp@halfheight\relax}
\expandafter\def\csname statusstamp@position@top-right\endcsname{%
  \statusstamp@x=\dimexpr\paperwidth-\statusstamp@margin-\wd\statusstamp@box/2\relax
  \statusstamp@y=\dimexpr-\statusstamp@margin-\statusstamp@halfheight\relax}
\expandafter\def\csname statusstamp@position@bottom-left\endcsname{%
  \statusstamp@x=\dimexpr\statusstamp@margin+\wd\statusstamp@box/2\relax
  \statusstamp@y=\dimexpr-\paperheight+\statusstamp@margin+\statusstamp@halfheight\relax}
\expandafter\def\csname statusstamp@position@bottom-right\endcsname{%
  \statusstamp@x=\dimexpr\paperwidth-\statusstamp@margin-\wd\statusstamp@box/2\relax
  \statusstamp@y=\dimexpr-\paperheight+\statusstamp@margin+\statusstamp@halfheight\relax}

\newcommand{\statusstamp@shipout}[1]{%
  \ifstatusstamp@enabled
    \begingroup
      \def\statusstamp@thislayer{#1}%
      \ifx\statusstamp@layer\statusstamp@thislayer
        \statusstamp@selectedfalse
        \statusstamp@select
        \ifstatusstamp@selected\statusstamp@place\fi
      \fi
    \endgroup
  \fi
}
\AddToHook{shipout/background}[statusstamp]{\statusstamp@shipout{background}}
\AddToHook{shipout/foreground}[statusstamp]{\statusstamp@shipout{foreground}}
\endinput
