%D \module
%D   [       file=meta-ini,
%D        version=2008.03.25,
%D          title=\METAPOST\ Graphics,
%D       subtitle=Initialization,
%D         author=Hans Hagen,
%D           date=\ currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D For real \METAFUN\ magic see \type {https://art-aleatoire.com/}.

% initializations:
%
% - pass settings from tex to mp (delayed expansion)
% - used by context core (and modules)
% - cummulative definitions
% - flushed each graphic
% - can be disabled per instance
% - managed at the tex end
%
% extensions:
%
% - add mp functionality (immediate expansion)
% - cummulative
% - all instances or subset of instances
% - can be disabled per instance
% - managed at the lua/mp end
% - could be managed at the tex end but no real reason and also messy
%
% definitions:
%
% - add mp functionality (delayed expansion)
% - cummulative
% - per instance
% - managed at the tex end
%
% inclusions:
%
% - add mp functionality (delayed expansion)
% - cummulative only when [+]
% - per instance
% - managed at the tex end
%
% order of execution:
%
%   definitions
%   extensions
%   inclusions
%   beginfig
%     initializations
%     graphic
%   endfig

% The instance will be implemented stepwise ... I should redo some code in order to
% make the macros look better than they do now.

\writestatus{loading}{MetaPost Graphics / Initializations}

\registerctxluafile{meta-ini}{autosuffix}

\unprotect

\newtoks \everyMPgraphic          % mp % public or not ?

\appendtoks
    \setcatcodetable\ctxcatcodes
    % then this is not needed:
    \restoreendofline % see interferences-001.tex
\to \everyMPgraphic

\mutable  \cdef\MPruntimefile    {mprun}
\mutable  \cdef\currentMPformat  {metafun}
\permanent\cdef\defaultMPinstance{metafun}

\installcorenamespace{mpinstance}
\installcorenamespace{mpinclusions}
\installcorenamespace{mpdefinitions}
\installcorenamespace{mpgraphic}
\installcorenamespace{mpstaticgraphic}
\installcorenamespace{mpclip}
\installcorenamespace{mpcategory}

\newtoks \t_meta_initializations  % tex, each

\permanent\def\t_meta_inclusions {\csname\??mpinclusions \currentMPinstance\endcsname} % token register
\permanent\def\t_meta_definitions{\csname\??mpdefinitions\currentMPinstance\endcsname} % token register

%D The next command is, of course, dedicated to Mojca, who needs it for gnuplot.
%D Anyway, the whole multiple engine mechanism is to keep her gnuplot from
%D interfering.

\lettonothing\m_meta_saved_instance

\permanent\tolerant\protected\def\startMPdefinitions#=#:#2\stopMPdefinitions
  {\let\m_meta_saved_instance\currentMPinstance
   \cdef\currentMPinstance{#1}%
   \ifempty\currentMPinstance
     \let\currentMPinstance\defaultMPinstance
   \fi
   \gtoksapp\t_meta_definitions{#2}%
   \let\currentMPinstance\m_meta_saved_instance}

\permanent\protected\lettonothing\stopMPdefinitions

\permanent\tolerant\protected\def\startMPextensions#=#:#2\stopMPextensions % we could use buffers instead
  {\clf_setmpextensions{#1}{#2}}

\permanent\protected\lettonothing\stopMPextensions

\permanent\protected\def\startMPinitializations#1\stopMPinitializations % for all instances, when enabled
  {\gtoksapp\t_meta_initializations{#1}}

\permanent\protected\lettonothing\stopMPinitializations

\permanent\tolerant\protected\def\startMPinclusions[#1]#*#:#=#:#3\stopMPinclusions
  {\let\m_meta_saved_instance\currentMPinstance % \pushmacro
   \cdef\currentMPinstance{#2}%
   \ifempty\currentMPinstance
     \let\currentMPinstance\defaultMPinstance
   \fi
   \iftok{#1}{+}\else
     \global\t_meta_inclusions\emptytoks
   \fi
   \gtoksapp\t_meta_inclusions{#3}%
   \let\currentMPinstance\m_meta_saved_instance} % \popmacro

\permanent\protected\lettonothing\stopMPinclusions

% The next was broken since we added instances so it will go away!

\permanent\tolerant\protected\def\MPinclusions[#1]#:#*#=#:#*#=%
  {\let\m_meta_saved_instance\currentMPinstance
   \iftok{#1}{+}\else
     \global\t_meta_inclusions\emptytoks
   \fi
   \ifparameter#3\or
     \cdef\currentMPinstance{#2}%
     \ifempty\currentMPinstance
       \let\currentMPinstance\defaultMPinstance
     \fi
     \gtoksapp\t_meta_inclusions{#3}%
   \else
     \let\currentMPinstance\defaultMPinstance
     \gtoksapp\t_meta_inclusions{#2}%
   \fi
   \let\currentMPinstance\m_meta_saved_instance}

% so far

\installcommandhandler \??mpinstance {MPinstance} \??mpinstance

\setupMPinstance
  [\s!format=metafun,
   \s!extensions=\v!no,
   \s!initializations=\v!no,
   \c!method=\s!default,
   \c!textstyle=,
   \c!textcolor=]

\appendtoks
    \ifcsname\??mpdefinitions\currentMPinstance\endcsname \else
      \expandafter\newtoks\csname\??mpdefinitions\currentMPinstance\endcsname
    \fi
    \ifcsname\??mpinclusions\currentMPinstance\endcsname \else
      \expandafter\newtoks\csname\??mpinclusions\currentMPinstance\endcsname
    \fi
    \t_meta_definitions\emptytoks % in case we redefine
    \t_meta_inclusions \emptytoks % in case we redefine
\to \everydefineMPinstance

% \permanent\protected\def\resetMPinstance[#1]%
%   {\writestatus\m!metapost{reset will be implemented when needed}}

\def\meta_analyze_graphicname[#1]%
  {\expanded{\meta_analyze_graphicname_indeed[#1::::]}}

\def\meta_show_properties_indeed
  {\writestatus{metapost}{name: \currentMPgraphicname, instance: \currentMPinstance, format: \currentMPformat}}

\let\meta_show_properties\donothing

\installtextracker
  {metapost.properties}
  {\let\meta_show_properties\meta_show_properties_indeed}
  {\let\meta_show_properties\donothing}

\protected\def\meta_analyze_graphicname_indeed[#1::#2::#3]% instance ::
  {\cdef\currentMPgraphicname{#2}%
   \ifempty\currentMPgraphicname
     \cdef\currentMPgraphicname{#1}%
     \let\currentMPinstance\defaultMPinstance
   \orelse\ifcsname\??mpdefinitions#1\endcsname
     \cdef\currentMPinstance{#1}%
   \else
     \let\currentMPinstance\defaultMPinstance
   \fi
   \cdef\currentMPformat{\MPinstanceparameter\s!format}%
   \meta_show_properties}

\mutable\def\currentMPgraphicname{\s!unknown}
\mutable\def\currentMPinstance   {\defaultMPinstance}
\mutable\def\currentMPformat     {\currentMPinstance}

\defineMPinstance[metafun]    [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double]
\defineMPinstance[minifun]    [\s!format=minifun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double]
\defineMPinstance[extrafun]   [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double]
\defineMPinstance[lessfun]    [\s!format=metafun]
\defineMPinstance[scaledfun]  [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!scaled]
\defineMPinstance[doublefun]  [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double]
\defineMPinstance[binaryfun]  [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!binary]
\defineMPinstance[decimalfun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!decimal]
\defineMPinstance[positfun]   [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!posit]

\defineMPinstance[mprun]      [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes]

\defineMPinstance[metapost]   [\s!format=mpost]
\defineMPinstance[nofun]      [\s!format=mpost]
\defineMPinstance[scaledpost] [\s!format=mpost,\c!method=\s!scaled]
\defineMPinstance[doublepost] [\s!format=mpost,\c!method=\s!double]
\defineMPinstance[binarypost] [\s!format=mpost,\c!method=\s!binary]
\defineMPinstance[decimalpost][\s!format=mpost,\c!method=\s!decimal]

\defineMPinstance[simplefun]  [\s!format=metafun,\c!method=\s!double] % maybe use minifun

%defineMPinstance[megapost]   [\s!format=mpost,\c!method=\s!decimal]

\newconditional\c_meta_include_initializations

\def\meta_begin_graphic_group#1%
  {\begingroup
   \meta_analyze_graphicname[#1]}

\def\meta_end_graphic_group
  {\endgroup}

\mutable\def\MPaskedfigure{false}

\def\meta_flush_current_initializations
  {\ifconditional\c_meta_include_initializations
     \the\t_meta_initializations
   \fi}

\def\meta_flush_current_inclusions
  {\the\t_meta_inclusions}

\def\meta_flush_current_definitions
  {\the\t_meta_definitions}

\def\meta_start_current_graphic
  {\begingroup
   \meta_enable_include
   \expand\everyMPgraphic
   \edef\p_initializations{\MPinstanceparameter\s!initializations}%
   \ifx\p_initializations\v!yes
     \c_meta_include_initializations\conditionaltrue
   \else
     \c_meta_include_initializations\conditionalfalse
   \fi
   \edef\p_setups{\MPinstanceparameter\c!setups}%
   \ifempty\p_setups \else
     \setups[\p_setups]%
   \fi
   \useMPinstancestyleparameter\c!textstyle}

\def\meta_set_current_color
  {\useMPinstancecolorparameter\c!textcolor}

\def\meta_stop_current_graphic
  {\global\t_meta_definitions\emptytoks
   \global\t_meta_inclusions\emptytoks
   \endgroup}

\let\meta_relocate_graphic\relax % experimental hook

% \def\meta_process_graphic_start
%   {\pushMPboundingbox
%    \dostarttaggednodetail\t!mpgraphic
%    \setbox\b_meta_graphic\hpack\bgroup
%      % We now make everything an artifact because it's not worth the trouble to
%      % deal with nested text .. it will not be properly dealt with in viewers
%      % either so why bother mixing content and artifacts.
%      \dotaggedplaceholder
%      \dostartignoretagging\empty}

% \def\meta_process_graphic_stop
%   {\dostopignoretagging
%    \egroup
%    \meta_place_graphic
%    \meta_relocate_graphic
%    \dostoptagged
%    \popMPboundingbox}

\aliased\lettonothing\dotagmpgraphic

\def\meta_process_graphic_start_normal
  {\pushMPboundingbox
   \setbox\b_meta_graphic\hpack\bgroup}

\def\meta_process_graphic_stop_normal
  {\egroup
   \meta_place_graphic
   \meta_relocate_graphic
   \popMPboundingbox}

\def\meta_process_graphic_start_tagged
  {\pushMPboundingbox
   \dostarttaggednodetail\t!mpgraphic
   % only if exporting or tagging / a real nasty bit fo code as we can work inner out
   \enforced\edef\figuredescriptiontext{\mplevelparameter\c!descriptiontext}% directly use this
   \enforced\edef\figurealternativetext{\mplevelparameter\c!alternativetext}% directly use this
   \ifconditional\c_grph_in_image
     % set description if to yet set
     \dotagfigure
   \else
     \dotagmpgraphic % so it will be faster then
   \fi
   % We use image id 3 but then also check need to check the export!
   \setbox\b_meta_graphic\hpack attr \imageattribute \plusthree\bgroup
     % We now make everything an artifact because it's not worth the trouble to
     % deal with nested text .. it will not be properly dealt with in viewers
     % either so why bother mixing content and artifacts.
       \dotaggedplaceholder
       \dostartignoretagging\empty
     % We also need to prevent that there are annotations that then have no
     % pointer to what what into tagged, unless we then point to the whole.
     % \locationfalse % better not
   }

\def\meta_process_graphic_stop_tagged
  {\dostopignoretagging
   \egroup
   \meta_place_graphic
   \meta_relocate_graphic
   \dostoptagged
   \popMPboundingbox}

% we can alias in the tag enabler

\def\meta_process_graphic_start
  {\ifconditional\c_strc_tags_enabled
     \meta_process_graphic_start_tagged
   \else
     \meta_process_graphic_start_normal
   \fi}

\def\meta_process_graphic_stop
  {\ifconditional\c_strc_tags_enabled
     \meta_process_graphic_stop_tagged
   \else
     \meta_process_graphic_stop_normal
   \fi}

\protected\def\meta_process_graphic_instance#1#2% used in startMPpage
  {\cdef\currentMPinstance{#1}%
   \ifempty\currentMPinstance
     \let\currentMPinstance\defaultMPinstance
   \fi
   \setmpcategoryparameter\c!stacking{#2}%
   \cdef\currentMPformat{\MPinstanceparameter\s!format}%
   \meta_process_graphic}

\protected\def\meta_process_graphic#1% todo: extensions and inclusions outside beginfig
  {\meta_start_current_graphic
   \forgetall
   \meta_process_graphic_start
     \expanded{\noexpand\clf_mpgraphic
         instance        {\currentMPinstance}%
         format          {\currentMPformat}%
         data            {#1;}%
         initializations {\meta_flush_current_initializations}%
    \ifcstok{\MPinstanceparameter\s!extensions}\v!yes
         extensions      {\clf_getmpextensions{\currentMPinstance}}% goes through tex again, can be done better now
    \fi
         inclusions      {\meta_flush_current_inclusions}%
         definitions     {\meta_flush_current_definitions}%
         figure          {\MPaskedfigure}%
         filtering       {\mpcategoryparameter\c!stacking}
         method          {\MPinstanceparameter\c!method}%
         namespace       {\??graphicvariable\currentmpcategory:}%
    \relax}%
   \meta_process_graphic_stop
   \meta_stop_current_graphic}

\let\meta_process_graphic_figure_start\relax
\let\meta_process_graphic_figure_stop \relax

\let\normal_meta_process_graphic_start\relax
\let\normal_meta_process_graphic_stop \relax

\permanent\protected\def\processMPfigurefile#1% special case: obeys beginfig .. endfig and makes pages
  {\begingroup
   \let\normal_meta_process_graphic_start\meta_process_graphic_start
   \let\normal_meta_process_graphic_stop \meta_process_graphic_stop
   \let\meta_process_graphic_start\relax
   \let\meta_process_graphic_stop \relax
   \def\meta_process_graphic_figure_start{\startTEXpage[\c!offset=\v!overlay,\c!align=]\normal_meta_process_graphic_start}%
   \def\meta_process_graphic_figure_stop {\normal_meta_process_graphic_stop\stopTEXpage}
   \def\MPaskedfigure{all}%
   \meta_process_graphic{input "#1" ;}%
   \endgroup}

%D Calling up previously defined graphics.

% \def\includeMPgraphic#1% gets expanded !
%   {\ifcsname\??mpgraphic#1\endcsname
%      \csname\??mpgraphic#1\endcsname ; % ; is safeguard
%    \fi}
%
% \protected\def\meta_enable_include % public
%   {\let\meta_handle_use_graphic     \thirdofthreearguments
%    \let\meta_handle_reusable_graphic\thirdofthreearguments}
%
% but ... we want this too:
%
% \startuseMPgraphic{x}
%     draw textext("\externalfigure[foo.pdf]") ;
% \stopuseMPgraphic
%
% \useMPgraphic{x}
%
% so we cannot overload unless we let back to the original meanings each graphic
% ... a better solution is:

\permanent\def\includeMPgraphic#1% gets expanded !
  {\ifcsname\??mpgraphic#1\endcsname
     \doubleexpandafter\fourthoffourarguments\lastnamedcs ; % ; is safeguard
   \fi}

\let\meta_enable_include\relax

%D Drawings (stepwise built):

\newif\ifMPdrawingdone \MPdrawingdonefalse

\permanent\protected\def\finalizeMPdrawing
  {\MPdrawingdonetrue}

\mutable\lettonothing\MPdrawingdata

\permanent\protected\def\resetMPdrawing
  {\glettonothing\MPdrawingdata
   \global\MPdrawingdonefalse}

\permanent\protected\def\pushMPdrawing
  {\globalpushmacro\MPdrawingdata
   \glettonothing\MPdrawingdata}

\permanent\protected\def\popMPdrawing
  {\globalpopmacro\MPdrawingdata}

\permanent\protected\def\getMPdrawing
  {\ifMPdrawingdone
     \expandafter\meta_process_graphic\expandafter{\MPdrawingdata}% is this expansion still needed?
   \fi}

\permanent\tolerant\def\startMPdrawing[#1]% todo: use pickup #:
  {\meta_start_drawing{#1}}

\def\meta_start_drawing#1#2\stopMPdrawing
  {\relax
   \bgroup
   \meta_enable_include
   % can be a one liner:
   \iftok{#1}{-}%
     \xdef\MPdrawingdata{\MPdrawingdata\detokenize{#2}}%
   \else
     \xdef\MPdrawingdata{\MPdrawingdata#2}%
   \fi
   \egroup}

\permanent\protected\lettonothing\stopMPdrawing

\permanent\def\MPdrawing#1%
  {\relax
   \bgroup
   \meta_enable_include
   \xdef\MPdrawingdata{\MPdrawingdata#1}%
   \egroup}

\permanent\protected\def\startMPclip#1#2\stopMPclip % todo: store at the lua end or just store less
  {\gdefcsname\??mpclip#1\endcsname{#2}}

\permanent\protected\lettonothing\stopMPclip

\mutable\def\width {0 } % left-over, obsolete
\mutable\def\height{0 } % left-over, obsolete

\mutable\lettonothing\currentMPclip

\protected\def\meta_grab_clip_path#1#2#3%
  {\begingroup
   \d_overlay_width #2\relax
   \d_overlay_height#3\relax
   \edef\width {\the\d_overlay_width \space}% obsolete
   \edef\height{\the\d_overlay_height\space}% obsolete
   \cdef\currentMPclip{#1}%
   \ifcsname\??mpclip\currentMPclip\endcsname
     \meta_grab_clip_path_yes
   \else
     \meta_grab_clip_path_nop
   \fi
   \endgroup}

\def\meta_grab_clip_path_yes
  {\meta_start_current_graphic
     \expanded{\noexpand\clf_mpsetclippath
       instance        {\currentMPinstance}%
       format          {\currentMPformat}%
       data            {\begincsname\??mpclip\currentMPclip\endcsname}%
       initializations {\meta_flush_current_initializations}%
       useextensions   {\MPinstanceparameter\s!extensions}%
       inclusions      {\meta_flush_current_inclusions}%
       method          {\MPinstanceparameter\c!method}%
       width           \d_overlay_width
       height          \d_overlay_height
     \relax}%
   \meta_stop_current_graphic}

\def\meta_grab_clip_path_nop
  {\clf_mpsetclippath
     width  \d_overlay_width
     height \d_overlay_height
   \relax}

%D Since we want labels to follow the document settings, we also set the font
%D related variables.

\permanent\protected\def\MPfontsizehskip#1%
  {\dontleavehmode
   \begingroup
   \definedfont[#1]%
   \hskip\clf_currentdesignsize\scaledpoint\relax
   \endgroup}

\definefontsynonym[MetafunDefault][Regular*default]

\startMPinitializations % scale is not yet ok
    defaultfont:="\truefontname{MetafunDefault}";
  % defaultscale:=\the\bodyfontsize/10pt; % only when hard coded 10pt
  % defaultscale:=1;
\stopMPinitializations

%D A signal that we're in combined \CONTEXT||\METAFUN mode:

\startMPextensions
    string contextversion;contextversion:="\contextversion"; % expanded
\stopMPextensions

%D \macros
%D   {setupMPvariables}
%D
%D When we build collections of \METAPOST\ graphics, like background and buttons,
%D the need for passing settings arises. By (mis|)|using the local prefix that
%D belongs to \type {\framed}, we get a rather natural interface to backgrounds. To
%D prevent conflicts, we will use the \type {-} in \METAPOST\ specific variables,
%D like:
%D
%D \starttyping
%D \setupMPvariables[meta:button][size=20pt]
%D \stoptyping

% \lineheight  2pt  2  \scratchcounter  red  0.4  .5\bodyfontsize
%
% see cont-loc for test code

%D Currently the inheritance of backgrounds does not work and we might drop it
%D anyway (too messy)

\lettonothing\m_meta_current_variable

\installbasicnativeautosetuphandler \??mpcategory {mpcategory}

\permanent\tolerant\protected\def\useMPvariables[#1]#*[#2]{} % no longer needed

%D The uppercase ones are the official ones:

\aliased\let\setupMPvariables\setupmpcategory
\aliased\let\setMPvariables  \setupmpcategory

\def\meta_mpvar_default{\MPcolor{black}\space}
%def\meta_mpvar_default{0 }

\installmacrostack\currentmpcategory

\permanent\def\MPvar#1% todo: could be a framed chain
  {\beginlocalcontrol
   \edef\m_meta_current_variable{\mpcategoryparameter{#1}}%
   % new:
   \ifempty\m_meta_current_variable
     \push_macro_currentmpcategory
     \let\currentmpcategory\currentMPgraphicname
     \edef\m_meta_current_variable{\mpcategoryparameter{#1}}%
     \pop_macro_currentmpcategory
   \fi
   %
   \endlocalcontrol
   \ifempty\m_meta_current_variable
     \meta_mpvar_default
   \orelse\ifchkdimension\m_meta_current_variable\or
     \todimension\lastchkdimension\space\space
 % \orelse\ifchknum\m_meta_current_variable\or % we need to catch 1>2
   \orunless\ifempty{\ifchknum\m_meta_current_variable\or\tointeger\m_meta_current_variable\fi}%
     \tointeger\m_meta_current_variable\space\space % maybe \lastchkinteger
   \orelse\ifcsname\??colorattribute\currentcolorprefix\m_meta_current_variable\endcsname
     \MPcolor\m_meta_current_variable\space
   \orelse\ifcsname\??colorattribute\m_meta_current_variable\endcsname
     \MPcolor\m_meta_current_variable\space
   \else
     \m_meta_current_variable
   \fi}

\permanent\def\MPrawvar#1#2% todo: could be a framed chain
  {\beginlocalcontrol
   \edef\m_meta_current_variable{\namedmpcategoryparameter{#1}{#2}}%
   % new
 % \ifempty\m_meta_current_variable
 %   \push_macro_currentmpcategory
 %   \let\currentmpcategory\currentMPgraphicname
 %   \edef\m_meta_current_variable{\namedmpcategoryparameter{#1}{#2}}%
 %   \pop_macro_ currentmpcategory
 % \fi
   %
   \endlocalcontrol
   \ifempty\m_meta_current_variable
     \meta_mpvar_default
   \orelse\ifchkdim\m_meta_current_variable\or
     \todimension\m_meta_current_variable\space\space
 % \orelse\ifchknum\m_meta_current_variable\or % we need to catch 1>2
   \orunless\ifempty{\ifchknum\m_meta_current_variable\or\tointeger\m_meta_current_variable\fi}%
     \tointeger\m_meta_current_variable\space\space
   \orelse\ifcsname\??colorattribute\currentcolorprefix\m_meta_current_variable\endcsname
     \MPcolor\m_meta_current_variable\space
   \orelse\ifcsname\??colorattribute\m_meta_current_variable\endcsname
     \MPcolor\m_meta_current_variable\space
   \else
     \m_meta_current_variable
   \fi}

\aliased\let\MPvariable\MPvar

%D \macros
%D   {startuniqueMPgraphic, uniqueMPgraphic}
%D
%D This macros is probably of most use to myself, since I like to use graphics that
%D adapt themselves. The next \METAPOST\ kind of graphic is both unique and reused
%D when possible.
%D
%D \starttyping
%D \defineoverlay[example][\uniqueMPgraphic{test}]
%D
%D \startuniqueMPgraphic {test}
%D   draw OverlayBox ;
%D \stopuniqueMPgraphic
%D
%D \startuniqueMPgraphic {test}
%D   draw OverlayBox ;
%D \stopuniqueMPgraphic
%D \stoptyping

% todo: frozen or not?

\permanent\def\overlaystamp % watch the \MPcolor, since colors can be redefined
  {\the\d_overlay_width    :%
   \the\d_overlay_height   :%
   \the\d_overlay_depth    :%
   \the\d_overlay_offset   :%
   \the\d_overlay_linewidth:%
   \MPcolor\overlaycolor   :%  % todo, expand once \m_overlaycolor
   \MPcolor\overlaylinecolor}  % todo, expand once \m_overlaylinecolor

%D A better approach is to let additional variables play a role in determining the
%D uniqueness. In the next macro, the second, optional, argument is used to
%D guarantee the uniqueness, as well as prepare variables for passing them to
%D \METAPOST.
%D
%D \starttyping
%D \startuniqueMPgraphic{meta:hash}{gap,angle,...}
%D \stoptyping
%D
%D The calling macro also accepts a second argument. For convenient use in overlay
%D definitions, we use \type {{}} instead of \type {[]}.
%D
%D \starttyping
%D \uniqueMPgraphic{meta:hash}{gap=10pt,angle=30}
%D \stoptyping

\newinteger\c_meta_object_counter
\newbox    \b_meta_graphic

% hm, isn't this already done elsewhere?

\protected\def\meta_obey_box_depth
  {\setbox\b_meta_graphic\hpack\bgroup
     \raise\MPlly\box\b_meta_graphic
   \egroup}

\protected\def\meta_ignore_box_depth
  {\expanded
     {\meta_obey_box_depth % hence the \protected
      \wd\b_meta_graphic\the\wd\b_meta_graphic
      \ht\b_meta_graphic\the\ht\b_meta_graphic
      \dp\b_meta_graphic\the\dp\b_meta_graphic}}

\protected\def\meta_obey_box_origin
  {\setbox\b_meta_graphic\hpack\bgroup
     \kern\MPllx\raise\MPlly\box\b_meta_graphic
   \egroup}

\permanent\protected\def\obeyMPboxdepth  {\let\meta_relocate_box\meta_obey_box_depth}
\permanent\protected\def\ignoreMPboxdepth{\let\meta_relocate_box\meta_ignore_box_depth}
\permanent\protected\def\obeyMPboxorigin {\let\meta_relocate_box\meta_obey_box_origin}
\permanent\protected\def\normalMPboxdepth{\let\meta_relocate_box\relax}

\let\meta_relocate_box\relax

\protected\def\meta_place_graphic % the converter also displaces so in fact we revert
  {\meta_relocate_box
   \box\b_meta_graphic}

% \protected\def\meta_reuse_box#1#2#3#4#5% space delimiting would save some tokens
%   {\MPllx#2\MPlly#3\MPurx#4\MPury#5%
%    \hpack container{\forcecolorhack\getobject{MP}{#1}}} % else no proper color intent

\protected\def\meta_reuse_box#1#2#3#4#5% space delimiting would save some tokens
  {\MPllx#2\MPlly#3\MPurx#4\MPury#5%
   \hpack container{\getobject{MP}{#1}}}

\protected\def\meta_use_box
  {\setunreferencedobject{MP}}

\def\meta_handle_unique_graphic#1#2#3% when there are too many, we can store data at the lua end, although,
  {\begingroup                       % when there are that many they're probably not that unique anyway
 % \currentmpcategory already set
   \extendMPoverlaystamp{#2}% incl prepare (maybe move to lua)
   \ifcsname\??mpgraphic\overlaystamp:#1\endcsname % todo: is now per instance !
     \lastnamedcs
   \else
     \meta_enable_include % redundant
     \global\advanceby\c_meta_object_counter\plusone
     \meta_use_box{\the\c_meta_object_counter}\hpack{\meta_process_graphic{#3}}% was vbox, graphic must end up as hbox
     \xdefcsname\??mpgraphic\overlaystamp:#1\endcsname{\meta_reuse_box{\the\c_meta_object_counter}{\the\MPllx}{\the\MPlly}{\the\MPurx}{\the\MPury}}%
     \csname\??mpgraphic\overlaystamp:#1\endcsname\empty
   \fi
   \endgroup}

% todo: we partially expand

\permanent\protected\def\startuniqueMPgraphic
  {\dodoublegroupempty\meta_start_unique_graphic}

\permanent\protected\lettonothing\stopuniqueMPgraphic

\def\meta_start_unique_graphic#1%
  {\expanded{\meta_start_unique_graphic_indeed{#1}}}

\permanent\protected\def\meta_start_unique_graphic_indeed#1#2#3\stopuniqueMPgraphic
  {\gdefcsname\??mpgraphic#1\endcsname{\meta_handle_unique_graphic{#1}{#2}{#3}}}

% \permanent\tolerant\protected\def\uniqueMPgraphic#=#*#=%
%   {\meta_begin_graphic_group{#1}%
%    \checkmpcategoryparent
%    \let\currentmpcategory\currentMPgraphicname
%    \setupcurrentmpcategory[#2]%
%    \begincsname\??mpgraphic#1\endcsname\empty
%    \meta_end_graphic_group}

\permanent\tolerant\protected\def\uniqueMPgraphic
  {\futureexpandis[\meta_uniquempgraphic_yes\meta_uniquempgraphic_nop}

\def\meta_uniquempgraphic_yes[#1]#*#=%
  {% ugly code but we run on top of older code
%    \resetdummyparameter\c!instance
%    \getdummyparameters[#1]%
%    \cdef\currentMPinstance{\dummyparameter\c!instance}%
   %
   \meta_bump_current_level
   \setupcurrentmplevel[#1]%
   \cdef\currentMPinstance{\mplevelparameter\c!instance}%
   %
   % here we feed the instance into the analyzer
   \meta_begin_graphic_group{\ifempty\currentMPinstance\else\currentMPinstance::\fi#1}%
   \checkmpcategoryparent
   \let\currentmpcategory\currentMPgraphicname
   \setupcurrentmpcategory[#1]%
   \begincsname\??mpgraphic#2\endcsname\empty
   \meta_end_graphic_group}

\tolerant\def\meta_uniquempgraphic_nop#=#*#=%
  {\meta_begin_graphic_group{#1}%
   \checkmpcategoryparent
   \let\currentmpcategory\currentMPgraphicname
   \setupcurrentmpcategory[#2]%
   \begincsname\??mpgraphic#1\endcsname\empty
   \meta_end_graphic_group}

\def\meta_handle_use_graphic#1#2#3%
  {\begingroup
 % \currentmpcategory already set
   \meta_enable_include % redundant
   \meta_process_graphic{#3}%
   \endgroup}

\permanent\protected\def\startuseMPgraphic
  {\dodoublegroupempty\meta_start_use_graphic}

\permanent\protected\lettonothing\stopuseMPgraphic

\def\meta_start_use_graphic#1%
  {\expanded{\meta_start_use_graphic_indeed{#1}}}

\protected\def\meta_start_use_graphic_indeed#1#2#3\stopuseMPgraphic
  {\gdefcsname\??mpgraphic#1\endcsname{\meta_handle_use_graphic{#1}{#2}{#3}}}

\permanent\protected\def\startusableMPgraphic
  {\dodoublegroupempty\meta_start_usable_graphic}

\permanent\protected\lettonothing\stopusableMPgraphic

\def\meta_start_usable_graphic#1%
  {\expanded{\meta_start_usable_graphic_indeed{#1}}}

\protected\def\meta_start_usable_graphic_indeed#1#2#3\stopusableMPgraphic
  {\gdefcsname\??mpgraphic#1\endcsname{\meta_handle_use_graphic{#1}{#2}{#3}}}

\def\meta_handle_reusable_graphic#1#2#3%
  {\begingroup
 % \currentmpcategory already set
   \meta_enable_include % redundant
   \global\advanceby\c_meta_object_counter\plusone
   \meta_use_box{\the\c_meta_object_counter}\hpack{\meta_process_graphic{#3}}% was vbox, graphic must end up as hbox
   \xdefcsname\??mpgraphic#1\endcsname{\meta_reuse_box{\the\c_meta_object_counter}{\the\MPllx}{\the\MPlly}{\the\MPurx}{\the\MPury}}%
   \csname\??mpgraphic#1\endcsname\empty
   \endgroup}

\permanent\protected\def\startreusableMPgraphic
  {\dodoublegroupempty\meta_start_reusable_graphic}

\permanent\protected\lettonothing\stopreusableMPgraphic

\def\meta_start_reusable_graphic#1%
  {\expanded{\meta_start_reusable_graphic_indeed{#1}}}

\protected\def\meta_start_reusable_graphic_indeed#1#2#3\stopreusableMPgraphic
  {\gdefcsname\??mpgraphic#1\endcsname{\meta_handle_reusable_graphic{#1}{#2}{#3}}}

\permanent\tolerant\protected\def\useMPgraphic
  {\futureexpandis[\meta_usempgraphic_yes\meta_usempgraphic_nop}

\def\meta_usempgraphic_yes[#1]#*#=%
  {% ugly code but we run on top of older code
%    \resetdummyparameter\c!instance
%    \getdummyparameters[#1]%
%    \cdef\currentMPinstance{\dummyparameter\c!instance}%
   %
   \meta_bump_current_level
   \setupcurrentmplevel[#1]%
   \cdef\currentMPinstance{\mplevelparameter\c!instance}%
   %
   % here we feed the instance into the analyzer
   \meta_begin_graphic_group{\ifempty\currentMPinstance\else\currentMPinstance::\fi#2}%
   \ifcsname\??mpgraphic#2\endcsname
     \cdef\currentmpcategory{#2}%
   \orelse\ifcsname\??mpgraphic\currentMPgraphicname\endcsname
     \let\currentmpcategory\currentMPgraphicname
   \else
     \lettonothing\currentmpcategory
   \fi
   \ifempty\currentmpcategory
     % message
   \else
     \checkmpcategoryparent
     \setupcurrentmpcategory[#1]%
     \csname\??mpgraphic\currentmpcategory\endcsname
   \fi
   \meta_end_graphic_group}

\tolerant\def\meta_usempgraphic_nop#=#*#=%
  {\meta_begin_graphic_group{#1}%
   \ifcsname\??mpgraphic#1\endcsname
     \cdef\currentmpcategory{#1}%
   \orelse\ifcsname\??mpgraphic\currentMPgraphicname\endcsname
     \let\currentmpcategory\currentMPgraphicname
   \else
     \lettonothing\currentmpcategory
   \fi
   \ifempty\currentmpcategory
     % message
   \else
     \checkmpcategoryparent
     \ifempty{#2}\else
       \setupcurrentmpcategory[#2]%
     \fi
     \csname\??mpgraphic\currentmpcategory\endcsname
   \fi
   \meta_end_graphic_group}

\aliased\let\reuseMPgraphic   \useMPgraphic   % we can save a setup here if needed
\aliased\let\reusableMPgraphic\reuseMPgraphic % we can save a setup here if needed

%D Saves an overlaydefinition:

\permanent\protected\def\startoverlayMPgraphic
  {\dodoublegroupempty\meta_start_overlay_graphic}

\permanent\protected\lettonothing\stopoverlayMPgraphic

\def\meta_start_overlay_graphic#1%
  {\expanded{%
     \pack_overlay_define{#1}{\useMPgraphic{#1}}%
     \meta_start_overlay_graphic_indeed{#1}}%
   }

\protected\def\meta_start_overlay_graphic_indeed#1#2#3\stopoverlayMPgraphic
  {\gdefcsname\??mpgraphic#1\endcsname{\meta_handle_overlay_graphic{#1}{#2}{#3}}}

\def\meta_handle_overlay_graphic#1#2#3%
  {\begingroup
   \cdef\currentmpcategory{#1}%
   \meta_process_graphic{#3;BoundToOverlayBox;}%
   \endgroup}

%D New in \LMTX:

\newtoks\MPoverlaydata

\permanent\protected\lettonothing\stopMPoverlaydata

\permanent\protected\def\startMPoverlaydata
  {\iftrialtypesetting
     \expandafter\startMPoverlaydata_nop
   \else
     \expandafter\startMPoverlaydata_yes
   \fi}

\permanent\protected\def\startMPoverlaydata_nop#-\stopMPoverlaydata
  {}

\permanent\protected\def\startMPoverlaydata_yes#1\stopMPoverlaydata
  {\xtoksapp\MPoverlaydata{#1;}}

\def\includeMPoverlaydata % expandable
  {\the\MPoverlaydata
   \resetMPoverlaydata}

\def\resetMPoverlaydata % expandable
  {\localcontrolled{\global\MPoverlaydata\emptytoks}}


%D \macros
%D   {startuniqueMPpagegraphic,uniqueMPpagegraphic}
%D
%D Experimental.

\def\m_meta_page_prefix{\doifelseoddpage oe}

\permanent\def\overlaypagestamp
  {\m_meta_page_prefix     :%
   \the\d_overlay_width    :%
   \the\d_overlay_height   :%
   \the\d_overlay_depth    :%
   \the\d_overlay_offset   :%
   \the\d_overlay_linewidth:%
   \MPcolor\overlaycolor   :%
   \MPcolor\overlaylinecolor}

\permanent\tolerant\protected\def\startuniqueMPpagegraphic % todo the modern way
  {\dodoublegroupempty\meta_start_unique_page_graphic}

\permanent\protected\lettonothing\stopuniqueMPpagegraphic

\def\meta_start_unique_page_graphic#1%
  {\expanded{\meta_start_unique_page_graphic_indeed{#1}}}

\protected\def\meta_start_unique_page_graphic_indeed#1#2#3\stopuniqueMPpagegraphic    % inefficient, double storage
  {\gdefcsname\??mpgraphic o:#1\endcsname{\meta_handle_unique_graphic{o:#1}{#2}{#3}}% % but these also keep the state
   \gdefcsname\??mpgraphic e:#1\endcsname{\meta_handle_unique_graphic{e:#1}{#2}{#3}}} % and meaning will be redefined

\permanent\tolerant\protected\def\uniqueMPpagegraphic#=#=%
  {\meta_begin_graphic_group{#1}%
   \enforced\let\overlaystamp\overlaypagestamp
   \setupmpcategory[\m_meta_page_prefix:#1][#2]% prefix is new here
   \csname\??mpgraphic\m_meta_page_prefix:#1\endcsname\empty
   \meta_end_graphic_group}

\permanent\protected\def\extendMPoverlaystamp#1%
  {\processcommalist[#1]\meta_extend_overlay_stamp}

\def\meta_extend_overlay_stamp#1%
  {\enforced\permanent\edef\overlaystamp{\overlaystamp:\MPvariable{#1}}}

% \getMPdata % define at the lua end
% \rawMPdata % define at the lua end

%D We need this trick because we need to make sure that the tex scanner sees
%D newlines and does not quit. Also, we do need to flush the buffer under a normal
%D catcode regime in order to expand embedded tex macros. As usual with buffers,
%D \type {#1} can be a list.

\permanent\tolerant\protected\def\processMPbuffer[#1]%
  {\meta_begin_graphic_group{#1}%
   \meta_process_graphic{\clf_feedback{\currentMPgraphicname}}%
   \meta_end_graphic_group}

\permanent\tolerant\protected\def\runMPbuffer[#1]%
  {\startnointerference\processMPbuffer[#1]\stopnointerference}

%D \macros
%D   {startMPenvironment, resetMPenvironment}
%D
%D In order to synchronize the main \TEX\ run and the runs local to \METAPOST,
%D environments can be passed.

\permanent\protected\def\startMPenvironment
  {\begingroup
   \catcode\endoflineasciicode\ignorecatcode
   \meta_start_environment}

\lettonothing\m_meta_option

\tolerant\def\meta_start_environment[#1]#:#2\stopMPenvironment
  {\endgroup
   \edef\m_meta_option{#1}
   \ifx\m_meta_option\s!reset
     \resetMPenvironment % reset mp toks
   \orelse\ifx\m_meta_option\v!global
     #2%                 % use in main doc too
   \orelse\ifx\m_meta_option\!!plustoken
     #2%                 % use in main doc too
   \fi
   \clf_mptexset{\detokenize{#2}}}

\permanent\protected\lettonothing\stopMPenvironment

\permanent\protected\def\resetMPenvironment
  {\clf_mptexreset}

\permanent\protected\def\useMPenvironmentbuffer[#1]%
  {\clf_mptexsetfrombuffer{#1}}

%D This command takes \type {[reset]} as optional argument.
%D
%D \starttyping
%D \startMPenvironment
%D   \setupbodyfont[pos,14.4pt]
%D \stopMPenvironment
%D
%D \startMPcode
%D   draw btex \sl Hans Hagen etex scaled 5 ;
%D \stopMPcode
%D \stoptyping
%D
%D The most simple case:

% \permanent\tolerant\protected\def\startMPcode#=#:#2\stopMPcode
%   {\begingroup
%    \cdef\currentMPinstance{#1}%
%    \ifempty\currentMPinstance
%      \let\currentMPinstance\defaultMPinstance
%    \fi
%    \lettonothing\currentMPgraphicname
%    \cdef\currentMPformat{\MPinstanceparameter\s!format}%
%    \meta_enable_include
%    \meta_process_graphic{#2}%
%    \endgroup}

\permanent\tolerant\protected\def\startMPcode
  {\futureexpandis[\meta_start_mpcode_yes\meta_start_mpcode_nop}

\tolerant\def\meta_start_mpcode_nop#:#=#:#2\stopMPcode
  {\begingroup
   \cdef\currentMPinstance{#1}%
   \ifempty\currentMPinstance
     \let\currentMPinstance\defaultMPinstance
   \fi
   \lettonothing\currentMPgraphicname
   \cdef\currentMPformat{\MPinstanceparameter\s!format}%
   \meta_enable_include
   \meta_process_graphic{#2}%
   \endgroup}

\def\meta_start_mpcode_yes[#1]#2\stopMPcode
  {\begingroup
%    \resetdummyparameter\c!instance
%    \resetdummyparameter\c!stacking
%    \getdummyparameters[#1]%
%    \cdef\currentMPinstance{\dummyparameter\c!instance}%
%    \setmpcategoryparameter\c!stacking{\dummyparameter\c!stacking}%
   %
   \meta_bump_current_level
   \setupcurrentmplevel[#1]%
   \cdef\currentMPinstance{\mplevelparameter\c!instance}%
   \setmpcategoryparameter\c!stacking{\mplevelparameter\c!stacking}%
   %
   \ifempty\currentMPinstance
     \let\currentMPinstance\defaultMPinstance
   \fi
   \lettonothing\currentMPgraphicname
   \cdef\currentMPformat{\MPinstanceparameter\s!format}%
   \meta_enable_include
   \meta_process_graphic{#2}%
   \endgroup}

\permanent\protected\lettonothing\stopMPcode

%D This one is not optimized because it's only used for small snippets, if it
%D is used at all.
%D
%D \starttyping
%D test \MPcode {draw unitcircle scaled 1.5ExHeight} test test \MPcode [doublefun]
%D {draw unitcircle scaled 3mm shifted (0,-1mm)} test
%D \stoptyping

\permanent\tolerant\protected\def\MPcode[#1]#:#2%
  {\dontleavehmode
   \begingroup
   \obeyMPboxdepth
   \ifparameter#1\or
     \meta_begin_graphic_group{#1}%
     \meta_enable_include
     \meta_process_graphic{#2}%
     \meta_end_graphic_group
   \else
     \let\currentMPinstance\defaultMPinstance
     \meta_enable_include
     \meta_process_graphic{#2}%
   \fi
   \endgroup}

% a bit nasty (also needed for compatibility:

% \startMPrun input mp-www.mp ; \stopMPrun
% \externalfigure[mprun.3][width=10cm,height=8cm]

% \startMPrun{mprun} input mp-www.mp ; \stopMPrun % instance
% \externalfigure[mprun.4][width=10cm,height=8cm]

\mutable\let\MPruninstance\defaultMPinstance

\permanent\protected\def\useMPrun#1#2% name n
  {\begingroup
   \def\MPaskedfigure{#2}%
   \expanded{\useMPgraphic{\ifempty{#1}mprun\else#1\fi}}%
   \endgroup}

\permanent\tolerant\protected\def\startMPrun#=#:#2\stopMPrun
  {\expanded{\startuseMPgraphic{\ifempty{#1}mprun\else#1\fi}}#2\stopuseMPgraphic}

\permanent\protected\lettonothing\stopMPrun

%D The \type {\resetMPenvironment} is a quick way to erase the token list. You
%D should be aware of independencies. For instance, if you use a font in a graphic
%D that is not used in the main document, you need to load the typescript at the
%D outer level (either directly or by using the global option).
%D
%D \starttyping
%D \usetypescript[palatino][texnansi]
%D
%D \startMPenvironment
%D     \usetypescript[palatino][texnansi]
%D     \enableregime[utf]
%D     \setupbodyfont[palatino]
%D \stopMPenvironment
%D
%D \startMPpage
%D     draw btex aap‒noot coördinatie – één etex ;
%D \stopMPpage
%D \stoptyping

%D Loading specific \METAPOST\ related definitions is accomplished by:

% \permanent\protected\def\useMPlibrary[#1]{\clf_useMPlibrary{#1}}

%D \macros
%D   {setMPtext, MPtext, MPstring, MPbetex}
%D
%D To be documented:
%D
%D \starttyping
%D \setMPtext{identifier}{text}
%D
%D \MPtext  {identifier}
%D \MPstring{identifier}
%D \MPbetex {identifier}
%D \stoptyping

\installcorenamespace{mptext}

\permanent\protected\def\setMPtext#1#2{\edefcsname\??mptext#1\endcsname{\detokenize{#2}}} % \global will work here
\permanent          \def\MPtext     #1{\begincsname\??mptext#1\endcsname\empty}
\permanent          \def\MPstring   #1{"\begincsname\??mptext#1\endcsname\empty"}
\permanent          \def\MPbetex    #1{btex \begincsname\??mptext#1\endcsname\space etex}

%D Another helper:

\installcorenamespace {mplevel}

\installsetuponlycommandhandler \??mplevel {mplevel}

\lettonothing\currentmplevel

\newinteger\c_meta_mp_level

\def\meta_bump_current_level
  {\advanceby\c_meta_mp_level\plusone
   \ifnum\c_meta_mp_level>\plusone
     \cdef\currentmplevel{mp:\the\c_meta_mp_level}%
   \fi}

%D In order to communicate conveniently with the \TEX\ engine, we introduce some
%D typesetting variables.

% \setupcolors[state=stop,conversion=never] % quite tricky ... type mismatch

% \startMPinitializations
%     CurrentLayout:="\currentlayout";
% \stopMPinitializations

%D A dirty trick, ** in colo-ini.lua (mpcolor). We cannot use a vardef, because
%D that fails with spot colors.

% \startMPinitializations
%     def OverlayLineColor=\ifempty\overlaylinecolor black \else\MPcolor{\overlaylinecolor} \fi enddef;
%     def OverlayColor    =\ifempty\overlaycolor     black \else\MPcolor{\overlaycolor}     \fi enddef;
% \stopMPinitializations

\appendtoks
    \disablediscretionaries
   %\disablecompoundcharacters
    %
    \baselineskip1\baselineskip
    \lineheight  1\lineheight
    \topskip     1\topskip
    %
    \enforced\let\#\letterhash
    \enforced\let\_\letterunderscore
    \enforced\let\&\letterampersand
    \enforced\let\{\letteropenbrace
    \enforced\let\}\letterclosebrace
\to \everyMPgraphic

\newtoks\everyinsertMPfile

\startMPextensions
    def initialize_form_numbers =
        do_initialize_numbers;
    enddef;
\stopMPextensions

\startMPextensions
    vardef ForegroundBox =
        unitsquare xysized(HSize,VSize)
    enddef ;
\stopMPextensions

\startMPdefinitions {metapost}
    if unknown context_bare : input mp-bare.mpiv ; fi ;
\stopMPdefinitions
\startMPdefinitions {binarypost}
    if unknown context_bare : input mp-bare.mpiv ; fi ;
\stopMPdefinitions
\startMPdefinitions {decimalpost}
    if unknown context_bare : input mp-bare.mpiv ; fi ;
\stopMPdefinitions
\startMPdefinitions {doublepost}
    if unknown context_bare : input mp-bare.mpiv ; fi ;
\stopMPdefinitions

% \startMPdefinitions {nofun}
%     if unknown context_bare : input mp-bare.mpiv ; fi ;
% \stopMPdefinitions

%D And some more. These are not really needed since we don't use the normal figure
%D inclusion macros any longer.

\appendtoks
    \externalfigurepostprocessors\emptytoks % safeguard
\to \everyinsertMPfile

%D We also take care of disabling fancy figure features, that can terribly interfere
%D when dealing with symbols, background graphics and running (postponed) graphics.
%D You won't believe me if I tell you what funny side effects can occur. One took me
%D over a day to uncover when processing the screen version of the \METAFUN\ manual.

\permanent\def\doifelseMPgraphic#1%
  {\ifcsname\??mpgraphic   #1\endcsname\expandafter\firstoftwoarguments \orelse
   \ifcsname\??mpgraphic o:#1\endcsname\expandafter\firstoftwoarguments \orelse
   \ifcsname\??mpgraphic e:#1\endcsname\expandafter\firstoftwoarguments \else
                                       \expandafter\secondoftwoarguments\fi}

\aliased\let\doifMPgraphicelse\doifelseMPgraphic

%D New:

\definelayerpreset % no dx,dy - else nasty non-mp placement
  [mp]
  [\c!y=-\MPury,
   \c!x=\MPllx,
   \c!method=\v!fit]

\definelayer
  [mp]
  [\c!preset=mp]

%D Usage:
%D
%D \starttyping
%D \defineviewerlayer[one][state=start]
%D \defineviewerlayer[two][state=stop]
%D
%D \startuseMPgraphic{step-1}
%D   fill fullcircle scaled 10cm withcolor red ;
%D \stopuseMPgraphic
%D
%D \startuseMPgraphic{step-2}
%D   fill fullcircle scaled 5cm withcolor green ;
%D \stopuseMPgraphic
%D
%D \setlayer[mp]{\viewerlayer[one]{\useMPgraphic{step-1}}}
%D \setlayer[mp]{\viewerlayer[two]{\useMPgraphic{step-2}}}
%D
%D \ruledhbox{\flushlayer[mp]}
%D \stoptyping
%D
%D Reusing graphics is also possible (now):
%D
%D \starttyping
%D \startreusableMPgraphic{axis}
%D   tickstep := 1cm ; ticklength := 2mm ;
%D   drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
%D   tickstep := tickstep/2 ; ticklength := ticklength/2 ;
%D   drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
%D \stopreusableMPgraphic
%D
%D \startuseMPgraphic{demo}
%D   drawpoint "1cm,1.5cm" ;
%D \stopuseMPgraphic
%D
%D \definelayer[mp][preset=mp]
%D \setlayer[mp]{\reuseMPgraphic{axis}}
%D \setlayer[mp]{\useMPgraphic{demo}}
%D \ruledhbox{\flushlayer[mp]}
%D \stoptyping

%D \macros
%D   {startstaticMPfigure,useMPstaticfigure}
%D
%D Static figures are processed only when there has been something changed. Here is
%D Aditya Mahajan's testcase:
%D
%D \startbuffer
%D \startstaticMPfigure{circle}
%D   fill fullcircle scaled 1cm withcolor blue;
%D \stopstaticMPfigure
%D
%D \startstaticMPfigure{axis}
%D   drawarrow (0,0)--(2cm,0) ;
%D   drawarrow (0,0)--(0,2cm) ;
%D   label.llft(textext("(0,0)") ,origin) ;
%D \stopstaticMPfigure
%D \stopbuffer
%D
%D \typebuffer \getbuffer

\permanent\protected\def\startstaticMPfigure#1#2\stopstaticMPfigure
  {\startreusableMPgraphic{\??mpstaticgraphic#1}#2\stopreusableMPgraphic}

\permanent\tolerant\protected\def\startstaticMPgraphic#=#:#=#:#3\stopstaticMPgraphic
  {\startreusableMPgraphic{\??mpstaticgraphic#1}{#2}#3\stopreusableMPgraphic}

\permanent\protected\lettonothing\stopstaticMPfigure
\permanent\protected\lettonothing\stopstaticMPgraphic

\permanent\tolerant\protected\def\usestaticMPfigure[#1]#*[#2]%
  {\ifarguments\or
     \reuseMPgraphic{\??mpstaticgraphic#1}%
   \else
     \scale[#2]{\reuseMPgraphic{\??mpstaticgraphic#1}}%
   \fi}

%D Goody for preventing overflows:

%   frozen\def\MPdivten[#1]{\toscaled\dimexpr#1pt/10\relax}
\permanent\def\MPdivten[#1]{\toscaled\dimexpr#1pt/10\relax}

%D There is no way to distinguish the black color that you get when you issue a
%D \type {draw} without color specification from a color that has an explicit black
%D specification unless you set the variable \type {defaultcolormodel} to 1.
%D Hoewever, in that case you cannot distinguish that draw from one with a \type
%D {withoutcolor} specification. This means that we have to provide multiple
%D variants of inheritance.
%D
%D In any case we need to tell the converter what the inherited color is to start
%D with. Case~3 is kind of unpredictable as it closely relates to the order in which
%D paths are flushed. If you want to inherit automatically from the surrounding, you
%D can best stick to variant 1. Variant 0 (an isolated graphic) is the default.
%D
%D \startbuffer
%D \startuseMPgraphic{test}
%D     drawoptions(withpen pencircle scaled 1pt) ;
%D     def shift_cp = currentpicture := currentpicture shifted (-15pt,0) ; enddef ;
%D     draw fullcircle scaled 10pt withoutcolor  ; shift_cp ;
%D     fill fullcircle scaled 10pt               ; shift_cp ;
%D     draw fullcircle scaled 10pt withoutcolor  ; shift_cp ;
%D     fill fullcircle scaled 10pt withcolor red ; shift_cp ;
%D     draw fullcircle scaled 10pt withoutcolor  ; shift_cp ;
%D     fill fullcircle scaled 10pt               ; shift_cp ;
%D \stopuseMPgraphic
%D
%D \starttabulate
%D \NC 0\quad \NC \MPcolormethod0 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR
%D \NC 1\quad \NC \MPcolormethod1 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR
%D \NC 2\quad \NC \MPcolormethod2 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR
%D \NC 3\quad \NC \MPcolormethod3 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR
%D \stoptabulate
%D \stopbuffer
%D
%D \typebuffer \getbuffer

\newconstant\MPcolormethod

\appendtoks
    \clf_mpsetoutercolor
        \MPcolormethod\space
        \c_attr_colormodel\space
        \c_attr_color\space
        \dogetattribute{transparency}\relax
\to \everyMPgraphic

% \startMPinitializations
%     defaultcolormodel := \ifcase\MPcolormethod1\or1\or3\else3\fi;
% \stopMPinitializations

%D macros
%D  {mprunvar,mpruntab,mprunset}
%D
%D \starttyping
%D \startMPcode
%D     passvariable("version","1.0") ;
%D     passvariable("number",123) ;
%D     passvariable("string","whatever") ;
%D     passvariable("point",(1.5,2.8)) ;
%D     passvariable("triplet",(1/1,1/2,1/3)) ;
%D     passvariable("quad",(1.1,2.2,3.3,4.4)) ;
%D     passvariable("boolean",false) ;
%D     passvariable("path",fullcircle scaled 1cm) ;
%D     draw fullcircle scaled 20pt ;
%D \stopMPcode
%D
%D \ctxlua{inspect(metapost.variables)}
%D
%D \MPrunvar{version} \MPruntab{quad}{3} (\MPrunset{triplet}{,})
%D
%D $(x,y) = (\MPruntab{point}{1},\MPruntab{point}{2})$
%D $(x,y) = (\MPrunset{point}{,})$
%D \stoptyping

\permanent\def\MPrunvar  #1{\clf_mprunvar{#1}}         \aliased\let\mprunvar\MPrunvar
\permanent\def\MPruntab#1#2{\clf_mpruntab{#1}#2\relax} \aliased\let\mpruntab\MPruntab % #2 is number
\permanent\def\MPrunset#1#2{\clf_mprunset{#1}{#2}}     \aliased\let\mprunset\MPrunset

% \prependtoks \clf_mppushvariables \to \everybeforepagebody
% \appendtoks  \clf_mppopvariables  \to \everyafterpagebody

\tokspre\everybeforepagebody{\clf_mppushvariables}
\toksapp\everyafterpagebody {\clf_mppopvariables }

\aliased\let\MPpushvariables\clf_mppushvariables
\aliased\let\MPpopvariables \clf_mppopvariables

%D We also provide an outputless run:

\permanent\tolerant\protected\def\startMPcalculation#=#:#2\stopMPcalculation
  {\begingroup
   \setbox\nextbox\hpack\bgroup
   \cdef\currentMPinstance{#1}%
   \ifempty\currentMPinstance
     \let\currentMPinstance\defaultMPinstance
   \fi
   \lettonothing\currentMPgraphicname
   \cdef\currentMPformat{\MPinstanceparameter\s!format}%
   \meta_enable_include
   \meta_process_graphic{#2;draw origin}%
   \egroup
   \endgroup}

\permanent\protected\lettonothing\stopMPcalculation

%D \macros
%D   {setupMPgraphics}
%D
%D Here is a generic setup command:

\installcorenamespace{MPgraphics}

\installsetuponlycommandhandler \??MPgraphics {MPgraphics}

%D Here we hook in the outer color. When \type {color} is set to \type {global} we
%D get the outer color automatically. If you change this setting, you should do it
%D grouped in order not to make other graphics behave in unexpected ways.

\appendtoks
    \MPcolormethod\ifcstok{\directMPgraphicsparameter\c!color}\v!global\plusone\else\zerocount\fi
\to \everysetupMPgraphics

\setupMPgraphics
  [\c!color=\v!local]

%D Some more helpers (see \type {meta-grd.mkiv} for an example of usage):

% \relaxedspace fails on grid test

\permanent\def\MPdpar#1#2{\todimension{#1#2} }% \space}
\permanent\def\MPnpar#1#2{\todimension{#1#2} }% \space}
\permanent\def\MPspar#1#2{"#1#2"}

%D Done.

\protect \endinput
