\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{cccbform}[2024-11-08 In the Beginning, There Was Chaos]

\LoadClass{scrartcl}
\RequirePackage{geometry, calc, xparse, xcolor, hyperref, tikz,
		fontspec, changepage, letltxmacro, textpos}

% address
\newcommand{\address}{%
	Chaos Computer Club Berlin / CCC~(B)~e.~V.\\
	Marienstr.~11\\
	10117~Berlin
}

% page
\geometry{a4paper, margin=1.5cm, inner=2.5cm}
\pagestyle{empty}

\setmainfont[
	Renderer=HarfBuzz,
	ItalicFont=Recursive,
	BoldFont=Recursive,
	BoldItalicFont=Recursive,
	Scale=0.9,
	UprightFeatures={
		RawFeature={+ss01,+ss02,+ss08,+case},
		RawFeature={+axis={MONO=0.0,CASL=0.2,slnt=0,CRSV=0,wght=400}}
	},
	BoldFeatures={RawFeature={+axis={MONO=0.0,CASL=0.2,slnt=0,CRSV=0,wght=700}}},
	BoldItalicFeatures={RawFeature={+axis={MONO=0.0,CASL=0.2,slnt=-15,CRSV=1,wght=700}}},
	ItalicFeatures={RawFeature={+axis={MONO=0.0,CASL=0.2,slnt=-15,CRSV=1,wght=400}}}
	]{Recursive}

\setmonofont[
	Renderer=HarfBuzz,
	ItalicFont=Recursive,
	BoldFont=Recursive,
	BoldItalicFont=Recursive,
	Scale=0.9,
	UprightFeatures={
		RawFeature={+ss01,+ss02,+ss08,+case},
		RawFeature={+axis={MONO=1.0,CASL=0.2,slnt=0,CRSV=0,wght=400}}
	},
	BoldFeatures={RawFeature={+axis={MONO=1.0,CASL=0.2,slnt=0,CRSV=0,wght=700}}},
	BoldItalicFeatures={RawFeature={+axis={MONO=1.0,CASL=0.2,slnt=-15,CRSV=1,wght=700}}},
	ItalicFeatures={RawFeature={+axis={MONO=1.0,CASL=0.2,slnt=-15,CRSV=1,wght=400}}}
	]{Recursive}

\renewfontfamily\titlefont[
	Renderer=HarfBuzz,
	ItalicFont=Recursive,
	BoldFont=Recursive,
	BoldItalicFont=Recursive,
	Scale=0.9,
	UprightFeatures={
		RawFeature={+ss01,+ss02,+ss08,+case},
		RawFeature={+axis={MONO=0.0,CASL=0.4,slnt=0,CRSV=1,wght=500}}
	},
	BoldFeatures={RawFeature={+axis={MONO=0.0,CASL=0.4,slnt=0,CRSV=1,wght=800}}},
	BoldItalicFeatures={RawFeature={+axis={MONO=0.0,CASL=0.4,slnt=-15,CRSV=1,wght=800}}},
	ItalicFeatures={RawFeature={+axis={MONO=0.0,CASL=0.4,slnt=-15,CRSV=1,wght=500}}}
	]{Recursive}

% fonts
% cmr: 0 / 2.502 / 1.251 / 0.834 / 2.586 / 6.0 / 0.834 || -3
%\setmainfont{Barlow} % 0 / 1.2 / 0.6 / 0.4 / 3.036 / 6.0 / 0.4 || -2
%\setmainfont{Monaspace Neon} % 0 / 3.72 / 1.86 / 1.24 / 3.081 / 6.0 / 1.24 || -7
%\setmainfont{Baltic Sund} % 0 / 1.476 / 0.738 / 0.492 / 3.0 / 6.0 / 0.492 || -3
%\setmainfont{Cabin Sketch} % 0 / 1.35 / 0.675 / 0.45 / 3.03 / 6.0 / 0.45 || -2
%\setmainfont{Consolas} % 0 / 3.2988 / 0 / 0 / 2.941 / 6.0 / 0 || -6
%\setmainfont{Eagle Lake} % 0 / 1.787 / 0.89355 / 0.5957 / 3.2 / 6.0 / 0.5957 || -3
%\setmainfont{Fira Sans} % 0 / 1.59 / 0.795 / 0.53 / 3.162 / 6.0 / 0.53 || -3
%\setmainfont{Gentium Book Plus} % 0 / 1.32 / 0.66 / 0.44 / 2.72 / 6.0 / 0.44 || -2
%\setmainfont{Ubuntu} % 0 / 1.38 / 0.69 / 0.46 / 3.12 / 6.0 / 0.46 || -2
%\setmainfont{Ubuntu Condensed} % 0 / 1.17 / 0.58 / 0.39 / 3.12 / 6.0 / 0.39 || -2
%\setmainfont{Ubuntu Mono} % 0 / 3.0 / 0 / 0 / 3.12 / 6.0 / 0 || -5

