% 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