% Copyright 2023 by Qrrbrbirlbel
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%

\usepgflibrary{arrows.meta}
\unless\ifcsname tikzextset\endcsname
  \input tikzext-util.tex
\fi

\pgfqkeys{/tikz-ext/@arrows decl}{
  clone/.code={%
    \pgfutil@namelet{pgf@decl@arrow@code}{pgf@ar@code@#1}%
    \pgfutil@namelet{pgf@decl@arrow@defaults}{pgf@ar@defaults@#1}%
    \pgfutil@namelet{pgf@decl@arrow@setup}{pgf@ar@setup@#1}%
    \pgfutil@namelet{pgf@decl@arrow@bending@mode}{pgf@ar@bending@mode@#1}%
    \pgfutil@namelet{pgf@decl@arrow@par}{pgf@ar@par@#1}%
    \pgfutil@namelet{pgf@decl@arrow@cache}{pgf@ar@do@cache@#1}%
  },
  append setup code/.code=
    \begingroup
      \pgfutil@toks@\expandafter{\pgf@decl@arrow@setup#1}%
    \expandafter\endgroup
    \expandafter\def\expandafter\pgf@decl@arrow@setup\expandafter
      {\the\pgfutil@toks@ },
  % append parameters/.code=
  %   \begingroup
  %     \show\pgf@decl@arrow@par
  %     \pgfutil@toks@\expandafter{\pgf@decl@arrow@par#1}%
  %   \expandafter\endgroup
  %   \expandafter\def\expandafter\pgf@decl@arrow@par\expandafter
  %     {\the\pgfutil@toks@ }
}
% \pgfkeyssetvalue{/pgf/arrow keys/ext/weight}{true}

%%% Barbed
%   Arc Barb, Parenthesis
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Arc Barb,
  name                         = ext_Centered Arc Barb,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed
      \pgfarrowssetbackend{0pt}
    \else
      \pgfarrowssettipend{0pt}
    \fi
}
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Arc Barb,
  name                         = ext_Untipped Arc Barb,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed
      \pgfarrowssetbackend{\pgfarrowlength}
    \else
      \pgfarrowssettipend{\pgfarrowlength}
    \fi
}

%   Hooks
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Hooks,
  name                         = ext_Centered Hooks,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed
      \pgfarrowssetbackend{0pt}
    \else
      \pgfarrowssettipend{0pt}
    \fi
}

%   Straight Barb
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Straight Barb,
  name                         = ext_Centered Straight Barb,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed
      \pgfarrowssetbackend{.5\pgfarrowlength}
    \else
      \pgfarrowssettipend{.5\pgfarrowlength}
    \fi
}

%   Tee Barb, Bar, Bracket
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Tee Barb,
  name                         = ext_Centered Tee Barb,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed
      \pgfarrowssetbackend{0pt}
    \else
      \pgfarrowssettipend{0pt}
    \fi
}
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Tee Barb,
  name                         = ext_Untipped Tee Barb,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed\expandafter\pgfarrowssetbackend\else\expandafter\pgfarrowssettipend\fi
    {\pgfutil@tempdima
      \ifpgfutil@tempswa % does it not extend to the right?
        \advance\pgf@x-.5\pgfarrowlinewidth
      \else
        \ifpgfutil@tempswb
        \else
          \pgf@x=.5\pgfarrowlength
        \fi
        \ifpgfarrowroundcap\else
          \advance\pgf@x-.5\pgfarrowlinewidth
        \fi
      \fi
    }
}
%%% Mathematical
%   Classical TikZ Rightarrow
%   Computer Modern Rightarrow, To
%   Implies

%%% Geometric
%   Circle, Ellipse
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Circle,
  name                         = ext_Centered Circle,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed
      \pgfarrowssetbackend{.5\pgfarrowlength}
    \else
      \pgfarrowssettipend{.5\pgfarrowlength}
    \fi
}
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Circle,
  name                         = ext_Untipped Circle,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed
      \pgfarrowssetbackend{\pgfarrowlength \advance\pgf@x -.5\pgfarrowlinewidth}
    \else
      \pgfarrowssettipend{\pgfarrowlength \advance\pgf@x -.5\pgfarrowlinewidth}
    \fi
}

