% Copyright 2008 by Marc de Falco
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Public License.
%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{tikz-inet}[2008/06/02 v0.1 tikz interaction nets library]
\RequirePackage{tikz}
\RequirePackage{ifthen}

% We need this to load the \emph{isosceles triangle} shape
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{shadows}
\usetikzlibrary{positioning}
\usetikzlibrary{matrix}
\usetikzlibrary{fit}

\pgfkeys{/pgf/.cd,
    arity/.initial=4,
}

% The definition of the shape of a cell
\pgfdeclareshape{cellule}{
    \savedmacro\arity{%        
        \pgfmathtruncatemacro\arity{\pgfkeysvalueof{/pgf/arity}}%
    }

    \inheritsavedanchors[from=isosceles triangle]
    \inheritanchorborder[from=isosceles triangle]
    \inheritanchor[from=isosceles triangle]{center}
    \inheritanchor[from=isosceles triangle]{left corner}
    \inheritanchor[from=isosceles triangle]{right corner}
    \inheritanchor[from=isosceles triangle]{south}
    \inheritanchor[from=isosceles triangle]{west}
    \inheritanchor[from=isosceles triangle]{north east}
    \inheritanchor[from=isosceles triangle]{north west}
    \inheritanchor[from=isosceles triangle]{south east}
    \inheritanchor[from=isosceles triangle]{south west}
    \inheritanchor[from=isosceles triangle]{east}
    \inheritanchor[from=isosceles triangle]{north}
    \inheritanchor[from=isosceles triangle]{lower left}
    \inheritanchor[from=isosceles triangle]{apex}
   
    \anchor{above pax}{
        \trianglepoints
        \pgfmathrotatepointaround{
            \pgfpointadd{
                \pgfpointadd{\pgfpoint{-2ex}{0cm}}{
                    \pgfpointlineattime{0.5}
                        {\lowerleftanchor}{\lowerrightanchor}
                    }
                }
                {\centerpoint}
            }{\centerpoint}{\rotate}
        }

  
    \anchor{above middle pax}{
        \trianglepoints
        \pgfmathrotatepointaround{
            \pgfpointadd{
                \pgfpointadd{\pgfpoint{-2ex}{0cm}}{
                    \pgfpointlineattime{0.5}
                        {\lowerleftanchor}{\lowerrightanchor}
                    }
                }
                {\centerpoint}
            }{\centerpoint}{\rotate}
        }

                    \anchor{pax}{
                    \trianglepoints
                    \pgfmathrotatepointaround{
                    \pgfpointadd{\pgfpointlineattime{0.5}
                    {\lowerleftanchor}{\lowerrightanchor}}{\centerpoint}}
                    {\centerpoint}{\rotate}
                    }


                    \anchor{middle pax}{
                    \trianglepoints
                    \pgfmathrotatepointaround{
                    \pgfpointadd{\pgfpointlineattime{0.5}
                    {\lowerleftanchor}{\lowerrightanchor}}{\centerpoint}}
                    {\centerpoint}{\rotate}
                    }

                    \anchor{above left pax}{
                    \trianglepoints
                    \pgfmathrotatepointaround{
                    \pgfpointadd{
                    \pgfpointadd{\pgfpoint{-2ex}{0cm}}{
                    \pgfpointlineattime{0.25}
                    {\lowerleftanchor}{\lowerrightanchor}
                    }
                    }
                    {\centerpoint}
                    }{\centerpoint}{\rotate}
                    }


                    \anchor{left pax}{
                    \trianglepoints
                    \pgfmathrotatepointaround{
                    \pgfpointadd{\pgfpointlineattime{0.25}
                    {\lowerleftanchor}{\lowerrightanchor}}{\centerpoint}}
                    {\centerpoint}{\rotate}
                    }

    \anchor{above right pax}{
    \trianglepoints
    \pgfmathrotatepointaround{
    \pgfpointadd{
    \pgfpointadd{\pgfpoint{-2ex}{0cm}}{
    \pgfpointlineattime{0.75}
    {\lowerleftanchor}{\lowerrightanchor}
    }
    }
    {\centerpoint}
    }{\centerpoint}{\rotate}
    }


    \anchor{right pax}{
    \trianglepoints
    \pgfmathrotatepointaround{
    \pgfpointadd{\pgfpointlineattime{0.75}
    {\lowerleftanchor}{\lowerrightanchor}}{\centerpoint}}
    {\centerpoint}{\rotate}
    }

    \anchor{above pal}{
    \trianglepoints
    \pgfpointadd{\centerpoint}{
    \pgfmathrotatepointaround{
    \pgfpointadd{\pgfpoint{2ex}{0cm}}{\apexanchor}}
    {\pgfpointorigin}{\rotate}
    }
    }


    \anchor{pal}{
    \trianglepoints
    \pgfpointadd{\centerpoint}{
    \pgfmathrotatepointaround{
    \pgfpointadd{\pgfpoint{-0.07cm}{0cm}}{\apexanchor}
    }{\pgfpointorigin}{\rotate}
    }
    }


    \backgroundpath{
        \trianglepoints{
            \pgftransformshift{\centerpoint}
            \pgftransformrotate{\rotate}
            \pgfpathmoveto{\apex}
            \pgfpathlineto{
                \pgfpointlineattime{0.8}{\apex}{\lowerleft}
            }
            \pgfpathcurveto{
                \pgfpointlineattime{0.9}{\apex}{\lowerleft}
            }{
                \pgfpointlineattime{0.1}{\lowerleft}{\lowerleft\pgf@y-\pgf@y}
            }{
    \pgfpointlineattime{0.2}{\lowerleft}{\lowerleft\pgf@y-\pgf@y}
    }
    \pgfpathlineto{
    \pgfpointlineattime{0.8}{\lowerleft}{\lowerleft\pgf@y-\pgf@y}
    }
    \pgfpathcurveto{
    \pgfpointlineattime{0.9}{\lowerleft}{\lowerleft\pgf@y-\pgf@y}
    }{
    \pgfpointlineattime{0.1}{\lowerleft\pgf@y-\pgf@y}{\apex}
    }{
    \pgfpointlineattime{0.2}{\lowerleft\pgf@y-\pgf@y}{\apex}
    }

    \pgfpathclose
    }
    }
    
    \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@cellule\endcsname{%
		\c@pgf@counta\arity\relax%
		\pgfmathloop%
			\ifnum\c@pgf@counta>0\relax%
				\pgfutil@ifundefined{pgf@anchor@cellule@pax\space\the\c@pgf@counta}{%
                % I HATE TeX
				\expandafter\xdef\csname pgf@anchor@cellule@pax\space\the\c@pgf@counta\endcsname{% 
                \noexpand\pgfmathadd@{\noexpand\arity}{-1}%
                \noexpand\c@pgf@countb=\noexpand\pgfmathresult%
                \noexpand\pgfmathadd@{\the\c@pgf@counta}{-1}%
                \noexpand\pgfmathdivide@{\noexpand\pgfmathresult}%
                    {\noexpand\the\c@pgf@countb}%
                \noexpand\pgfmathmultiply@{\noexpand\pgfmathresult}{0.5}%
                \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{0.25}%
                \noexpand\let\noexpand\time\noexpand\pgfmathresult%
                \noexpand\trianglepoints%
                  \noexpand\pgfmathrotatepointaround{%
                  \noexpand\pgfpointadd{%
                    \noexpand\pgfpointlineattime%
                    {\noexpand\time}%
                    {\noexpand\lowerleftanchor}%
                    {\noexpand\lowerrightanchor}%
                  }{\noexpand\centerpoint}%
                  }{\noexpand\centerpoint}{\noexpand\rotate}%
                }%
                \expandafter\xdef\csname pgf@anchor@cellule@above pax\space\the\c@pgf@counta\endcsname{%
                \noexpand\pgfmathadd@{\noexpand\arity}{-1}%
                \noexpand\c@pgf@countb=\noexpand\pgfmathresult%
                \noexpand\pgfmathadd@{\the\c@pgf@counta}{-1}%
                \noexpand\pgfmathdivide@{\noexpand\pgfmathresult}%
                    {\noexpand\the\c@pgf@countb}%
                \noexpand\pgfmathmultiply@{\noexpand\pgfmathresult}{0.5}%
                \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{0.25}%
                \noexpand\let\noexpand\time\noexpand\pgfmathresult%
                \noexpand\trianglepoints
                  \noexpand\pgfmathrotatepointaround{%
                      \noexpand\pgfpointadd{%
                            \noexpand\pgfpointadd{
                                \noexpand\pgfpoint{-2ex}{0cm}}{%
                                    \noexpand\pgfpointlineattime%
                                        {\noexpand\time}%
                                        {\noexpand\lowerleftanchor}%
                                        {\noexpand\lowerrightanchor}%
                                    }%
                            }{\noexpand\centerpoint}%
                    }%
                    {\noexpand\centerpoint}%
                    {\noexpand\rotate}%
                }%
			}{\c@pgf@counta0\relax}% 
			\advance\c@pgf@counta-1\relax%
		\repeatpgfmathloop%	
	}%

}

