\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{tikz-opm}[2014/01/23 v0.1.1 OPM Digrams]


\RequirePackage{tikz}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{calc, positioning}
\usepgflibrary{shapes.multipart, arrows}

\RequirePackage{makeshape}
\RequirePackage{amsmath}

% Keys for tikzopm triangles
%
% /pgf/tikzopmGeneralization : side length (of the triangle)
\pgfkeys{/opm/.cd,
  side length/.code=#1,
  side length/.default=15pt,
  side length/.initial=15pt}
%\pgfkeys{/opm/side length=12pt}

\def\defaulttriangleanchors{%
  \savedanchor{\upper}{%
    \pgfpoint{0pt}{.5\pgf@ya}%
    \mincorrect{\pgf@y}{\pgfshapeminheight}%
    \advance\pgf@y by -2\pgfshapeouterysep%
  }%
  
  \anchor{north}{\upper}%
  \anchor{north west}{\upper}%
  \anchor{north east}{\upper}%
  \anchor{south west}{\pgfpoint{-7.5pt}{-.5\pgf@ya}}%
  \anchor{south}{\pgfpoint{0pt}{-.5\pgf@ya}}%
  \anchor{west}{\pgfpoint{-7.5pt}{-.5\pgf@ya}}%
  \anchor{south east}{\pgfpoint{7.5pt}{-.5\pgf@ya}}%
  \anchor{east}{\pgfpoint{7.5pt}{-.5\pgf@ya}}%
  \anchor{center}{\pgfpointorigin}%
}

\def\defaulttrianglelengths{%
  \pgfmathsetlength{\pgf@xa}{15pt}%\pgfkeysvalueof{/opm/side length}}%
  \pgfmathsetlength{\pgf@ya}{ sqrt(3) * \pgf@xa / 2 }%
}

\def\trianglepath{%
    \defaulttrianglelengths%
    \pgfpathmoveto{\pgfpoint{0pt}{\pgf@ya}}%
    \pgfpathlineto{\pgfpoint{-.5\pgf@xa}{0}}%
    \pgfpathlineto{\pgfpoint{.5\pgf@xa}{0}}%
    \pgfpathclose%
  }
  
\pgfdeclareshape{tikzopmGeneralization}%
{ \nodeparts{}% this is a symbol only
  %% xa: length
  %% ya: height
  \defaulttrianglelengths%
  \defaulttriangleanchors%
  
  %% draw the triangle
  \backgroundpath{
    \trianglepath%
    \pgfusepath{stroke}%
  }%
}

\pgfdeclareshape{tikzopmAggregation}%
{ \nodeparts{}%
  \defaulttrianglelengths%
  \defaulttriangleanchors%
  
  \backgroundpath{%
    \trianglepath%
    \pgfusepath{fill}}
}
  
\pgfdeclareshape{tikzopmExhibition}{%
  \nodeparts{}%
  \defaulttrianglelengths%
  \defaulttriangleanchors%

  \backgroundpath{%
    \defaulttrianglelengths%
    \trianglepath\pgfusepath{stroke}%
    \pgfpathmoveto{\pgfpoint{0pt}{.7\pgf@ya}}%
    \pgfpathlineto{\pgfpoint{-4pt}{.15\pgf@ya}}%
    \pgfpathlineto{\pgfpoint{4pt}{.15\pgf@ya}}%
    \pgfpathclose\pgfusepath{fill}%
  }%
}

\pgfdeclareshape{tikzopmInstantiation}{%
  \nodeparts{}%
  \defaulttrianglelengths%
  \defaulttriangleanchors%

  \backgroundpath{%
    \defaulttrianglelengths%
    \trianglepath\pgfusepath{stroke}%
    \pgfpathmoveto{\pgfpoint{0pt}{0pt}}%
    \pgfpathlineto{\pgfpoint{-4pt}{.5\pgf@ya}}%
    \pgfpathlineto{\pgfpoint{4pt}{.5\pgf@ya}}%
    \pgfpathclose\pgfusepath{fill}%
  }%
}

% \pgfdeclareshap{tikzopmInstance}{%
%   \nodeparts{text,instanceof}%
%   %
%   % Anchors
%   %
%   \savedanchor\centerpoint{%
%     \pgf@x=.5\wd\gpfnodeparttextbox%
%     \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/inner ysep}}%
%     \pgf@y=-\pgf@y%
%     \advance\pgf@y by-\dp\pgfnodeparttextbox%
%     \advance\pgf@y by-.5\pgflinewidth%
%   }%

% \newcommand{\opmInstance}[4]{%
%   \node [shape=rectangle, draw, font=\scriptsize, #4] (#1-inner) {#3};%
%   \node [shape=rectangle, draw, minimum height=25pt,
%   at=(#1-inner.northwest] (#1) {#2};%
%   }

\newcommand{\opmInstance}[2]{%
  \ensuremath{\genfrac{}{}{0pt}{}{\text{#1}}{\text{\tiny #2}}}}

\tikzset{every edge/.style={draw, thick}}
\tikzset{opmentity/.style={draw, thick}}


\tikzset{opminstance/.style={shape=rectangle, draw}}
\tikzset{opmobject/.style={shape=rectangle, opmentity}}
%\tikzset{opmobjectwithstate/.style={shape=rectangle, opmentity,text depth=8ex}}

\tikzset{opmstate/.style={opmentity, shape=rectangle, rounded corners=6pt}}
\tikzset{opmprocess/.style={shape=ellipse, opmentity}}
\tikzset{opmgeneralization/.style={shape=tikzopmGeneralization, draw, yshift=15pt}}
\tikzset{opmaggregation/.style={shape=tikzopmAggregation, draw, yshift=15pt}}
\tikzset{opmexhibition/.style={shape=tikzopmExhibition, draw, yshift=15pt}}
\tikzset{opminstantiation/.style={shape=tikzopmInstantiation, draw, yshift=15pt}}

%% edge styles
\tikzset{opmrelatesto/.style={-angle 45, draw, thick}}
\tikzset{opmbidirrelate/.style={left to-left to, draw, thick}}

%% the requires version allows for a more DSL like style
\tikzset{opminstrument/.style={-o, thick}}
\tikzset{opmrequires/.style={o-, thick}}

%% the handles version allows for a more DSL like style
\tikzset{opmagent/.style={-*, thick}}
\tikzset{opmhandles/.style={-*, thick}}

\tikzset{opminput/.style={-open triangle 45, thick}}

\tikzset{opmoutput/.style={-open triangle 45,thick}}

%% the consumes version allows for a more DSL like style
\tikzset{opmconsumption/.style={-open triangle 45, thick}}
\tikzset{opmconsumes/.style={open triangle 45-, thick}}

%% the yields version allows for a more DSL like style
\tikzset{opmresult/.style={-open triangle 45, thick}}
\tikzset{opmyields/.style={-open triangle 45, thick}}

%% the affects version allows for a more DSL like style
\tikzset{opmeffect/.style={open triangle 45-open triangle 45, thick}}
\tikzset{opmaffects/.style={open triangle 45-open triangle 45, thick}}

\pgfarrowsdeclarecombine*{twoopentriang}{twoopentriang}%
{open triangle 45}{open triangle 45}
{open triangle 45}{open triangle  45}
\tikzset{dbla/.style={postaction={draw,shorten >=-1pt, -open triangle 45}}}
%% the invkoes version allows for a more DSL like style
\tikzset{opminvocation/.style={-twoopentriang, thick}}
\tikzset{opminvokes/.style={-twoopentriang, thick}}
