% Copyright 2022 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.
%
%% full arc
%% https://tex.stackexchange.com/a/144297/16595
%% The postfix operator R is added to PGFmath,
%% it allows the use of angular segments.
%% full arc = 10 makes it so that
%%   1R =  36°
%%   2R =  72°
%%   …
%%  10R = 360°
%% Calling the full arc key with an empty value 
%% makes 1R = 1°
\pgfset{full arc/.code=%
  \def\pgf@temp{#1}%
  \ifx\pgfutil@empty\pgf@temp
    \let\pgfmath@fullarc@factor\pgfutil@empty
  \else
    \pgfmathsetmacro\pgfmath@fullarc@factor{360/(#1)}%
  \fi,full arc=}
\pgfmathdeclareoperator{R}{full arc}{1}{postfix}{950}
\pgfmathdeclarefunction{full arc}{1}{%
  \begingroup
    \pgfmath@x=#1pt\relax
    \ifx\pgfmath@fullarc@factor\pgfutil@empty\else
      \pgfmath@x\pgfmath@fullarc@factor\pgfmath@x
    \fi
    \pgfmath@returnone\pgfmath@x
  \endgroup}

%% foreach
%% http://tex.stackexchange.com/a/126418/16595
%% instead of \foreach \var in {start, start + delta, ..., end}
%% this allows to use \foreach[use int={start to end step delta}] without(!) a list in {}
%% the values start, end and delta are evaluated by PGFmath at the start of the loop.
%% In addition to use int, there's also use float.
\newif\ifqrr@pgf@foreach@no@list
\pgfqkeys{/pgf/foreach}{
  use int/.code={%
    \qrr@pgf@foreach@no@list@parse@to\pgfmathtruncatemacro#1\pgffor@stop
  },
  use float/.code={%
    \qrr@pgf@foreach@no@list@parse@to\pgfmathsetmacro#1\pgffor@stop
  }
}

\def\qrr@pgf@foreach@no@list@parse@to#1#2to#3\pgffor@stop{%
  \qrr@pgf@foreach@no@listtrue
  #1\foreachStart{#2}%
  \pgfutil@in@{step}{#3}
  \ifpgfutil@in@
    \qrr@pgf@foreach@no@list@parse@step{#1}#3\pgffor@stop
  \else
    \qrr@pgf@foreach@no@list@parse@step{#1}#3step1\pgffor@stop
  \fi
  \edef\qrr@pgf@foreach@no@list@list{\foreachStart,\foreachSecond,...,\foreachEnd}%
}
\def\qrr@pgf@foreach@no@list@parse@step#1#2step#3\pgffor@stop{%
  #1\foreachEnd{#2}%
  #1\foreachSecond{\foreachStart+#3}%
}
\def\pgffor@vars{% manually extended, better etoolbox
  \pgfutil@ifnextchar i{\pgffor@@vars@end}{%
    \pgfutil@ifnextchar[{\pgffor@@vars@opt}{%]
      \pgfutil@ifnextchar/{\pgffor@@vars@slash@gobble}{%
         \ifqrr@pgf@foreach@no@list\expandafter\pgfutil@firstoftwo\else
           \expandafter\pgfutil@secondoftwo\fi
         {\qrr@pgf@foreach@no@listfalse\pgffor@macro@list\qrr@pgf@foreach@no@list@list}
         {\pgffor@@vars}}}}}%

%% Handlers
%% .pgfmath evaluates values given to keys in PGFmath before handing them over.
%% .pgfmath int truncates the result
%% .pgfmath strcat concatenates the given values
\pgfkeys{/handlers/.pgfmath/.code=\pgfmathparse{#1}\expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult}}
\pgfkeys{/handlers/.pgfmath int/.code=\pgfmathint{#1}\expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult}}
\pgfkeys{/handlers/.pgfmath strcat/.code=\pgfmathstrcat{#1}\expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult}}

%% http://tex.stackexchange.com/a/144187/16595
%% key/.List={(point-1),(point-2),(point-...),(point-6)} will call
%% key=(point-1)(point-2)(point-3)(point-4)(point-5),(point-6)
\pgfkeys{/handlers/.List/.code={%
    \let\pgfkeys@global@temp\pgfutil@empty
    \foreach \pgfkeys@temp in{#1}{
      \ifx\pgfkeys@global@temp\pgfutil@empty
        \global\let\pgfkeys@global@temp\pgfkeys@temp
      \else
        \expandafter\pgfutil@g@addto@macro\expandafter\pgfkeys@global@temp\expandafter
          {\pgfkeys@temp}%
      \fi}%
    \expandafter\pgfkeys@exp@call\expandafter{\pgfkeys@global@temp}}}

%% PGFmath
%% strrepeat("x", 5) = "xxxxx"
\pgfmathdeclarefunction{strrepeat}{2}{%
  \begingroup\pgfmathint{#2}\pgfmath@count\pgfmathresult
    \let\pgfmathresult\pgfutil@empty
    \pgfutil@loop\ifnum\pgfmath@count>0\relax
      \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult#1}%
      \advance\pgfmath@count-1\relax
    \pgfutil@repeat\pgfmath@smuggleone\pgfmathresult\endgroup}

%% isInString("foo", "foobar") = true (= 1)
%% isInString("boo", "foobar") = false (= 0)
\pgfmathdeclarefunction{isInString}{2}{%
  \pgfutil@in@{#1}{#2}%
  \ifpgfutil@in@\def\pgfmathresult{1}\else\def\pgfmathresult{0}\fi}

%% strcat("foo", "bar") = "foobar" (can have more than two parameters)
\pgfutil@IfUndefined{pgfmathstrcat@}{
  \pgfmathdeclarefunction{strcat}{...}{%
    \begingroup
      \let\pgfmathresult\pgfutil@empty
      \pgfmathstrcat@@#1\pgfmath@stop}
  \def\pgfmathstrcat@@#1{%
    \ifx\pgfmath@stop#1%
      \def\pgfmath@next{\pgfmath@smuggleone\pgfmathresult\endgroup}
    \else
      \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult#1}%
      \let\pgfmath@next\pgfmathstrcat@@
    \fi
    \pgfmath@next}
}{}

% http://tex.stackexchange.com/questions/244569/bounding-lines-around-tax-nodes/244619#244619
\pgfmathdeclarefunction{atanXY}{2}{\pgfmathatantwo@{#2}{#1}}
\pgfmathdeclarefunction{atanYX}{2}{\pgfmathatantwo@{#1}{#2}}

%% http://tex.stackexchange.com/a/132939/16595
\tikzset{
  @edges through/.code={{{% three braces to protect \pgfeov
    \pgfutil@ifnextchar[{\pgfkeysvalueof{/tikz/@@edges through/.@cmd}}
                        {\pgfkeysvalueof{/tikz/@@edges through/.@cmd}[]}#1\pgfeov}}},
  @@edges through/.style args={[#1]#2}{/tikz/insert path={edge[#1] (#2) (#2)}},
  edges through/.style={/tikz/@edges through/.list={#1}}}
\tikzset{
  @edges to/.code={{{% three braces to protect \pgfeov
    \pgfutil@ifnextchar[{\pgfkeysvalueof{/tikz/@@edges to/.@cmd}}
                        {\pgfkeysvalueof{/tikz/@@edges to/.@cmd}[]}#1\pgfeov}}},
  @@edges to/.style args={[#1]#2}{/tikz/insert path={edge[#1] (#2)}},
  edges to/.style={/tikz/@edges to/.list={#1}}}
\tikzset{
  @tos to/.code={{{% three braces to protect \pgfeov
    \pgfutil@ifnextchar[{\pgfkeysvalueof{/tikz/@@tos to/.@cmd}}
                        {\pgfkeysvalueof{/tikz/@@tos to/.@cmd}[]}#1\pgfeov}}},
  @@tos to/.style args={[#1]#2}{/tikz/insert path={to[#1] (#2)}},
  tos to/.style={/tikz/@tos to/.list={#1}}}


\pgfmathdeclarefunction{distancebetween}{2}{% only coordinates/nodes
  \begingroup
    \pgfpointdiff{\pgfpointanchor{#1}{center}}{\pgfpointanchor{#2}{center}}%
    \edef\pgfmath@temp{{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}}%
    \expandafter\pgfmathveclen@\pgfmath@temp
    \pgfmath@smuggleone\pgfmathresult
  \endgroup}
\pgfmathdeclarefunction{qdistancebetween}{1}{% only coordinates/nodes
  \begingroup
    \pgfpointdiff{\pgfpointorigin}{\pgfpointanchor{#1}{center}}%
    \edef\pgfmath@temp{{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}}%
    \expandafter\pgfmathveclen@\pgfmath@temp
    \pgfmath@smuggleone\pgfmathresult
  \endgroup}

\pgfmathdeclarefunction{qanglebetween}{1}{%
  \pgfmathanglebetweenpoints{\pgfpointorigin}{\pgfpointanchor{#1}{center}}}

\pgfmathdeclarefunction{anglebetween}{2}{%
  \pgfmathanglebetweenpoints{\pgfpointanchor{#1}{center}}{\pgfpointanchor{#2}{center}}}

\pgfmathdeclarefunction{isEmpty}{1}{%
  \begingroup
    \edef\pgfmath@temp{#1}%
    \pgfutil@ifxempty\pgfmath@temp{\def\pgfmathresult{1}}{\def\pgfmathresult{0}}%                           
    \pgfmath@smuggleone\pgfmathresult
  \endgroup}

\pgfqkeys{/utils}{
  if/.code n args=3{%
    \pgfmathparse{#1}%
    \ifdim\pgfmathresult pt=0pt
      \expandafter\pgfutil@firstoftwo
    \else
      \expandafter\pgfutil@secondoftwo
    \fi
    {\pgfkeysalso{#3}}%
    {\pgfkeysalso{#2}}},
  IF/.code args={(#1)#2}{%
    \pgfmathparse{#1}%
    \pgfutil@in@{else}{#2}%
    \ifpgfutil@in@
      \expandafter\pgfutil@firstoftwo
    \else
      \expandafter\pgfutil@secondoftwo
    \fi
    {\qrr@misc@handle@else#2\pgf@stop}{\qrr@misc@handle@else#2else\pgf@stop}%
  },
  TeX/if/.code n args={4}{%
    \if#1#2\expandafter\pgfutil@firstoftwo\else\expandafter\pgfutil@secondoftwo\fi
    {\pgfkeysalso{#3}}{\pgfkeysalso{#4}}%
  },
  TeX/ifnum/.code n args={3}{%
    \ifnum#1\relax\expandafter\pgfutil@firstoftwo\else\expandafter\pgfutil@secondoftwo\fi
    {\pgfkeysalso{#2}}{\pgfkeysalso{#3}}%
  },
  TeX/ifdim/.code n args={3}{%
    \ifdim#1\relax\expandafter\pgfutil@firstoftwo\else\expandafter\pgfutil@secondoftwo\fi
    {\pgfkeysalso{#2}}{\pgfkeysalso{#3}}%
  },
  TeX/ifx/.code n args={4}{%
    \ifx#1#2\relax\expandafter\pgfutil@firstoftwo\else\expandafter\pgfutil@secondoftwo\fi
    {\pgfkeysalso{#3}}{\pgfkeysalso{#4}}%
  },
  TeX/ifempty/.code n args={3}{%
    \edef\pgfkeys@temp{#1}%
    \pgfutil@ifxempty\pgfkeys@temp{\pgfkeysalso{#2}}{\pgfkeysalso{#3}}%
  },
  tex/.search also=/utils/TeX,
}
\def\qrr@misc@handle@else#1else#2\pgf@stop{%
  \ifdim\pgfmathresult pt=0pt
    \expandafter\pgfutil@firstoftwo
  \else
    \expandafter\pgfutil@secondoftwo
  \fi
  {\pgfkeysalso{#2}}%
  {\pgfkeysalso{#1}}}

\pgfset{
  declare constant/.code={%
    \let\pgfmathdeclareconstant@@@\pgfutil@empty
    \pgfkeysvalueof{/pgf/declare function/execute at begin function}%
    \pgfmathdeclareconstant@#1@=@;\pgf@stop
    \pgfkeysvalueof{/pgf/declare function/execute at end function}%
    \pgfmathdeclareconstant@@@
  }}
\def\pgfmathdeclareconstant@{%
  \pgfutil@ifnextchar x\pgfmathdeclareconstant@@\pgfmathdeclareconstant@@
}
\def\pgfmathdeclareconstant@@#1=#2;#3\pgf@stop{%
  \edef\pgfmath@local@temp{#1}%
  \pgfutil@ifx\pgfmath@local@temp\pgfmath@local@at{}{%
    \pgfutil@g@addto@macro\pgfmathdeclareconstant@@@{\pgfmathdeclarepseudoconstant{#1}{\def\pgfmathresult{#2}}}%
    \pgfmathdeclareconstant@#3\pgf@stop
  }%
}