% Copyright 2013 by Valletta Ventures
%
% This file may be distributed and/or modified under the LaTeX Project Public License

% A few notes
% * \pgf@sys@bp{} converts any measurement into pdf/ps coordinate system

% fundamental object writing command
\def\pgfsys@invoke#1{\special{vvtexpgf:: #1}}

% outer invoke is a monumentally stupid thing to do, so I've suppressed it here
% however, given the structure of vvtex's pgf driver it would work quite well
\def\pgfsys@outerinvoke#1{}
 
%\ifpgfsys@eorule is defined in pgfsys.code.tex
\newif\ifpgf@fillcolor
\newif\ifpgf@strokecolor
\newif\ifpgfsys@@clipnext

% Section: Path manipulation

% Subsection:lineto ✓
\def\pgfsys@lineto#1#2{\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgfsysprotocol@literal{lineto}}

% Subsection: moveto ✓
\def\pgfsys@moveto#1#2{\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgfsysprotocol@literal{moveto}}

% Subsection: curveto ✓
\def\pgfsys@curveto#1#2#3#4#5#6{\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgf@sys@bp{#3}\pgf@sys@bp{#4}\pgf@sys@bp{#5}\pgf@sys@bp{#6}\pgfsysprotocol@literal{curveto}}
  
% Subsection: rect ✓
\def\pgfsys@rect#1#2#3#4{\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgf@sys@bp{#3}\pgf@sys@bp{#4}\pgfsysprotocol@literal{rect}}

% Subsection: closepath ✓
\def\pgfsys@closepath{\pgfsysprotocol@literal{closepath}}

% Subsection: stroke ✓
\def\pgfsys@stroke{%
  \ifpgfsys@@clipnext%
    \ifpgfsys@eorule%
      \pgfsysprotocol@literal{strokeandclip}%
    \else%
      \pgfsysprotocol@literal{strokeandeoclip}%
    \fi%
    \pgfsys@@clipnextfalse%
  \else%
    \pgfsysprotocol@literal{stroke}%
 \fi}
 
% Subsection: fill ✓
\def\pgfsys@fill{%
  \ifpgfsys@@clipnext%
    \ifpgfsys@eorule%
      \pgfsysprotocol@literal{eofillandclip}%
    \else%
      \pgfsysprotocol@literal{fillandclip}%
    \fi%
    \pgfsys@@clipnextfalse%
  \else%
    \ifpgfsys@eorule%
      \pgfsysprotocol@literal{eofill}%
    \else%
      \pgfsysprotocol@literal{fill}%
    \fi%
 \fi}

% Subsection: fill and stroke a path ✓
\def\pgfsys@fillstroke{%
  \ifpgfsys@@clipnext%
    \ifpgfsys@eorule%
      \pgfsysprotocol@literal{eofillandstrokeandclip}%
    \else%
      \pgfsysprotocol@literal{fillandstrokeandclip}%
    \fi%
    \pgfsys@@clipnextfalse%
  \else%
    \ifpgfsys@eorule%
      \pgfsysprotocol@literal{eofillandstroke}%
    \else%
      \pgfsysprotocol@literal{fillandstroke}%
    \fi%
  \fi}
    
% Subsection: clipnext ✓
\def\pgfsys@clipnext{\pgfsys@@clipnexttrue}

% Subsection: discardpath ✓
\def\pgfsys@discardpath{%
  \ifpgfsys@@clipnext%
    \ifpgfsys@eorule%
      \pgfsysprotocol@literal{eoclip}%
    \else%
      \pgfsysprotocol@literal{clip}%
    \fi%
    \pgfsys@@clipnextfalse%
  \else%
    \pgfsysprotocol@literal{discardpath}%
  \fi}

% Section:  CTM