% colors
\definecolor{fieldcolor}{gray}{0.85}
\definecolor{bordercolor}{gray}{0.1}

% lengths
\def\deflength#1#2{\newlength{#1}\setlength{#1}{#2}}
\setlength{\parindent}{0pt}
\setlength{\fboxsep}{0pt}
\deflength{\formfieldheight}{14pt}
\deflength{\formshrink}{4pt}
\deflength{\formskip}{0.5em}
\deflength{\colsep}{1.0em}
\deflength{\indentstep}{1cm}
\deflength{\borderwidth}{0.5pt}
\def\checkboxtextshrink{\dimexpr
	\formfieldheight  % width of checkbox
	+1em              % the \quad separator's width
	+\formshrink      % wild guess, -2\borderwidth leaves 1pt overfull
\relax}
\deflength{\htweak}{0.5pt} % manual adjustment of horizontal alignment of form elements
\deflength{\hadj}{\dimexpr -0.5\formshrink - 0.5\fontdimen2\font + \htweak \relax}

% counters
\newcounter{fieldnum}
\def\@autofieldname{field\thefieldnum}

% abbreviations
\def\@formdefaults{%
	backgroundcolor=fieldcolor,bordercolor=fieldcolor,%
	borderwidth=0pt,charsize=\formfieldheight%
}

% address placement helper
\newcommand{\@dinaddress}{%
	\begin{tikzpicture}[remember picture, overlay]
		\node[anchor=north west] at (current page.north west) [xshift=2.35cm, yshift=-5cm] {%
		\begin{minipage}{10cm}
			\emph{an den} \par
			\vspace{\formskip}
			\noindent\address
		\end{minipage}
		};
	\end{tikzpicture}
}

