% %%%%%%%
% % From http://tex.stackexchange.com/questions/314053/how-to-declare-a-tikz-directory-or-group-of-keys/314065?noredirect=1#comment765927_314065
% \pgfkeys{
%   /handlers/.is directory/.code={
%     \pgfkeysedef{\pgfkeyscurrentpath}{
%       \noexpand\pgfkeys{\pgfkeyscurrentpath/.cd,##1‌​}
%     }
%   }
% }
% %%%%%%%

\tikzmath{
  function sign(\x) {
    if (\x < 0) then {
      return -1;
    } else {
      if (\x > 0) then {
        return 1;
      } else {
        return 0;
      };
    };
  };
}

\newif\iftrianglefitisosceles
\newif\iftrianglefitbackground
\tikzset{
  triangle fit current style/.style={},
  triangle fit current background style/.style={},
  triangle fit/.unknown/.code={
    % \message{triangle fit unknown:\pgfkeyscurrentkeyRAW=#1^^J}
    \let\trianglefitstorekey=\pgfkeyscurrentkeyRAW
    \edef\triangleExp{
      \noexpand\tikzset{
        /tikz/triangle fit current style/.append style={
          \trianglefitstorekey=\noexpand#1
        }
      }
    }
    \triangleExp
    %\pgfqkeys{/tikz}{}
  },
  triangle fit/triangle sep/.initial=0.15em,
  triangle fit/triangle sep/.default=0.15em,
  triangle fit/top space/.initial=1.5ex,
  triangle fit/top space/.default=1.5ex,
  triangle fit/bottom space/.initial=0ex,
  triangle fit/bottom space/.default=0ex,
  triangle fit/top/.initial=,
  triangle fit/nodes/.initial=,
  triangle fit/no rounded corners/.style={/tikz/rounded corners=0pt},
  every triangle fit/.style={
    triangle sep=.15em,
    rounded corners=5pt,
    isosceles,
  },
  triangle fit/isosceles/.is if=trianglefitisosceles,
  triangle fit/not isosceles/.style={isosceles=false},
  triangle fit/bg/.code={
    \tikzset{
      triangle fit current background style/.style={#1},
    }
  },
  triangle fit/.code={
    \tikzset{
      /tikz/triangle fit current style/.style={},
      /tikz/triangle fit/.cd,
      /tikz/every triangle fit,
      #1,
    }
    % \node[draw, /tikz/every triangle fit] {EEE}
    % \edef\currenttrianglestyle{\pgfkeysvalueof{/tikz/triangle fit/style}}
    % \message{\currenttrianglestyle}
    % \tikzset{
    %   triangle fit current style/.style=\currenttrianglestyle,
    % }
    % Compute the minimum and maxiumum slope, as well as the maximum y (i.e. height) for the triangle.
    \tikzmath{
      coordinate \pt,\ttop;
      % int \found;
      % \found{top} = 0;
      % \found{bot} = 0;
      \ttop=([yshift=\pgfkeysvalueof{/tikz/triangle fit/top space}]\pgfkeysvalueof{/tikz/triangle fit/top});
      \slopeleft = 0;
      \sloperight = 0;
      \maxdy = 0;
    }
    % Foreach loop over all nodes, which computes the max and min slopes and triangle height
    \edef\triangleFitItems{\pgfkeysvalueof{/tikz/triangle fit/nodes}}
    \foreach \i in \triangleFitItems{
      \foreach \ii in {(\i.north east),(\i.south east),(\i.south west),(\i.north west)} {
        \tikzmath{
          \pt = \ii;
          \dx = \ptx - \ttopx;
          \dx = \dx + \pgfkeysvalueof{/tikz/triangle fit/triangle sep} * sign(\dx);
          \dy = \ttopy - \pty;
          \dy = \dy + \pgfkeysvalueof{/tikz/triangle fit/triangle sep} * sign(\dy);
          \slope = \dx / \dy;
          if \slope > \sloperight then {
            \sloperight = \slope;
          };
          if \slope < \slopeleft then {
            \slopeleft = \slope;
          };
          if \dy > \maxdy then {
            \maxdy = \dy;
          };
        }
        \global\let\sloperight\sloperight%
        \global\let\slopeleft\slopeleft%
        \global\let\maxdy\maxdy%
        % \message{\ii, ptx=\ptx, pty=\pty, dx=\dx, dy=\dy, slope=\slope, sloperight=\sloperight, slopeleft=\slopeleft, maxdy=\maxdy^^J}
      }
    }
    \tikzmath{
      \maxdy = \maxdy + \pgfkeysvalueof{/tikz/triangle fit/bottom space};
    }
    \iftrianglefitisosceles
      \tikzmath{
        if -\sloperight < \slopeleft then {
          \slopeleft = -\sloperight;
        };
        if -\slopeleft > \sloperight then {
          \sloperight = -\slopeleft;
        };
      }
    \fi
    % Draw the triangle:
    \draw[/tikz/triangle fit current style]
      (\ttopx,\ttopy)
      -- +(\sloperight*\maxdy pt,-\maxdy pt)
      -- +(\slopeleft*\maxdy pt,-\maxdy pt)
      -- cycle;
    
    % Draw the background
    \begin{pgfonlayer}{background}
      \path[/tikz/triangle fit current background style]
        (\ttopx,\ttopy)
        -- +(\sloperight*\maxdy pt,-\maxdy pt)
        -- +(\slopeleft*\maxdy pt,-\maxdy pt)
        -- cycle;      
    \end{pgfonlayer}
  }
}

\def\nodx{
  node[draw, every triangle fit, triangle fit={top={\fittriangletop},nodes={\fittriangletop\foresteoption{fit these}}}] {nodes:\fittriangletop\foresteoption{fit these}}
}
% \forestset{
% %  every triangle fit/.forward to=/tikz/every triangle fit,
%   every triangle fit/append/.forward to=/tikz/every triangle fit/append,
%   every triangle fit/style/.forward to=/tikz/every triangle fit/style,
%   declare toks={fit these}{},
%   triangle fit whole subtree/.style={
%     delay={
%       temptoksa=,
%       for descendants={%
%         temptoksa+/.wrap pgfmath arg={,##1}{name()},
%       },
%       fit these/.register=temptoksa,
%       delay={
%         % /utils/exec={
%         %   \pgfmathsetmacro{\fittriangletop}{name()}
%         %   \message{^^JFIT THESE=\foresteoption{fit these}, NAME=\fittriangletop^^J}
%         % },
%         % append after command={
%         %   \nodx
%         % },
%         tikz+={
%           \pgfmathsetmacro{\fittriangletop}{name()}
%           % \message{\foresteoption{fit these}}
%           \path[triangle fit={
%             top=\fittriangletop.north,
%             nodes={\fittriangletop\foresteoption{fit these}},
%             #1
%           }];
%         },
%       },
%     },
%   },
% }
