%\RequirePackage{xcolor}
\RequirePackage{ifthen}
\RequirePackage{pgf}
%\RequirePackage[latin9]{inputenc}
\RequirePackage[T1]{fontenc}
%\RequirePackage{lmodern} 

\newcommand{\pgfumlclass}[3][]{%
  \def\@tempa{#1}%
  \ifx\@tempa\empty%
    \pgf@umlclass[]{#2}{#3}
  \else%
    \pgf@umlclass[#1]{#2}{#3}
  \fi%
}
\def\pgf@umlclass[#1]#2#3{%
  \setlength{\tabcolsep}{5pt}%
  \setlength{\fboxsep}{0pt}%
  \ttfamily%
  \fbox{%
    \begin{tabular}{l}%
      \hfil\textbf{%
        \begin{tabular}{c}%
          #1%
        \end{tabular}%
      }%
      \\ \hline%
      #2%
      \\ \hline%
      #3%
    \end{tabular}%
  }%
}
%
\newbox\pgfuml@boxa
\newbox\pgfuml@boxb
\newbox\pgfuml@boxc
\newbox\pgfuml@boxd
\newdimen\pgfuml@dim@nameattrsep
\newdimen\pgfuml@dim@classht
\newdimen\pgfuml@dim@classwd
\newdimen\pgfuml@dim@attrmethsep
\newdimen\pgfuml@dim@temp
\newdimen\pgfuml@dim@tempa
\@ifundefined{SideSep} {\newdimen\SideSep  \SideSep=2mm}{}
\@ifundefined{MiddleSep} {\newdimen\MiddleSep  \MiddleSep=3mm}{}
\@ifundefined{ShadowSep} {\newdimen\ShadowSep  \ShadowSep=3pt}{}
\newboolean{pgfuml@attribute}%
\newboolean{pgfuml@method}%
\setboolean{pgfuml@attribute}{false}%
\setboolean{pgfuml@method}{false}%
\newboolean{pgfuml@fixedwidth}%
\setboolean{pgfuml@fixedwidth}{false}%
% Keys
\RequirePackage{xkeyval}
\define@boolkey[pgfuml]{class}{shadow}[true]{}
\define@boolkey[pgfuml]{class}{simple}[true]{}
\define@boolkey[pgfuml]{class}{fill}[true]{}
\define@boolkey[pgfuml]{class}{abstract}[true]{}
\define@boolkey[pgfuml]{class}{interface}[true]{}
\define@key[pgfuml]{class}{name}{\def\pgfuml@classname{#1}}
\define@key[pgfuml]{class}{fillcolor}{\def\pgfuml@fillcolor{#1}}
\define@key[pgfuml]{class}{stereotype}{\def\pgfuml@stereotype{#1}}
\define@key[pgfuml]{class}{width}{%
  \ifdim#1>0pt
    \setboolean{pgfuml@fixedwidth}{true}%
    \pgfuml@dim@classwd#1
  \else
    \setboolean{pgfuml@fixedwidth}{false}%
  \fi
}
\presetkeys[pgfuml]{class}{%
  shadow=false,%
  simple=false,%
  fill=false,%
  abstract=false,%
  interface=false,%
  name=,%
  stereotype=,%
  fillcolor=lightgray%
  width=0pt%
}{}
% Utility macros
\def\pgfuml@addsidesep#1{%
  \setbox#1\hbox{\hskip\SideSep\box#1\hskip\SideSep}%
}
\def\pgfuml@boxheight#1#2{%
  #1\ht#2%
  \advance#1\dp#2%
}
\def\pgfuml@testempty#1#2{%
    \def\pgfuml@temp{#2}%
    \ifx\pgfuml@temp\@empty%
      \setboolean{#1}{false}%
    \else%
      \setboolean{#1}{true}%
    \fi%
}
\def\pgfuml@boxarg#1#2#3{%
    \ifthenelse{\boolean{#1}}{%
      \setbox#2\hbox{%
        \setlength{\tabcolsep}{0pt}%
        \begin{tabular}{l}%
          #3%
        \end{tabular}%
      }%
    }{%
      \setbox#2\hbox{}%
    }%
}
\def\pgfuml@maxwd#1#2#3{%
    \ifdim\wd#1>\wd#2%
      \ifdim\wd#1>\wd#3%
        \wd#1%
      \else%
        \wd#3%
      \fi%
    \else%
      \ifdim\wd#2>\wd#3%
        \wd#2%
      \else%
        \wd#3%
      \fi%
    \fi%
}
% User Interface
\newcommand{\pgfumlclassI}{}
\def\pgfumlclassI{\@ifnextchar[{\pgfuml@classI}{\pgfuml@classI[]}}
% Actual macro
\def\pgfuml@classI[#1](#2,#3)#4#5{%
  \setkeys[pgfuml]{class}{#1}%
  \def\pgfuml@class@origin{\pgfpoint{#2}{#3}}%
  \ttfamily\frenchspacing%
  \setbox\pgfuml@boxa\hbox{%
    \ifpgfuml@class@interface%
      \itshape%
      \setlength{\tabcolsep}{0pt}%
      \begin{tabular}{c}%
        \guillemotleft interface\guillemotright\\% 
        \pgfuml@classname%
      \end{tabular}%
    \else%
      \ifx\pgfuml@stereotype\@empty%
        \ifpgfuml@class@abstract%
          \itshape%
        \else%
        \fi%
        \pgfuml@classname%
      \else%
        \setlength{\tabcolsep}{0pt}%
        \begin{tabular}{c}%
          \guillemotleft\pgfuml@stereotype\guillemotright\\% 
          \pgfuml@classname%
        \end{tabular}%
      \fi%
    \fi%
    }%
  \ifpgfuml@class@simple%
    % Adding side sep horizontally
    \pgfuml@addsidesep{\pgfuml@boxa}%
    % Setting the width of the class
    \ifthenelse{\boolean{pgfuml@fixedwidth}}{%
      \setbox\pgfuml@boxa\hbox to \pgfuml@dim@classwd{\hfil\box\pgfuml@boxa\hfil}%
    }{%
      \pgfuml@dim@classwd\wd\pgfuml@boxa%
    }%
    % Adding side sep vertically
    \setbox\pgfuml@boxd\vbox{%
      \vskip\SideSep%
      \box\pgfuml@boxa%
      \vskip\SideSep%
    }%
  \else%
    % Setting boolean indicating whether there are attributes and methods
    \pgfuml@testempty{pgfuml@attribute}{#4}%
    \pgfuml@testempty{pgfuml@method}{#5}%
    % Boxing attributes and methods
    \pgfuml@boxarg{pgfuml@attribute}{\pgfuml@boxb}{#4}%
    \pgfuml@boxarg{pgfuml@method}{\pgfuml@boxc}{#5}%
    % Adding SideSep horizontally to a, b and c
    \pgfuml@addsidesep{\pgfuml@boxa}%
    \pgfuml@addsidesep{\pgfuml@boxb}%
    \pgfuml@addsidesep{\pgfuml@boxc}%
    % Setting the width of the class to be the max of the three boxes
    \pgfuml@dim@classwd\pgfuml@maxwd{\pgfuml@boxa}{\pgfuml@boxb}{\pgfuml@boxc}%
    % adjusting and centering of a
    \setbox\pgfuml@boxa\hbox to \pgfuml@dim@classwd{\hfil\box\pgfuml@boxa\hfil}%
    % \pgfuml@dim@attrmethsep: the y of the first line (\SideSep + c + \MiddleSep/2)
    \pgfuml@boxheight{\pgfuml@dim@attrmethsep}{\pgfuml@boxc}%
    \advance\pgfuml@dim@attrmethsep\SideSep%
    \advance\pgfuml@dim@attrmethsep.5\MiddleSep%
    % \pgfuml@dim@nameattrsep: the y of the second line (first + b + \MiddleSep)
    \pgfuml@boxheight{\pgfuml@dim@nameattrsep}{\pgfuml@boxb}%
    \advance\pgfuml@dim@nameattrsep\pgfuml@dim@attrmethsep%
    \advance\pgfuml@dim@nameattrsep\MiddleSep%
    % Building the final box
    \setbox\pgfuml@boxd\vbox{%
      \vskip\SideSep%
      \box\pgfuml@boxa%
      \vskip\MiddleSep%
      \ifthenelse{\boolean{pgfuml@attribute}}{\box\pgfuml@boxb}{}%
      \vskip\MiddleSep%
      \ifthenelse{\boolean{pgfuml@method}}{\box\pgfuml@boxc}{}%
      \vskip\SideSep%
    }%
  \fi%
  % \pgfuml@dim@classht: the total height of the class 
  \pgfuml@boxheight{\pgfuml@dim@classht}{\pgfuml@boxd}%
  % The background if needed
  \ifpgfuml@class@fill%
    \begin{pgfscope}%
      \color{\pgfuml@fillcolor}%
      \pgfrect[fill]{\pgfuml@class@origin}{\pgfpoint{\the\pgfuml@dim@classwd}{\the\pgfuml@dim@classht}}%%
    \end{pgfscope}%
  \else%
  \fi%
  % The frame
  \begin{pgfscope}%
    \pgfrect[stroke]{\pgfuml@class@origin}{\pgfpoint{\the\pgfuml@dim@classwd}{\the\pgfuml@dim@classht}}%%
  \end{pgfscope}%
  \ifpgfuml@class@simple%
  \else
    % Rules
    \begin{pgfscope}%
      % the first line (between attributes and methods)
      \pgfline{%
        \pgfpointadd{\pgfuml@class@origin}{\pgfpoint{0pt}{\the\pgfuml@dim@attrmethsep}}%
      }{%
        \pgfpointadd{\pgfuml@class@origin}{\pgfpoint{\pgfuml@dim@classwd}{\the\pgfuml@dim@attrmethsep}}%
      }%%
      % the second line (between name and attributes)
      \pgfline{%
        \pgfpointadd{\pgfuml@class@origin}{\pgfpoint{0pt}{\pgfuml@dim@nameattrsep}}%
      }{%
        \pgfpointadd{\pgfuml@class@origin}{\pgfpoint{\pgfuml@dim@classwd}{\the\pgfuml@dim@nameattrsep}}%
      }%%
    \end{pgfscope}%
  \fi%
  % the shadow
  \ifpgfuml@class@shadow%
    \begin{pgfscope}%
      \color{black}%
      \pgfrect[fill]{\pgfpointadd{\pgfuml@class@origin}{\pgfpoint{\ShadowSep}{-\ShadowSep}}}{\pgfpoint{\the\pgfuml@dim@classwd}{\ShadowSep}}%
      \pgfrect[fill]{\pgfpointadd{\pgfuml@class@origin}{\pgfpoint{\pgfuml@dim@classwd}{-\ShadowSep}}}{\pgfpoint{\ShadowSep}{\the\pgfuml@dim@classht}}%
    \end{pgfscope}%
  \else%
  \fi%
  % The content of the class
  \pgfputat{\pgfpointadd{\pgfuml@class@origin}{\pgfpoint{0pt}{.5\pgfuml@dim@classht}}}{%
    \pgfbox[left,center]{\box\pgfuml@boxd}%
  }%
}






%     \def\pgfuml@temp{#4}%
%     \ifx\pgfuml@temp\@empty%
%       \setboolean{pgfuml@attribute}{false}%
%     \else%
%       \setboolean{pgfuml@attribute}{true}%
%     \fi%
%     \def\pgfuml@temp{#5}%
%     \ifx\pgfuml@temp\@empty%
%       \setboolean{pgfuml@method}{false}%
%     \else%
%       \setboolean{pgfuml@method}{true}%
%     \fi%
%     \ifthenelse{\boolean{pgfuml@attribute}}{%
%       \setbox\pgfuml@boxb\hbox{%
%         \setlength{\tabcolsep}{0pt}%
%         \begin{tabular}{l}%
%           #4%
%         \end{tabular}%
%       }%
%     }{%
%       \setbox\pgfuml@boxb\hbox{}%
%     }%
%     \ifthenelse{\boolean{pgfuml@method}}{%
%       \setbox\pgfuml@boxc\hbox{%
%         \setlength{\tabcolsep}{0pt}%
%         \begin{tabular}{l}%
%           #5%
%         \end{tabular}%
%       }%
%     }{%
%       \setbox\pgfuml@boxc\hbox{}%
%     }%
%     \ifdim\wd\pgfuml@boxa>\wd\pgfuml@boxb%
%       \ifdim\wd\pgfuml@boxa>\wd\pgfuml@boxc%
%         \pgfuml@dim@classwd\wd\pgfuml@boxa%
%       \else%
%         \pgfuml@dim@classwd\wd\pgfuml@boxc%
%       \fi%
%     \else%
%       \ifdim\wd\pgfuml@boxb>\wd\pgfuml@boxc%
%         \pgfuml@dim@classwd\wd\pgfuml@boxb%
%       \else%
%         \pgfuml@dim@classwd\wd\pgfuml@boxc%
%       \fi%
%     \fi%