%   Kite, Diamond, Turned Square
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Kite,
  name                         = ext_Centered Kite,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed
      \pgfarrowssetbackend{\pgfarrowinset}
    \else
      \pgfarrowssettipend{\pgfarrowinset}
    \fi
}

%   LaTeX
%   Square, Rectangle
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Square,
  name                         = ext_Centered Square,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed
      \pgfarrowssetbackend{.5\pgfarrowlength}
    \else
      \pgfarrowssettipend{.5\pgfarrowlength}
    \fi
}

%   Stealth, Triangle
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Stealth,
  name                         = ext_Centered Stealth,
  /tikz-ext/@arrows decl/append setup code =
    % \pgfkeysgetvalue{/pgf/arrow keys/weight}\pgf@temp
    % \ifx\pgf@temp\pgf@truetext
      \ifpgfarrowreversed
        \pgfarrowssetbackend{.25\pgfarrowlength \advance\pgf@x .25\pgfarrowinset}
      \else
        \pgfarrowssettipend{.25\pgfarrowlength \advance\pgf@x .25\pgfarrowinset}
      \fi
    % \else
    %   \ifpgfarrowreversed
    %     \pgfarrowssetbackend{\pgf@temp\pgfarrowlength}
    %   \else
    %     \pgfarrowssettipend{\pgf@temp\pgfarrowlength}
    %   \fi
    % \fi
    ,
  % append parameters = {,\pgfkeysvalueof{/pgf/arrow keys/weight}},
  % parameters = {
  %   \the\pgfarrowlinewidth,%
  %   \the\pgfarrowlength,%
  %   \the\pgfarrowwidth,%
  %   \the\pgfarrowinset,%
  %   \pgfkeysvalueof{/pgf/arrow keys/weight},%
  %   \ifpgfarrowharpoon h\fi%
  %   \ifpgfarrowopen o\fi%
  %   \ifpgfarrowroundjoin j\fi%
  % },
}
%%% Caps

%%% Rays
\pgfdeclarearrow{
  /tikz-ext/@arrows decl/clone =              Rays,
  name                         = ext_Centered Rays,
  /tikz-ext/@arrows decl/append setup code =
    \ifpgfarrowreversed
      \pgfarrowssetbackend{0pt}
    \else
      \pgfarrowssettipend{0pt}%\pgfarrowssetvisualtipend{\pgf@xa}
    \fi
}

