\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{argumentation}[2024/09/25 Argumentation]
% Author:   Lars Bengel
% E-Mail:   lars.bengel@fernuni-hagen.de
% Version:  1.3
% Date:     2024/09/25
% License:  LaTeX Project Public License 1.3c

%%%%%%%%%%% Package Requirements %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage{amsbsy,amsmath}                 % Proper bold letters in math mode
\RequirePackage{pgfopts}                        % Managing package options
\RequirePackage{xspace}                         % Dynamic spaces after math commands
\RequirePackage{xcolor}                         % Defining colors
\RequirePackage{tikz}                           % Drawing the argumentation frameworks
\usetikzlibrary{positioning}                    % Relative node positioning
\usetikzlibrary{arrows.meta}                    % Directed edges / attack arrows
\usetikzlibrary{arrows}                         % Directed edges / attack arrows
\usetikzlibrary{decorations.markings}           % Creating the support edge markings
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%% Package Style Definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcounter{argument}                           % Counter for arguments in the af-environment
\newcommand{\argstyle}[1]{#1}                   % Defines the font style in which argument names are displayed
\definecolor{aigyellow}{RGB}{210,149,81}        % Highlight color
\definecolor{aigblue}{RGB}{0,76,151}            % Node color

%%% Argument Style Definitions
\tikzset{ % global base styles
    argument size/.style={},                    % Size of argument nodes
    argument/.style={},                         % Base style for argument nodes
    argument standard/.style={circle,draw=black,inner sep=0,outer sep=0},
    argument large/.style={circle,draw=black,inner sep=0,outer sep=0, font=\large},
    argument thick/.style={circle,draw=black,inner sep=0,outer sep=0, line width=0.1em},
    argument gray/.style={argument thick,fill=gray!30,draw=gray!65,text=black!80},
    argument colored/.style={argument thick,fill=aigblue!40,draw=aigblue!80,text=black!80},
}

%%% Attack/Support Edge Definitions
\tikzset{ % global base styles
    attack width/.style={},                     % Width of attack arrows
    attack/.style={},                           % Base style for attack arrow
    attack standard/.style={-{stealth'}},                                   % Standard attack arrow
    attack large/.style={-{Stealth[scale=1.25]}},                           % Larger arrow tip
    attack modern/.style={-{To[sharp,length=0.65ex,line width=0.05em]}},    % Mordern rightarrow style tip
    support/.style={},
    support standard/.style = {attack, postaction = {decorate,decoration={markings,mark=at position 0.36 with {\draw[-] (0,-0.1) -- (0.1,0.1);}}}},                % Standard support arrow
    support dashed/.style={attack,densely dashed},                          % Dashed Support arrow
    support double/.style={-{Classical TikZ Rightarrow},double},            % double-line support arrow
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%% Package Options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Options for style of the argument node itself
\pgfkeys{/tikz/.cd,
    argumentstyle/.is choice,
    argumentstyle/standard/.code={\tikzset{argument/.style={argument standard,argument size}}},
    argumentstyle/large/.code={\tikzset{argument/.style={argument large,argument size}}},
    argumentstyle/thick/.code={\tikzset{argument/.style={argument thick,argument size}}},
    argumentstyle/gray/.code={\tikzset{argument/.style={argument gray,argument size}}},
    argumentstyle/colored/.code={\tikzset{argument/.style={argument colored,argument size}}},
}
\pgfkeys{/argumentation/.cd,
    .unknown/.code={},
    argumentstyle/.is choice,
    argumentstyle/standard/.code={\tikzset{argument/.style={argument standard,argument size}}},
    argumentstyle/large/.code={\tikzset{argument/.style={argument large,argument size}}},
    argumentstyle/thick/.code={\tikzset{argument/.style={argument thick,argument size}}},
    argumentstyle/gray/.code={\tikzset{argument/.style={argument gray,argument size}}},
    argumentstyle/colored/.code={\tikzset{argument/.style={argument colored,argument size}}},
    argumentstyle=standard,
}

%%% Options for the style of the attack edges
\pgfkeys{/tikz/.cd,
    attackstyle/.is choice,
    attackstyle/standard/.code={\tikzset{attack/.style={attack width,attack standard}}},
    attackstyle/large/.code={\tikzset{attack/.style={attack width,attack large}}},
    attackstyle/modern/.code={\tikzset{attack/.style={attack width,attack modern}}},
    attackstyle=standard,
}
\pgfkeys{/argumentation/.cd,
    attackstyle/.is choice,
    attackstyle/standard/.code={\tikzset{attack/.style={attack width,attack standard}}},
    attackstyle/large/.code={\tikzset{attack/.style={attack width,attack large}}},
    attackstyle/modern/.code={\tikzset{attack/.style={attack width,attack modern}}},
    attackstyle=standard,
}

%%% Options for the style of the support edges
\pgfkeys{/tikz/.cd,
    supportstyle/.is choice,
    supportstyle/standard/.code={\tikzset{support/.style={support standard}}},
    supportstyle/dashed/.code={\tikzset{support/.style={support dashed}}},
    supportstyle/double/.code={\tikzset{support/.style={support double}}},
    supportstyle=standard,
}
\pgfkeys{/argumentation/.cd,
    supportstyle/.is choice,
    supportstyle/standard/.code={\tikzset{support/.style={support standard}}},
    supportstyle/dashed/.code={\tikzset{support/.style={support dashed}}},
    supportstyle/double/.code={\tikzset{support/.style={support double}}},
    supportstyle=standard,
}

%%% Options for the automatic text formatting for the argument names
\pgfkeys{/tikz/.cd,
    namestyle/.is choice,
    namestyle/none/.code={\renewcommand{\argstyle}[1]{##1}},
    namestyle/math/.code={\renewcommand{\argstyle}[1]{\ensuremath{##1}}},
    namestyle/bold/.code={\renewcommand{\argstyle}[1]{\ensuremath{\boldsymbol{##1}}}},
    namestyle/monospace/.code={\renewcommand{\argstyle}[1]{{\ttfamily##1}}},
    namestyle/monoemph/.code={\renewcommand{\argstyle}[1]{{\ttfamily\itshape##1}}},
    namestyle=none,
}
\pgfkeys{/argumentation/.cd,
    namestyle/.is choice,
    namestyle/none/.code={\renewcommand{\argstyle}[1]{##1}},
    namestyle/math/.code={\renewcommand{\argstyle}[1]{\ensuremath{##1}}},
    namestyle/bold/.code={\renewcommand{\argstyle}[1]{\ensuremath{\boldsymbol{##1}}}},
    namestyle/monospace/.code={\renewcommand{\argstyle}[1]{{\ttfamily##1}}},
    namestyle/monoemph/.code={\renewcommand{\argstyle}[1]{{\ttfamily\itshape##1}}},
    namestyle=none,
}

%%% Options for automatic indexing (and naming) of argument nodes
\NewDocumentCommand { \argument } {} {\relax}
\pgfkeys{/argumentation/.cd,
    indexing/.is choice,
    indexing/none/.code={ % No auto-indexing, node identifier required
        \RenewDocumentCommand { \argument } {O{} r() m dat d()} {
            \IfNoValueTF {##5}{%
                \node[argument size,argument,##1](##2) {\argstyle{##3}};
            }{%
                \node[argument size,argument,##1](##2) at (##5) {\argstyle{##3}};
            }
        }
    },
    indexing/numeric/.code={ % Numeric auto-indexing: a1,a2,...
        \RenewDocumentCommand { \argument } {O{} d() m dat d()} {
            \stepcounter{argument}
            \IfNoValueTF {##2}{%
                \IfNoValueTF {##5}{%
                    \node[argument size,argument,##1](a\arabic{argument}) {\argstyle{##3}};
                }{%
                    \node[argument size,argument,##1](a\arabic{argument}) at (##5) {\argstyle{##3}};
                }
            }{%
                \IfNoValueTF {##5}{%
                    \node[argument size,argument,##1](##2) {\argstyle{##3}};
                }{%
                    \node[argument size,argument,##1](##2) at (##5) {\argstyle{##3}};
                }
            }
        }
    },
    indexing/alphabetic/.code={ % Alphabetic auto-indexing: a,b,...
        \RenewDocumentCommand { \argument } {O{} d() m dat d()} {
            \stepcounter{argument}
            \IfNoValueTF {##2}{%
                \IfNoValueTF {##5}{%
                    \node[argument size,argument,##1](\alph{argument}) {\argstyle{##3}};
                }{%
                    \node[argument size,argument,##1](\alph{argument}) at (##5) {\argstyle{##3}};
                }
            }{%
                \IfNoValueTF {##5}{%
                    \node[argument size,argument,##1](##2) {\argstyle{##3}};
                }{%
                    \node[argument size,argument,##1](##2) at (##5) {\argstyle{##3}};
                }
            }
        }
    },
    indexing/.default=numeric,
    indexing=numeric,
}

\newif\ifmacros
\pgfkeys{/argumentation/.cd,
    macros/.is choice,
    macros/true/.code={
        \macrostrue
    },
    macros/false/.code={
        \macrosfalse
    },
    macros/.default=true,
    macros=false,
}

\ProcessPgfPackageOptions{/argumentation}

%%%%%%%%%%%%%%%  AF Environment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Additional AF Style Parameters
\tikzset{ % global predefined tikz-styles
    selfattack/.style={loop,min distance=0.4em,in=0,out=60,looseness=4.5},  % Self-attack
    inactive/.style={fill=none,draw=gray!50,text=gray!60},                  % Inactive argument or edge (reduct)
    incomplete/.style={densely dashed},                                     % incomplete argument or edge
    accepted/.style={fill=green!40},                                        % Accepted argument (in)
    rejected/.style={fill=red!40},                                          % Rejected argument (out)
    undecided/.style={fill=cyan!40},                                        % Undecided Argument (undec)
    highlight/.style={fill=aigyellow!60},                                   % Highlighted argument
    caption/.style={draw=none},                                             % Caption or text
    invisible/.style={draw=none,text=black!0,fill=none},                    % Invisible argument or edge
    annotation/.style={font=\small},                                        % Argument annotation
    argin/.style={accepted},
    argout/.style={rejected},
    argundec/.style={undecided},
}

%%% Style-Options for af environment
\pgfkeys{/tikz/.cd,
    standard/.style={node distance=6.6ex,argument size/.style={minimum size=4.5ex},attack width/.style={line width=0.05em},},
    small/.style={node distance=3.5ex,argument size/.style={minimum size=3.4ex},attack width/.style={line width=0.045em},caption/.append style={font=\small}},
    tiny/.style={node distance=2.3ex,argument size/.style={minimum size=2.6ex,font=\small},attack width/.style={line width=0.03em},caption/.append style={font=\small}},
}


\ifmacros
%%% Definitions for referencing
\providecommand{\AF}{\ensuremath{F}\xspace}                     % AF abbreviation
\providecommand{\arguments}{\ensuremath{A}\xspace}              % Set of arguments
\providecommand{\attacks}{\ensuremath{R}\xspace}                % Set of attacks
\providecommand{\AFcomplete}{\ensuremath{\AF = (\arguments, \attacks)}\xspace}  % Full AF
\newcommand{\afref}[1]{\ensuremath{\AF_{\ref{#1}}}\xspace}      % Reference an AF
\newcommand{\fullafref}[1]{\ensuremath{\afref{#1} = (\arguments_{\ref{#1}}, \attacks_{\ref{#1}})}\xspace}                                   % Full AF with reference
\else\relax
\fi

%%% Initializing the af environment
\newcounter{af}
\newenvironment{af}[1][]{
    \refstepcounter{af}
    \setcounter{argument}{0}
    \pgfkeys{/argumentation/.cd, #1}
    \tikzpicture[standard,#1]
}{%
    \endtikzpicture
}

%%%%%%%%%%%%%%%% Additional Commands %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Creates a node displaying the name of the AF
\NewDocumentCommand { \afname } { O{} D(){caption} m dat d()} {
    \IfNoValueTF {#5}{%
        \node[caption,#1](#2){#3};
    }{%
        \node[caption,#1](#2) at (#5) {#3};
    }
    
}

\newcommand{\annotation}[3][]{\node[annotation,above of=#2,#1](an_#2){#3};}

% Basic attack edge
\newcommand{\attack}[3][]{\path(#2) edge [attack,#1] (#3);}

% Self-attack edge
\newcommand{\selfattack}[2][]{\path(#2) edge [attack,selfattack,#1] (#2);}

% Symmetric attack edges between two arguments
\newcommand{\dualattack}[3][]{\path(#2) edge [attack, bend right,#1] (#3);\path(#3) edge [attack, bend right,#1] (#2);}

% Attack edge with value
\newcommand{\annotatedattack}[4][]{\path(#2) edge [attack,#1] node[annotation](p_#2_#3){#4} (#3);}

% Support edge
\newcommand{\support}[3][]{\path(#2) edge [support=0.35,#1] (#3);}

%%% Commands for setting custom tikz-style parameters
\newcommand{\setargumentstyle}[1]{\tikzset{argument/.style={argument size,#1}}}
\newcommand{\setattackstyle}[1]{\tikzset{attack/.style={attack width,#1}}}
\newcommand{\setsupportstyle}[1]{\tikzset{support/.style={#1}}}
\newcommand{\setannotationstyle}[1]{\tikzset{annotation/.style={#1}}}

%\newcommand{\setloopstyle}[1]{\tikzset{selfattack/.style={#1}}}
%\newcommand{\adjustargumentstyle}[1]{\tikzset{argument/.append style={#1}}}
%\newcommand{\adjustattackstyle}[1]{\tikzset{attack/.append style={#1}}}