% Subsection: transformcm ✓
\def\pgfsys@transformcm#1#2#3#4#5#6{%
  \pgfsysprotocol@literalbuffered{[#1 #2 #3 #4}\pgf@sys@bp{#5}\pgf@sys@bp{#6}\pgfsysprotocol@literal{] concat}}

% Section:  scope 

% Subsection: beginscope ✓
\def\pgfsys@beginscope{\pgfsysprotocol@literal{save}}

% Subsection: endscope ✓
\def\pgfsys@endscope{\pgfsysprotocol@literal{restore}}


% Section:  Graphics state

% Subsection: setdash ✓
\def\pgfsys@setdash#1#2{%
  \pgfsysprotocol@literalbuffered{[}%
  \pgfutil@for\pgf@sys@temp:={#1}\do{\pgf@sys@bp{\pgf@sys@temp}}%
  \pgfsysprotocol@literalbuffered{]}%
  \pgf@sys@bp{#2}\pgfsysprotocol@literal{setdash}}
  
% Subsection: setlinewidth ✓
\def\pgfsys@setlinewidth#1{\pgf@sys@bp{#1}\pgfsysprotocol@literal{setlinewidth}}

% Subsection: setmiterlimit ✓
\def\pgfsys@setmiterlimit#1{\pgfsysprotocol@literal{#1 setmiterlimit}}

% NB in the following commands, the values must correspond to CGLineCap values. These values are common between pdf and ps

% Subsection: buttcap ✓
\def\pgfsys@buttcap{\pgfsysprotocol@literal{0 setlinecap}}

% Subsection: roundcap ✓
\def\pgfsys@roundcap{\pgfsysprotocol@literal{1 setlinecap}}

% Subsection: rectcap ✓
\def\pgfsys@rectcap{\pgfsysprotocol@literal{2 setlinecap}}

% NB in the following commands, the values must correspond to CGLineJoin values. These values are common between pdf and ps

% Subsection: miterjoin ✓
\def\pgfsys@miterjoin{\pgfsysprotocol@literal{0 setlinejoin}}

% Subsection: round join ✓
\def\pgfsys@roundjoin{\pgfsysprotocol@literal{1 setlinejoin}}

% Subsection: bevel join ✓
\def\pgfsys@beveljoin{\pgfsysprotocol@literal{2 setlinejoin}}

% Section:  colour

% Subsection: rgbstroke ✓
\def\pgfsys@color@rgb@stroke#1#2#3{\pgfsysprotocol@literal{#1 #2 #3 setrgbstrokecolour}\pgf@strokecolortrue}

% Subsection: rgbfill ✓
\def\pgfsys@color@rgb@fill#1#2#3{\pgfsysprotocol@literal{#1 #2 #3 setrgbfillcolour}\pgf@fillcolortrue}

% Subsection: rgb fill and stroke ✓
\def\pgfsys@color@rgb#1#2#3{\pgfsys@color@reset\pgfsys@color@rgb@stroke{#1}{#2}{#3}\pgfsys@color@rgb@fill{#1}{#2}{#3}}

% Subsection: cmyk stroke ✓
\def\pgfsys@color@cmyk@stroke#1#2#3#4{\pgfsysprotocol@literal{#1 #2 #3 #4 setcmykstrokecolour}\pgf@strokecolortrue}

% Subsection: cmyk fill ✓
\def\pgfsys@color@cmyk@fill#1#2#3#4{\pgfsysprotocol@literal{#1 #2 #3 #4 setcmykfillcolour}\pgf@fillcolortrue}

% Subsection: cmyk fill and stroke ✓
\def\pgfsys@color@cmyk#1#2#3#4{\pgfsys@color@reset\pgfsys@color@cmyk@stroke{#1}{#2}{#3}{#4}\pgfsys@color@cmyk@fill{#1}{#2}{#3}{#4}}

% Subsection: cmy stroke (dependent on cmyk stroke) ✓
\def\pgfsys@color@cmy@stroke#1#2#3{\pgfsysprotocol@literal{#1 #2 #3 0 setcmykstrokecolour}\pgf@strokecolortrue}

% Subsection: cmy fill  (dependent on cmyk stroke) ✓
\def\pgfsys@color@cmy@fill#1#2#3{\pgfsysprotocol@literal{#1 #2 #3 0 setcmykfillcolour}\pgf@fillcolortrue}

% Subsection: cmy fill and stroke ✓
\def\pgfsys@color@cmy#1#2#3{\pgfsys@color@reset\pgfsys@color@cmyk@stroke{#1}{#2}{#3}{0}\pgfsys@color@cmyk@fill{#1}{#2}{#3}{0}}

% Subsection: gray stroke ✓
\def\pgfsys@color@gray@stroke#1{\pgfsysprotocol@literal{#1 setgraystrokecolour}\pgf@strokecolortrue}

% Subsection: gray fill ✓
\def\pgfsys@color@gray@fill#1{\pgfsysprotocol@literal{#1 setgrayfillcolour}\pgf@fillcolortrue}

% Subsection: gray fill and stroke ✓
\def\pgfsys@color@gray#1{\pgfsys@color@reset\pgfsys@color@gray@stroke{#1}\pgfsys@color@gray@fill{#1}}

% Subsection: I think this is only called by pgfsys@color@reset ✓
% I'm am curious whether this needs to "turn off" stroking at the vvtex level, but it seems not
\def\pgfsysps@color@resetnow{\pgf@strokecolorfalse\pgf@fillcolorfalse}%

% Subsection: colorreset
\def\pgfsys@color@reset{%
  \ifpgfsys@color@reset@inorder%
    \ifpgf@strokecolor%
      \pgfsysps@color@resetnow%
    \else%
      \ifpgf@fillcolor%
        \pgfsysps@color@resetnow%
      \fi%
    \fi%
  \else%
    \pgfsysps@color@resetnow%
  \fi}


% Section:  Opacity

% Subsection: fill opacity ✓
\def\pgfsys@fill@opacity#1{%
  \pgfsysprotocol@literal{#1 setfillalpha}
}

% Subsection: stroke opacity ✓
\def\pgfsys@stroke@opacity#1{%
  \pgfsysprotocol@literal{#1 setstrokealpha}
}

% Section:  Shadings

% Subsection: horizhading ✓
\def\pgfsys@horishading#1#2#3{%
\pgfsys@invoke{#1 -- #2 -- #3 horishading}%
  {%
    \pgf@parsefunc{#3}%
    \pgfmathsetlength\pgf@x{#2}%
    \pgf@xa=\pgf@x%
    \pgf@sys@bp@correct{\pgf@x}%
    \pgf@y=\pgf@max%
    \pgf@sys@bp@correct{\pgf@y}%
    \expandafter\xdef\csname @pgfshading#1!\endcsname{\hbox to \the\pgf@max{%
        \noexpand\vrule width0pt height\the\pgf@xa%
        \noexpand\pgfsys@beginpurepicture%
          % I think this is width then height
          \noexpand\pgfsys@rect{0pt}{0pt}{\the\pgf@max}{\the\pgf@xa}%
          \noexpand\pgfsys@clipnext%
          \noexpand\pgfsys@discardpath%
          \noexpand\pgfsys@invoke{\pgf@domb\space \pgf@sys@tonumber{\pgf@x} horizontalpreshade}%
          \noexpand\pgfsys@invoke{\pgf@psfuncs\space horizontalshade}%
          \hss%
        \noexpand\pgfsys@endpurepicture}}%
  }%
}

% Subsection: vertshading ✓
\def\pgfsys@vertshading#1#2#3{%
  \pgfsys@invoke{#1 -- #2 -- #3}%
  {%
    \pgf@parsefunc{#3}%
    \pgfmathsetlength\pgf@x{#2}%
    \pgf@xa=\pgf@x%
    \pgf@sys@bp@correct{\pgf@x}%
    \pgf@y=\pgf@max%
    \pgf@sys@bp@correct{\pgf@y}%
    \expandafter\xdef\csname @pgfshading#1!\endcsname{\hbox to\the\pgf@xa{%
        \noexpand\vrule width0pt height\the\pgf@max%
        \noexpand\pgfsys@beginpurepicture%
          \noexpand\pgfsys@rect{0pt}{0pt}{\the\pgf@xa}{\the\pgf@max}%
          \noexpand\pgfsys@clipnext%
          \noexpand\pgfsys@discardpath%
          % I'm not sure what the first parameter is height? but the second is width
          \noexpand\pgfsys@invoke{\pgf@domb\space \pgf@sys@tonumber{\pgf@x}\space verticalpreshade}%
          % \pgf@psfuncs is setup during the pgf@parsefunc call to
          % first pass
          %  \pgf@prevx\space \pgf@rgb\space \pgf@prevcolor\space pgfshade
          % subsequent passes
          %  \pgf@prevx\space \pgf@rgb\space \pgf@prevcolor\space pgfshade
          %
          % each pgfshade is a colourstop I believe with y, colour at this colour stop, colour at last colour stop, pgfshde command
          % there is an implicit colourstop at y=height with the 
          \noexpand\pgfsys@invoke{\pgf@psfuncs\space verticalshade}%
          \hss%
        \noexpand\pgfsys@endpurepicture}}%
  }%
}

% Subsection: radialshading ✓
\def\pgfsys@radialshading#1#2#3{%
  {%
    \pgf@parsefunc{#3}%
    \pgf@process{#2}%
    \pgf@sys@bp@correct{\pgf@x}%
    \pgf@sys@bp@correct{\pgf@y}%
    \pgf@xa=2\pgf@max%
    \pgf@sys@bp@correct{\pgf@max}%
    \advance\pgf@x by \pgf@max%
    \advance\pgf@y by \pgf@max%
    \expandafter\xdef\csname @pgfshading#1!\endcsname{\hbox to \the\pgf@xa{%
        \noexpand\vrule width0pt height\the\pgf@xa%
        \noexpand\pgfsys@beginpurepicture%
          \noexpand\pgfsys@invoke{%
            \pgf@domb\space \pgf@sys@tonumber{\pgf@y} \pgf@sys@tonumber{\pgf@x} \pgf@sys@tonumber{\pgf@max} radialpreshade\space %
            \pgf@psfuncs\space %
            \pgf@firstcolor\space \pgf@doma\space radialshade}%
          \hss%
        \noexpand\pgfsys@endpurepicture}}%
  }%
}

% Subsection: functionalshading
\def\pgfsys@functionalshading#1#2#3#4{%
\PackageWarning{pgfsys-vvtex}{vvtex pgf driver does not support functional shading - please contact Texpad support}%
}

% Section:  Patterns

% Subsection: declarepattern ✓
\def\pgfsys@declarepattern#1#2#3#4#5#6#7#8#9{%
  % Start building the pattern dictionary:
  \pgf@xa=#2\relax%
  \pgf@ya=#3\relax% 
  \pgf@xb=#4\relax%
  \pgf@yb=#5\relax%
  \pgf@xc=#6\relax%
  \pgf@yc=#7\relax%
  \pgf@sys@bp@correct\pgf@xa% x1
  \pgf@sys@bp@correct\pgf@ya% y1
  \pgf@sys@bp@correct\pgf@xb% x2
  \pgf@sys@bp@correct\pgf@yb% y2
  \pgf@sys@bp@correct\pgf@xc% xstep
  \pgf@sys@bp@correct\pgf@yc% ystep
  % #1 is pattern name, #8 is pattern "code", #9 is flag
  \pgfsys@invoke{'#1}% first the name, as a string
  \pgfsys@invoke{\pgf@sys@tonumber\pgf@xa}% x1
  \pgfsys@invoke{\pgf@sys@tonumber\pgf@ya}% y1
  \pgfsys@invoke{\pgf@sys@tonumber\pgf@xb}% x2
  \pgfsys@invoke{\pgf@sys@tonumber\pgf@yb}% y2
  \pgfsys@invoke{\pgf@sys@tonumber\pgf@xc}% xstep
  \pgfsys@invoke{\pgf@sys@tonumber\pgf@yc}% ystep
  \pgfsys@invoke{"#8}% put the drawing code in as a block
  \pgfsys@invoke{#9\space declarepattern}% flag
}

% Subsection: setpatternnuncolored ✓
% #1 = pattern name, #2,#3,#4 = r,g,b
\def\pgfsys@setpatternuncolored#1#2#3#4{%
  \pgfsysprotocol@literal{'#1 #2 #3 #4 setuncolouredpattern}% NB using " would force the entire line to be a pattern
  \pgf@fillcolortrue%
}

% Subsection: setpatterncolored ✓
% pattern name only (must have been declared with flag = 1)
\def\pgfsys@setpatterncolored#1{%
  \pgfsysprotocol@literal{'#1 setcolouredpattern}%
  \pgf@fillcolortrue%
}


% this is inserted at the beginning of a document
\def\pgfsys@atbegindocument{}

% Section: begin/end

% Subsection: beginpicture ✓
\def\pgfsys@beginpicture{\special{vvtexpgf::begin}}

% Subsection: endpicture ✓
\def\pgfsys@endpicture{\special{vvtexpgf::end}}

% Section: hbox ✓
% With vvtex there is no need to end the context, and if you do, you lose the positioning information
\def\pgfsys@hbox#1{%
  \wd#1=0pt%
  \ht#1=0pt%
  \dp#1=0pt%
  \box#1}

%TODO no idea how to implement this: \def\pgfsys@color@unstacked#1{}

% I've cleared out all the image suffixes, because right now we don't keep any
\def\pgfsys@imagesuffixlist{png:pdf:jpg:jpeg:bmp}

% This is interpreted by the code added for the geometry package
% Subsection: papersize ✓
\def\pgfsys@papersize#1#2{%
  \expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument\special{papersize=#1,#2}}}

% this is supposedly only needed for plain TeX
% TODO comment out?
\AtBeginDocument{ % needed for plain TeX
  \pgfsys@atbegindocument
  \let\pgfsys@atbegindocument=\pgfutil@empty
}

% Section: position tracking ✓

% NB added the \vvtexcurx and \vvtexcury primitives to vvtex to make this work

\def\pgfsys@markposition#1{%
  \edef\pgf@temp{#1}%
  \expandafter\write\expandafter\pgfutil@auxout\expandafter{%
    \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\vvtexcurx}{\vvtexcury}}%
}

\def\pgfsyspdfmark#1#2#3{%
  \expandafter\gdef\csname pgf@sys@pdf@mark@pos@#1\endcsname{\pgfqpoint{#2sp}{#3sp}}%
}

\def\pgfsys@getposition#1#2{%
  \edef\pgf@marshal{%
    \let\noexpand#2=\expandafter\noexpand\csname pgf@sys@pdf@mark@pos@#1\endcsname%
  }%
  \pgf@marshal%
}

\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfpointorigin}

\endinput