%%% Variants
\pgfkeys{
  ext_Centered Ellipse       /.tip = {ext_Centered Circle[length=+3.3pt +4.95, width'=+0pt +0.5]},
  ext_Centered Parenthesis   /.tip = {ext_Centered Arc Barb[arc=+120,length=+1.725pt +2.3]},
  ext_Centered Bar           /.tip = {ext_Centered Tee Barb[length=+0pt]},
  ext_Centered Bracket       /.tip = {ext_Centered Tee Barb[inset'=+0pt +1,length=+0.75pt +1]},
  ext_Centered Diamond       /.tip = {ext_Centered Kite[inset'=+0pt .5]},
  ext_Centered Turned Square /.tip = {ext_Centered Kite[length=+3pt 4,width'= +0pt 1,inset'= +0pt 0.5]},
  ext_Centered Rectangle     /.tip = {ext_Centered Square[length=+3pt +4.5,width'=+0pt +.5]},
  ext_Centered Triangle      /.tip = {ext_Centered Stealth[inset=+0pt, angle=+60:+2.7pt +3.6]},
  ext_Untipped Ellipse       /.tip = {ext_Untipped Circle[length=+3.3pt +4.95, width'=+0pt +0.5]},
  ext_Untipped Parenthesis   /.tip = {ext_Untipped Arc Barb[arc=+120,length=+1.725pt +2.3]},
  ext_Untipped Bar           /.tip = {ext_Untipped Tee Barb[length=+0pt]},
  ext_Untipped Bracket       /.tip = {ext_Untipped Tee Barb[inset'=+0pt +1,length=+0.75pt +1]},
}

%%% New Arrows
\pgfdeclarearrow{
  name = ext_Hug Cap,
  parameters = \the\pgfarrowlength,
  defaults = {
   length = +0pt +1
  },
  setup code={
    % h = r - .5 sqrt(4 r^2 - s^2)
    \ifdim2\pgfarrowlength<\pgflinewidth
      \pgfarrowlength=.51\pgflinewidth
    \fi
    \pgfmathsetlengthmacro\pgfarrowh{\pgfarrowlength-.5*sqrt(4*\pgfarrowlength*\pgfarrowlength-\pgflinewidth*\pgflinewidth}
    % a = asin(s / (2 r))
    \pgfmathsetmacro\pgfarrowangle{asin(\the\pgflinewidth/(2*\the\pgfarrowlength))}
    \pgfarrowssavethe\pgfarrowlength % radius
    \pgfarrowssave\pgfarrowh         % h
    \pgfarrowssave\pgfarrowangle     % a
    \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth}
    \pgfarrowsupperhullpoint{\pgfarrowh}{.5\pgflinewidth}
  },
  drawing code={
    \pgfpathmoveto{\pgfqpoint{\pgfarrowh}{-.5\pgflinewidth}}
    \pgfpatharc{180+\pgfarrowangle}{180-\pgfarrowangle}{\pgfarrowlength}
    \pgfpathlineto{\pgfqpoint{-.1pt}{.5\pgflinewidth}}
    \pgfpathlineto{\pgfqpoint{-.1pt}{-.5\pgflinewidth}}
    \pgfpathclose
    \pgfusepathqfill
  }
}

\pgfdeclarearrow{
  name = ext_Loop,
  parameters = {\the\pgfarrowlength,\the\pgfarrowinset,\ifpgfarrowopen o\fi},
  defaults = {length = +3pt +1 +0, inset = +.75pt +1 +0},
  setup code = {%
    \ifdim\pgfarrowlength<\dimexpr2\pgfarrowinset+\pgflinewidth\relax
      \pgfarrowlength\dimexpr2\pgfarrowinset+\pgflinewidth\relax
    \fi
    \ifdim\pgfarrowinset<.5\pgflinewidth
      \pgfarrowinset=.5\pgflinewidth
    \fi
    \pgfarrowssettipend{\pgfarrowlength}%
    \pgfarrowssetlineend{.5\pgflinewidth}%
    \pgfarrowshullpoint{\pgfarrowlength}{\pgfarrowlength}%
    \pgfarrowsupperhullpoint{0pt}{\pgfarrowlength}%
    \pgfarrowshullpoint{\pgflinewidth}{-\pgfarrowlength}%
    \pgfarrowssavethe\pgfarrowlength
    \pgfarrowssavethe\pgfarrowinset
  },
  drawing code={%
    \pgfsetroundcap
    \pgfpathmoveto{\pgfqpoint{.5\pgflinewidth}{0pt}}%
    \pgfpathlineto{\pgfqpoint{\dimexpr\pgfarrowlength-\pgfarrowinset}
                             {0pt}}%
    \pgfpatharc{+-90}{+0}{+\dimexpr\pgfarrowinset-.5\pgflinewidth}%
    \pgfpathlineto{\pgfqpoint{\dimexpr\pgfarrowlength-.5\pgflinewidth}
                             {\dimexpr\pgfarrowlength-\pgfarrowinset}}%
    \pgfpatharc{+0}{+90}{+\dimexpr\pgfarrowinset-.5\pgflinewidth}%
    \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{\dimexpr\pgfarrowlength-.5\pgflinewidth}}%
    \pgfpatharc{+90}{+180}{+\dimexpr\pgfarrowinset-.5\pgflinewidth}%
    \pgfpathlineto{\pgfqpoint{.5\pgflinewidth}
                             {\dimexpr-\pgfarrowlength+.5\pgflinewidth}}%
    \ifpgfarrowopen\pgfusepathqstroke\else\pgfusepathqfillstroke\fi
  }
}

\pgfdeclarearrow{
  name = ext_Double Cap@,
  defaults = {length = +0pt +1 +1, width = +0pt +1 +0},
  setup code={%
    \pgfarrowssettipend{+0pt}%
    \pgfarrowssetbackend{+-\pgfarrowlength}%
    \pgfarrowssetlineend{+-.5\pgfarrowlength}%
    \pgfarrowsupperhullpoint{+0pt}{+.5\pgfarrowwidth}%
    \pgfarrowsupperhullpoint{+-\pgfarrowlength}{+.5\pgfarrowwidth}%
    \pgfarrowssavethe\pgfarrowwidth
    \pgfarrowssavethe\pgfarrowlength
  },
  drawing code={%
    \pgfsetdash{}{+0pt}%
    \ifpgfarrowroundcap\pgfsetroundcap\fi
    \pgfpathmoveto{\pgfqpoint{-.5\pgfarrowlength}
      {\dimexpr.5\pgfarrowwidth\ifpgfarrowroundcap-.5\pgfarrowlength\fi}}%
    \pgfpathlineto{\pgfqpoint{-.5\pgfarrowlength}
      {\dimexpr-.5\pgfarrowwidth\ifpgfarrowroundcap+.5\pgfarrowlength\fi}}%
    \pgfsetlinewidth{+\pgfarrowlength}%
    \pgfusepathqstroke
  },
  parameters={\the\pgfarrowlength,\the\pgfarrowwidth,\ifpgfarrowroundcap c\fi}}

\pgfdeclarearrow{
  name = ext_Double Stealth@,
  /tikz-ext/@arrows decl/clone = Stealth,
  /tikz-ext/@arrows decl/append setup code = {%
    \pgfmathsetlengthmacro\lwocenter
      {.5*\pgfinnerlinewidth+.25*(\pgflinewidth-\pgfinnerlinewidth)}%
    \advance\pgfarrowinset by\pgf@yc % undo weird things
    \ifdim\pgfarrowinset=0pt \def\shortenedinset{0pt}%
    \else \pgfmathsetlengthmacro\shortenedinset
      {\pgfarrowinset/\pgfutil@tempdimb*(\pgfutil@tempdimb-\lwocenter)}\fi
    \pgfarrowssetlineend{\shortenedinset}%
    \pgfarrowssave\lwocenter
    \pgfarrowssave\shortenedinset
  },
  drawing code = {%
    \pgfsetdash{}{+0pt}%
    \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
    \ifdim\pgfarrowlinewidth=\pgflinewidth
      \else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
    \ifdim\shortenedinset=0pt
      \pgfsetrectcap
      \pgfpathmoveto{\pgfqpoint{\shortenedinset}{-\lwocenter}}%
    \else
      \pgfsetbuttcap
      \pgfpathmoveto{\pgfqpoint
        {\shortenedinset\advance\pgf@x-.5\pgfarrowlinewidth}{-\lwocenter}}%
      \pgfpathlineto{\pgfqpoint{\shortenedinset}{-\lwocenter}}%
    \fi
    \pgfpathlineto{\pgfqpoint{\pgf@ya}{-\pgfutil@tempdimb}}%
    \pgfpathlineto{\pgfqpoint{\pgfutil@tempdima\advance\pgf@x by\pgf@ya}{0pt}}%
    \pgfpathlineto{\pgfqpoint{\pgf@ya}{\pgfutil@tempdimb}}%
    \pgfpathlineto{\pgfqpoint{\shortenedinset}{\lwocenter}}%
    \ifdim\shortenedinset=0pt \else
      \pgfpathlineto{\pgfqpoint
        {\shortenedinset\advance\pgf@x-.5\pgfarrowlinewidth}{\lwocenter}}%
    \fi
    \ifpgfarrowopen \pgfusepathqstroke\else
      \ifdim\pgfarrowlinewidth>0pt \pgfusepathqfillstroke
                             \else \pgfusepathqfill \fi \fi
  },
  defaults = {
    length  = +3pt +4.5 +.8,
    width'  = +0pt +1.75,
    inset'  = +0pt +0.425,
    line width = +0pt +1 +1,
  },
}%

\pgfdeclarearrow{name = ext_Double Cap,     means = {ext_Double     Cap@[quick]}}
\pgfdeclarearrow{name = ext_Double Stealth, means = {ext_Double Stealth@[open, quick]}}
\pgfdeclarearrow{name = ext_Double Triangle,means = {ext_Double Stealth[inset=+0pt]}}

%%% Compatibility
\pgfqkeys{/pgf/arrow keys}{radius/.style={/pgf/arrow keys/inset={#1}}} % should be removed after v0.6
\tikzextset{
  /tikz-ext/compat/add library={arrows}{pre 0.6},
  /tikz-ext/@arrows decl/new name/.code={% This is not a good idea.
    \expandafter\let\csname pgf@ar@code@#1\endcsname\@undefined
    \expandafter\let\csname pgf@ar@defaults@#1\endcsname\@undefined
    \expandafter\let\csname pgf@ar@setup@#1\endcsname\@undefined
    \expandafter\let\csname pgf@ar@bending@mode@#1\endcsname\@undefined
    \expandafter\let\csname pgf@ar@par@#1\endcsname\@undefined
    \expandafter\let\csname pgf@ar@do@cache@#1\endcsname\@undefined
    \pgfset{@arrows decl/name={#1}}%
  },
  compat/arrows/warn/.append code={%
    \tikzextutil@compatwarning@key{arrows}{pre 0.6}{/pgf/@arrows decl/clone}{/tikz-ext/@arrows decl/clone}%
    \tikzextutil@compatwarning@key{arrows}{pre 0.6}{/pgf/@arrows decl/append setup code}{/tikz-ext/@arrows decl/append setup code}%
    \pgfutil@for\tikzext@temp:=Centered Arc Barb,Untipped Arc Barb,Centered Hooks,%
      Centered Straight Barb,Centered Tee Barb,Untipped Tee Barb,Centered Circle,%
      Untipped Circle,Centered Kite,Centered Square,Centered Stealth,Centered Rays\do{%
        \pgfutil@IfUndefined{pgf@ar@code@\tikzext@temp}{%
          \pgfutil@IfUndefined{pgf@ar@means@\tikzext@temp}{%
            \pgfdeclarearrow{%
              /tikz-ext/@arrows decl/clone/.expanded = ext_\tikzext@temp,
              name/.expanded = \tikzext@temp,
              /tikz-ext/@arrows decl/append setup code/.expanded = {%
                \noexpand\tikzextutil@compatmaybewarning
                  {arrow tip '\tikzext@temp'}{'ext_\tikzext@temp'}{arrows = pre 0.6}%
              }%
            }
          }{}%
        }{}%
      }%
  },
  compat/arrows/pre 0.6/.append code=%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Arc      Barb  , means = ext_Centered Arc      Barb}%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Untipped Arc      Barb  , means = ext_Untipped Arc      Barb}%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Hooks          , means = ext_Centered Hooks        }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Straight Barb  , means = ext_Centered Straight Barb}%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Tee      Barb  , means = ext_Centered Tee      Barb}%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Untipped Tee      Barb  , means = ext_Untipped Tee      Barb}%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Circle         , means = ext_Centered Circle       }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Untipped Circle         , means = ext_Untipped Circle       }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Kite           , means = ext_Centered Kite         }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Square         , means = ext_Centered Square       }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Stealth        , means = ext_Centered Stealth      }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Rays           , means = ext_Centered Rays         }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Ellipse        , means = ext_Centered Ellipse      }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Parenthesis    , means = ext_Centered Parenthesis  }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Bar            , means = ext_Centered Bar          }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Bracket        , means = ext_Centered Bracket      }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Diamond        , means = ext_Centered Diamond      }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Turned Square  , means = ext_Centered Turned Square}%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Rectangle      , means = ext_Centered Rectangle    }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Centered Triangle       , means = ext_Centered Triangle     }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Untipped Ellipse        , means = ext_Untipped Ellipse      }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Untipped Parenthesis    , means = ext_Untipped Parenthesis  }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Untipped Bar            , means = ext_Untipped Bar          }%
    \pgfdeclarearrow{/tikz-ext/@arrows decl/new name = Untipped Bracket        , means = ext_Untipped Bracket      }%
    ,%
  compat/arrows/\pgfkeysvalueof{/tikz/ext/compat/arrows}%
}
\endinput