% % % form@, fake@, and full@ variants of the form elements:
%
% (raw@: renamed / prefixed hyperref command)
% form@: PDF form element (some viewers don't print it)
% fake@: A colored box, non-interactive (but will be printed!)
% full@: a stack of fake@ and form@ on top of each other
%
% The general parameter convention here is: height, width multiplier
% - height is optional and defaults to \formfieldheight, giving the right size
%   for a single-line text field
% - width is "mandatory" but always used followed by \linewidth, so passing an
%   empty argument works and is effectively equivalent to passing 1

% rename commands to make nice names available
\LetLtxMacro\raw@TextField\TextField
\LetLtxMacro\raw@CheckBox\CheckBox
\let\CheckBox\relax

% wrapped form fields with defaults filled in
\NewDocumentCommand{\form@TextField}{D<>{\formfieldheight} O{1.0}}{%
	\stepcounter{fieldnum}
	\expandafter\raw@TextField\expandafter[\@formdefaults,
		name=\@autofieldname,
		width=\dimexpr #2\linewidth - \formshrink \relax,
		height=\dimexpr #1 - \formshrink \relax
	]{}%
}

\NewDocumentCommand{\form@MultilineTextField}{D<>{\formfieldheight} O{1.0}}{%
	\stepcounter{fieldnum}
	\expandafter\raw@TextField\expandafter[\@formdefaults,
		name=\@autofieldname,
		multiline=true,
		width=\dimexpr #2\linewidth - \formshrink \relax,
		height=\dimexpr #1 - \formshrink \relax
	]{}%
}

\NewDocumentCommand{\form@CheckBox}{}{%
	\stepcounter{fieldnum}
	\expandafter\raw@CheckBox\expandafter[\@formdefaults,
		name=\@autofieldname,
		width=\dimexpr \formfieldheight - \formshrink \relax,
		height=\dimexpr \formfieldheight - \formshrink \relax
	]{}%
}

% fake form fields to put *under* the PDF form fields
\NewDocumentCommand{\fake@TextField}{D<>{\formfieldheight} O{1.0}}{%
	\begin{tikzpicture}[baseline=0.6ex]
		\fill[fieldcolor]
			(0,0) rectangle (#2\linewidth - 2\borderwidth,#1);
		\draw[dash pattern=on 0.5\borderwidth off 5\borderwidth,bordercolor,
				line width=\borderwidth, line cap=round]
			(0,0) -- (#2\linewidth - 2\borderwidth,0);
	\end{tikzpicture}%
}

\LetLtxMacro\fake@MultilineTextField\fake@TextField

\NewDocumentCommand{\fake@CheckBox}{}{%
	\begin{tikzpicture}[baseline=0.6ex]
		\fill[fieldcolor]
			(0,0) rectangle (\formfieldheight,\formfieldheight);
		\draw[bordercolor,line width=\borderwidth]
			(0,0) rectangle (\formfieldheight,\formfieldheight);
	\end{tikzpicture}%
}

% "full" stacked version of fake + actual form field
\NewDocumentCommand{\full@TextField}{D<>{\formfieldheight} O{1.0}}{%
	\begin{tikzpicture}[baseline]
		\node (background) [anchor=base west, inner sep=0pt, outer sep=0pt] at (0,0) {
			\fake@TextField<#1>[#2]
		};
		\node[anchor=center, inner sep=0pt, outer sep=0pt] at (background.center) {
			\kern\hadj\form@TextField<#1>[#2]
		};
	\end{tikzpicture}
}

\NewDocumentCommand{\full@MultilineTextField}{D<>{\formfieldheight} O{1.0}}{%
	\begin{tikzpicture}[baseline]
		\node (background) [anchor=base west, inner sep=0pt, outer sep=0pt] at (0,0) {
			\fake@MultilineTextField<#1>[#2]
		};
		\node[anchor=center, inner sep=0pt, outer sep=0pt] at (background.center) {
			\kern\hadj\form@MultilineTextField<#1>[#2]
		};
	\end{tikzpicture}
}

\NewDocumentCommand{\full@CheckBox}{}{%
	\begin{tikzpicture}[baseline]
		\node (background) [anchor=base west, inner sep=0pt, outer sep=0pt] at (0,0) {
			\fake@CheckBox
		};
		\node [anchor=center, inner sep=0pt] at (background.center) {
			\kern\hadj\form@CheckBox
		};
	\end{tikzpicture}
}

% % % exposed form elements

% Text{text…} - just text, with proper spacing
\NewDocumentCommand{\Text}{m}{%
	\par#1\par\vspace{\formskip}
}

% TextField{label} - a single-line input
\RenewDocumentCommand{\TextField}{s m}{%
	\par%
	{\ttfamily\footnotesize #2\strut}\\%
	\IfBooleanTF{#1}{\full@TextField}{\full@TextField[0.7]}%
	\par\vspace{\formskip}%
}

% ShortTextField[width]{label} - a single-line input that doesn't have full width
%                                (50% by default)
\NewDocumentCommand{\ShortTextField}{O{0.35} m}{%
	\par%
	{\ttfamily\footnotesize #2\strut}\\%
	\full@TextField[#1]%
	\par\vspace{\formskip}%
}

% MultilineTextField[height]{label} - a multi-line input
\NewDocumentCommand{\MultilineTextField}{s O{} m}{%
	\par%
	{\ttfamily\footnotesize #3\strut}\\%
	\IfBooleanTF{#1}{\full@MultilineTextField<#2>}{\full@MultilineTextField<#2>[0.7]}%
	\par\vspace{\formskip}%
}

% Signature[label] - a field not fillable on the computer, big enough for a signature
\NewDocumentCommand{\Signature}{O{Datum, Unterschrift}}{%
	\par%
	{\ttfamily\footnotesize #1\strut}\\%
	\fake@MultilineTextField<1.0cm>[0.35]%
	\par\vspace{\formskip}%
}

% Notes[label] - a slightly taller fake field that fills the whole width
\NewDocumentCommand{\Notes}{O{Vermerke}}{%
	\par%
	{\ttfamily\footnotesize #1\strut}\\%
	\fake@MultilineTextField<1.5cm>%
	\par\vspace{\formskip}%
}

% Checkbox{label} - a checkbox; label can be long and will linebreak reasonably pretty
\NewDocumentCommand{\Checkbox}{m}{%
	\par%
	\full@CheckBox\quad%
	\begin{minipage}[t]{\dimexpr \linewidth - \checkboxtextshrink \relax}%
		#1%
	\end{minipage}%
	\par\vspace{\formskip}%
}

% InlineCheckbox - just the box
\NewDocumentCommand{\InlineCheckbox}{}{\full@CheckBox}

% CheckboxOther[width]{label} - a checkbox for a write-in option
\NewDocumentCommand{\CheckboxOther}{O{0.35} m}{%
	\par%
	\full@CheckBox\quad#2\quad\full@TextField[#1]%
	\par\vspace{\formskip}%
}

% high-level structure

% Section{title} - a form section
\NewDocumentCommand{\Section}{m}{%
	\vspace{1.5cm}%
	{\Large\bfseries #1}%
	\par\vspace{2\formskip}%
}

% Subsection{title} - slightly smaller than section
\NewDocumentCommand{\Subsection}{m}{%
	\vspace{1.0cm}%
	{\large\bfseries #1}%
	\par\vspace{\formskip}%
}

% Rule - a horizontal rule, with correct spacing
\NewDocumentCommand{\Rule}{}{%
	\vspace{\formskip}%
	\rule{\linewidth}{\borderwidth}%
	\vspace{2\formskip}%
}

% RuleSection - rule followed by a small note *immediately* below, before the spacing
%               (e.g. to separate public / internal sections of a form)
\NewDocumentCommand{\RuleSection}{m}{%
	\vspace{\formskip}%
	\leavevmode\rule{\linewidth}{\borderwidth}\\[-1ex]%
	{\details{#1}}%
	\par\vspace{2\formskip}
}

% \begin{Indented}[factor] ... \end{Indented} - indent a section
\NewDocumentEnvironment{Indented}{O{}}{%
	\begin{adjustwidth}{#1\indentstep}{0pt}%
}{%
	\end{adjustwidth}%
}

% TwoColumns{left}{right} - put two sections side-by-side
\NewDocumentCommand{\TwoColumns}{m m}{%
	\begin{minipage}[t]{0.5\linewidth - 0.5\colsep}%
		#1%
	\end{minipage}%
	\hfill
	\begin{minipage}[t]{0.5\linewidth - 0.5\colsep}%
		#2%
	\end{minipage}%
	\par\vspace{\formskip}%
}

\NewDocumentCommand{\ThreeColumns}{m m m}{%
	\begin{minipage}[t]{0.333\linewidth - 0.66\colsep}%
		#1%
	\end{minipage}%
	\hfill
	\begin{minipage}[t]{0.333\linewidth - 0.66\colsep}%
		#2%
	\end{minipage}%
	\hfill
	\begin{minipage}[t]{0.333\linewidth - 0.66\colsep}%
		#3%
	\end{minipage}%
	\par\vspace{\formskip}%
}

\NewDocumentCommand{\FiveColumns}{m m m m m}{%
	\begin{minipage}[t]{0.2\linewidth - 0.8\colsep}%
		#1%
	\end{minipage}%
	\hfill
	\begin{minipage}[t]{0.2\linewidth - 0.8\colsep}%
		#2%
	\end{minipage}%
	\hfill
	\begin{minipage}[t]{0.2\linewidth - 0.8\colsep}%
		#3%
	\end{minipage}%
	\hfill
	\begin{minipage}[t]{0.2\linewidth - 0.8\colsep}%
		#4%
	\end{minipage}%
	\hfill
	\begin{minipage}[t]{0.2\linewidth - 0.8\colsep}%
		#5%
	\end{minipage}%
	\par\vspace{\formskip}%
}

% details{text} - (use instead of font sizes, small text)
\NewDocumentCommand{\details}{m}{%
	{\scriptsize #1}%
}

% % % common title patterns

% put the logo in the top right corner
\NewDocumentCommand{\@logo}{}{
	\begin{tikzpicture}[remember picture, overlay]
		\node[anchor=north east] at (current page.north east) [xshift=-1.5cm, yshift=-1.5cm] {%
			\includegraphics[width=3cm]{logo.pdf}%
		};
	\end{tikzpicture}%
}

% LogoTitle{title} - logo on the right, title on the left
\NewDocumentCommand{\LogoTitle}{m}{
	\@logo
	\\[1cm]{\titlefont\huge\bfseries #1}\\[1.5cm]
}

% AddressTitle{title} - title at the top, address, then the form below
% AddressTitle*{title} - same, plus logo
\NewDocumentCommand{\AddressTitle}{s m}{
	\IfBooleanT{#1}{\@logo}
	\@dinaddress
	\\[1cm]\smash{{\titlefont\huge\bfseries #2}}\\[4cm]
}

% need to emit \Form ; hyperref generates incomplete CheckBox appearance data,
% which causes problems with some viewers - so it's currently better not to
% generate any at all
\AtBeginDocument{
\Form[NeedAppearances=false]
}