\newcommand\inetoptions{\setkeys{inet}}
\newcommand{\inetcolor}{red}
\define@key{inet}{color}{\renewcommand{\inetcolor}{#1}}
\newcommand{\inet@defaultangle}{0}
\define@key{inet}{defaultangle}{\renewcommand{\inet@defaultangle}{#1}}

\newcount\inet@angle
\inet@angle=0

\tikzset{wirestyle/.style = {draw, line width=0.15ex, line cap=rect}}
\tikzset{cellstyle/.style = {
    draw, line width=0.2ex, fill=white,
    inner sep=0.2ex,
    }}
\tikzset{boxstyle/.style = {draw,line width=0.1ex}}
\tikzfading[name=inet fading,
    left color=transparent!0,
    right color=transparent!100]
\tikzset{fancywirestyle/.style = {draw, line width=0.15ex,
    draw=black!50!#1,
    double=white!50!#1,double distance=0.2ex,
   }}
\tikzset{fancycellstyle/.style={%
    general shadow={fill, shadow scale=1.0,%
    shadow xshift=0.3ex,shadow yshift=-0.3ex,opacity=0.2},
    line width=0.15ex,%
    inner sep=0.2ex,%
    draw=black!50!#1,%
    top color=#1,%
    bottom color=white,%!80!#1,%
    shading angle=\inet@angle,%
    }}
\tikzset{fancyboxstyle/.style = {line width=0.2ex,fill opacity=0.5,
    fill=white!20!#1,draw=black!30!#1}}

\newif\ifinet@fancy\inet@fancyfalse

\DeclareOption{fancy}{\inet@fancytrue}
\DeclareOption{nofancy}{\inet@fancyfalse}

\newcommand{\inetfancy}{\inet@fancytrue}
\newcommand{\inetnofancy}{\inet@fancyfalse}

\newcommand{\inetsetfancycellstyle}[1]{
    \tikzset{fancycellstyle/.style = {#1}}%
}
\newcommand{\inetsetfancywirestyle}[1]{
    \tikzset{fancycellstyle/.style = {#1}}%
}

\DeclareOption*{\expandafter\inetoptions\expandafter{\CurrentOption}}
\ProcessOptions\relax

\pgfdeclarelayer{wire layer}
\pgfdeclarelayer{box layer}
\pgfsetlayers{box layer,wire layer,main}

\makeatletter

\newcommand{\inetcellstyle}{%
    \ifinet@fancy fancycellstyle\else cellstyle\fi%
}

\newcommand{\inetwirestyle}{%
    \ifinet@fancy fancywirestyle\else wirestyle\fi%
}

\newcommand{\inetboxstyle}{%
    \ifinet@fancy fancyboxstyle\else boxstyle\fi%
}


\newcommand{\inetcell}[1][]{%
    \@ifnextchar({%
    \inetcell@ii[#1]%
    }{%
    \inetcell@iib[#1]%
    }%
}

\def\inetcell@iib[#1]#2{%
    \inetcell@ii[#1](#2){#2}%
}

\def\inetcell@ii[#1](#2)#3{%
    \@ifnextchar[{\inetcell@iii[#1](#2){#3}%
    }{\inetcell@iii[#1](#2){#3}[\inet@defaultangle]}%
}

\def\inetcell@iii[#1](#2)#3[#4]{%
    \ifthenelse{\equal{#4}{U}}{\inet@angle=180}{%
        \ifthenelse{\equal{#4}{D}}{\inet@angle=0}{%
            \ifthenelse{\equal{#4}{L}}{\inet@angle=270}{%
                \ifthenelse{\equal{#4}{R}}{\inet@angle=90}{\inet@angle=#4}%
            }%
        }%
    }%
    \node[%
    \inetcellstyle=\inetcolor%
    ,shape border rotate=\inet@angle-90%
    ,cellule, isosceles triangle apex angle=60,%
    shape border uses incircle, #1] (#2) {#3};%
}

\def\inetwirecoords(#1)(#2){%
    \begin{pgfonlayer}{wire layer}%
        \draw[\ifinet@fancy fancywirestyle\else wirestyle\fi=\inetcolor]%
        (#1) -- (#2);%
    \end{pgfonlayer}
}

\def\inetwire{%
    \@ifnextchar[{\inetwire@i}{\inetwire@i[]}%
}

\def\inetwire@i[#1](#2.#3)(#4.#5){%
    \begin{pgfonlayer}{wire layer}%
        \draw[\inetwirestyle=\inetcolor,#1]%
        (#2.#3) .. controls (#2.above #3) and (#4.above #5) .. (#4.#5);%
    \end{pgfonlayer}%
}

\def\inetwirefree{%
    \@ifnextchar[{\inetwirefree@i}{\inetwirefree@i[]}%
}
\def\inetwirefree@i[#1](#2.#3){%
    \begin{pgfonlayer}{wire layer}%
        \draw[\ifinet@fancy fancywirestyle\else wirestyle\fi=\inetcolor,#1]%
        (#2.#3) -- (#2.above #3);%
    \end{pgfonlayer}%
}

\newcommand{\inetloop}[1][]{%
    \begin{pgfonlayer}{wire layer}%
        \node[\ifinet@fancy fancywirestyle\else wirestyle\fi=\inetcolor,%
        #1,circle,inner sep=6pt] {};
    \end{pgfonlayer}%
}

\newcommand{\inetbox}[1][]{%
    \inetbox@i[#1]%
}

\def\inetbox@i[#1]#2(#3){%
    \begin{pgfonlayer}{box layer}%
        \node[\ifinet@fancy fancyboxstyle\else boxstyle\fi=\inetcolor,
        fit=#2,inner sep=10pt,#1] (#3) {};%
    \end{pgfonlayer}%
}

\newcommand{\inetprombox}[1][]{%
    \inetprombox@i[#1]%
}
\def\inetprombox@i[#1]#2(#3){%
   \inetbox@i[#1]{#2}(b#3)%
   \inetcell[above=-4ex of b#3.south](#3){$!$}%
   %\inetcell[above=-4ex of $(b#3.south west)!.75!(b#3.south)$](#3){$!$}%
}

\makeatother

\endinput
