%\iffalse
%<*copyright>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% rmannot.sty package,                   2011-11-04    %%
%% Copyright (C) 2008  D. P. Story                      %%
%%   dpstory@acrotex.net                                %%
%%                                                      %%
%% This program can redistributed and/or modified under %%
%% the terms of the LaTeX Project Public License        %%
%% Distributed from CTAN archives in directory          %%
%% macros/latex/base/lppl.txt; either version 1 of the  %%
%% License, or (at your option) any later version.      %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%</copyright>
%<package>\NeedsTeXFormat{LaTeX2e}[1997/12/01]
%<package>\ProvidesPackage{rmannot}
%<package> [2011/12/22 v2.0 Rich Media Annotations (dps)]
%<*driver>
\documentclass{ltxdoc}
\usepackage[colorlinks,hyperindex]{hyperref}
\def\AcroFLeX{AcroF\kern-.1667em\lower.5ex\hbox{L}\kern-.3eme\kern-.125emX\@}
\def\AcroTeX{Acro\negthinspace\TeX}
\begin{document}
  \def\CMD#1{\textbackslash#1}
  \GetFileInfo{rmannot.sty}
  \title{%
    \texttt{rmannot}: Support for FLV, SWF, and MP3\texorpdfstring{\\}{: }in Acrobat 9 Pro}
  \author{D. P. Story\\
    Email: \texttt{dpstory@acrotex.net}}
  \date{processed \today}
  \maketitle
  \tableofcontents
  \let\Email\texttt
  \DocInput{rmannot.dtx}
  \PrintIndex
\end{document}
%</driver>
% \fi
% \MakeShortVerb{|}
% \StopEventually{}
%
% \DoNotIndex{\def,\edef,\gdef,\xdef,\global,\long,\let}
% \DoNotIndex{\expandafter,\string,\the,\ifx,\else,\fi}
% \DoNotIndex{\csname,\endcsname,\relax,\begingroup,\endgroup}
% \DoNotIndex{\DeclareTextCommand,\DeclareTextCompositeCommand}
% \DoNotIndex{\space,\@empty,\special}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \section{Introduction}
%
% The \texttt{rmannot} package was written, in part, to support the {\AcroFLeX} Graphing package;
% however, this package has wider application. The \texttt{rmannot} package supports the creation of
% rich media annotations (\texttt{RichMedia}), and the embedding of \textsf{SWF} and \textsf{FLV} files in a \textsf{PDF}. \textsf{SWF}
% animations and \textsf{FLV} video can then be played within PDF viewed within version 9 (or later) of Adobe Reader
% and Acrobat.
%
% Source material for the creation of this package is document \textsl{Adobe Supplement to the
% ISO 32000}, June 2008. This document contains the PDF specification of rich media annotations.
% Beginning with version 9, Adobe Reader and Acrobat contain a Adobe Flash Player, which will
% play \textsf{SWF},  \textsf{FLV}, \textsf{MP3} files, and a number of other formats that
% need to be H.264 encoded.
%
%\paragraph*{On the Topic of 3D.}
% Here is something that I've only just come to realize: If you use the UI, and you
% create a 3D annotation in Acrobat, then give it a SWF as a resource, the 3D annot
% gets converted into a Rich Media annotation. Looking through the specification as
% described in the \emph{Adobe Supplement to ISO 32000}, I determined to implement this
% feature, and why not since most of the structure (rich media annot) was already in place
% by way of my \textsf{rmannot} package. So, this version of \textsf{rmannot} supports
% what I'll call Rich Media 3D annotations (RM3DA).
%
% Initially, it was not a challenge to get a 3D model to appear in a RMA
% created by \textsf{rmannot}, some straight forward modifications to
% \textsf{rmannot} were required, following ISO 32000. Looking at Alexander
% Grahn's\marginpar{\parbox{\linewidth}{\flushright\textbf{Alexander Grahn},\\he's the man!}} very fine and
% brilliant \textsf{movie15} package, I saw the difficulties of defining
% and creating \emph{view}s through the {\LaTeX} interface. With
% Alexander's permission, I gently lifted all the really heavy code from
% \textsf{movie15}, and placed it in \textsf{rmannot}. I offer up my great
% and humble thanks for his kindness in allowing the use of his code
% (characterized by commands beginning with \texttt{@MXV}).
%
%    \begin{macrocode}
\RequirePackage{xkeyval}
%    \end{macrocode}
%    \begin{macro}{use3D}
% When this option is invoked, the \texttt{annot3d.def} code file is
% input at the end of the package, and the \texttt{fp} package is loaded,
% is package is used to calculate the views matrices.
%    \begin{macrocode}
\DeclareOptionX{use3D}{%
    \def\rma@input@iiidCode{\InputIfFileExists{annot3d.def}{}{}}%
    \def\rma@requirefp{\RequirePackage[nomessages]{fp}}%
}
\let\rma@input@iiidCode\relax
\let\rma@requirefp\relax
%    \end{macrocode}
%    \end{macro}
% Process options, there can be only one!
%    \begin{macrocode}
\ProcessOptionsX
%    \end{macrocode}
% We use \textsf{graphicxsp} to generate annotation appearances.
%    \begin{macrocode}
\RequirePackage{graphicxsp}
\rma@requirefp
\RequirePackage{ifthen}
%    \end{macrocode}
%
% \section{Preliminary Code}
%
% A counter to track the annots as they are created.
%    \begin{macrocode}
\newcounter{rm@Cnt}
%    \end{macrocode}
% Some switches and markers to prevent embedding the same file multiple times.
%    \begin{macrocode}
\newif\ifrma@EmbedFile\rma@EmbedFiletrue
\newif\ifrma@EmbedVideoPlayer\rma@EmbedVideoPlayerfalse
\let\rma@isVPEmbedded=0
\newif\ifrma@EmbedAudioPlayer\rma@EmbedAudioPlayerfalse
\let\rma@isAPEmbedded=0
%    \end{macrocode}
%    \begin{macro}{\pathToSkins}
%    \begin{macro}{\pathToPlayers}
% For FLV files, one of standard skins are used to control the play.
% We need to know where the skins are located on the system (for
% distiller) and where the players are. Use \cs{pathToSkins} to
% specify the location of the skins, and \cs{pathToPlayers}.
% Specifying the \cs{pathToSkins} also defines the path to players.
% Currently, the players are in a sub-folder of the
% \texttt{Multimedia Skins} folder. We include \cs{pathToPlayers} in
% case future releases move the players elsewhere; in this case,
% \cs{pathToPlayers} must be executed after \cs{pathToSkins}.
%    \begin{macrocode}
\newcommand{\pathToSkins}[1]{\def\rma@pathToSkins{#1}%
    \def\PathToSkins{#1}\def\rma@pathToPlayers{#1/Players}}
%    \end{macrocode}
% The default location on a WinXP system.
%    \begin{macrocode}
%\pathToSkins{%
%    C:/Program Files/Adobe/Acrobat 9.0/Acrobat/Multimedia Skins}
\pathToSkins{%
    C:/Program Files (x86)/Adobe/Acrobat 10.0/Acrobat/Multimedia Skins}
\newcommand{\pathToPlayers}[1]{\def\rma@pathToPlayers{#1}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\defineRMPath}
% A simple command for defining paths. We use \cs{hyper@normalise} (from \textsf{hyperref}).
% Special characters are made safe to use. The command takes two arguments, the first
% is the control sequence of the path you want to define; the second argument is
% the path. For example,
%\begin{verbatim}
%  \defineRMPath{\myURLRMFiles}{http://www.example.com/~dpspeaker/videos}
%\end{verbatim}
%    \begin{macrocode}
\newcommand{\defineRMPath}[1]{\def\rm@ctrlName{#1}%
    \hyper@normalise\rm@defineURLPath}
\def\rm@defineURLPath#1{\expandafter\xdef\rm@ctrlName{#1}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\useVideoPlayerPlus}
% \texttt{(2010/09/29 v1.0b)} Added support for the use of a video player with
% additional features that are nice. \texttt{VideoPlayerPlus.swf} is supplied by Joel Geraci, see his
% blog article at
% \begin{NoHyper}\url{blogs.adobe.com/pdfdevjunkie/2010/03/introducing_the_video_player_p.html}\end{NoHyper}.
%    \begin{macro}{\useVideoPlayerX}
% We also support the video player begin developed (and in beta) by UVSAR at
% \begin{NoHyper}\url{http://www.uvsar.com/projects/acrobat/videoplayerx/}\end{NoHyper}.
%    \begin{macrocode}
\newif\ifVideoPlayerEx\VideoPlayerExfalse
\def\rma@VideoPlayer{VideoPlayer.swf}
\newcommand{\useVideoPlayerPlus}{%
    \VideoPlayerExtrue
    \def\rma@VideoPlayer{VideoPlayerPlus.swf}%
%    \end{macrocode}
% The JavaScript API supported by Geraci's \texttt{Video\-Player\-Plus.swf}. Full documentation
% for these is at \begin{NoHyper}\url{blogs.adobe.com/pdfdevjunkie/2010/03/introducing_the_video_player_p.html}\end{NoHyper}.
% The three below are also supported by \textbf{PlayerX}, but have different names.
%    \begin{macrocode}
    \def\mmSource{"multimedia_source"}
    \def\mmSkin{"multimedia_skin"}
    \def\mmSkinColor{"multimedia_skinBackgroundColor"}
%    \end{macrocode}
%  The method below is unique to this player.
%    \begin{macrocode}
    \def\mmSkinAutoHide{"multimedia_skinAutoHide"}
%    \end{macrocode}
%  We don't want both players declared in the same document so we prevent this by letting
% \cs{useVideoPlayerX} to \cs{relax}.
%    \begin{macrocode}
    \let\useVideoPlayerX\relax
}
\newcommand{\useVideoPlayerX}{%
    \VideoPlayerExtrue
    \def\rma@VideoPlayer{VideoPlayerX.swf}%
%    \end{macrocode}
% The JavaScript API supported by UVSAR's \texttt{Video\-PlayerX.swf}. Some API are more advanced, and  not listed,
% others---listed under the core above---change the return value from \texttt{void} to a non-\texttt{void} return. Full documentation for these
% is at \begin{NoHyper}\url{http://www.uvsar.com/projects/acrobat/videoplayerx/}\end{NoHyper}.
%
% These next three are supported by \texttt{PlayerPlus}, but has a different name. Using macros automatically
% gives the correct string for the player.
%    \begin{macrocode}
    \def\mmSource{"multimedia_setSource"}
    \def\mmSkin{"multimedia_setSkin"}
    \def\mmSkinColor{"multimedia_setSkinColor"}
%    \end{macrocode}
% The rest of these are unique to this player.
%    \begin{macrocode}
    \def\mmSeekCuePoint{"multimedia_seekCuePoint"}
    \def\mmSkinAlpha{"multimedia_setSkinAlpha"}
    \def\mmGetSource{"multimedia_getSource"}
    \def\mmUseLocal{"multimedia_useLocal"}
    \def\mmGetMetaData{"multimedia_getMetdata"}
    \def\mmGetVideoState{"multimedia_getVideoState"}
    \def\mmSetScaleMode{"multimedia_setScaleMode"}
    \def\mmGetVersion{"multimedia_getVersion"}
%    \end{macrocode}
% Version 10.2 of VPX, VPX now recognizes API of VPPlus, we therefore
% include \cs{mmSkinAutoHide}.
%    \begin{macrocode}
    \def\mmSetStageColor{"multimedia_setStageColor"}
    \def\mmIsLooping{"multimedia_isLooping"}
    \def\mmSkinAutoHide{"multimedia_skinAutoHide"}
%    \end{macrocode}
%  We don't want both players declared in the same document
%  so we prevent this by letting
% \cs{useVideoPlayerPlus} to \cs{relax}.
%    \begin{macrocode}
    \let\useVideoPlayerPlus\relax
}
%    \end{macrocode}
% \cs{useVideoPlayerPlus} and \cs{useVideoPlayerX} allowed only in the preamble.
%    \begin{macrocode}
\@onlypreamble\useVideoPlayerPlus
\@onlypreamble\useVideoPlayerX
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
% \paragraph*{Javascript API for Multimedia.} We present some convenience macros
% for controlling the multimedia players; we support three players \texttt{VideoPlayer.swf} (adobe),
% \texttt{VideoPlayerPlus.swf} (Geraci); and \texttt{VideoPlayerX.swf} (UVSAR). We shall refer to
% these three as \textbf{Player}, \textbf{PlayerPlus}, and \textbf{PlayerX}, respectively.
% Special definitions for \textbf{PlayerPlus} and \textbf{PlayerX} appear
%
% \medskip\noindent\textbf{Core: Player, PlayerPlus, PlayerX.} Valid for all three players.
%    \begin{macrocode}
\def\mmPlay{"multimedia_play"}
\def\mmPause{"multimedia_pause"}
\def\mmRewind{"multimedia_rewind"}
\def\mmNextCuePoint{"multimedia_nextCuePoint"}
\def\mmPrevCuePoint{"multimedia_prevCuePoint"}
\def\mmSeek{"multimedia_seek"}
\def\mmMute{"multimedia_mute"}
\def\mmVolume{"multimedia_volume"}
%    \end{macrocode}
% \textbf{Usage:} The following example sets the source for the RMA to play.
%\begin{verbatim}
%   var rm=this.getAnnotRichMedia(this.pageNum, "myRMA");
%   rm.callAS(\mmSource, "myVideo");
%\end{verbatim}
% The code is valid for \textbf{PlayerPlus} and for \textbf{PlayerX}, but not for the \textbf{Player}.
% Extensive examples may be found on the \textbf{AeB Blog}
% \begin{NoHyper}\url{http://blog.acrotex.net}\end{NoHyper}.
%
% \paragraph*{Other Macros of use}
%
%    \begin{macrocode}
\def\ps@mark{[\space}
\def\rma@edefexecute#1{\edef\rm@@temp@@exp{#1}\rm@@temp@@exp}
%    \end{macrocode}
% These label commands were taken from \textsf{movie15}, needed for comparability with
% of the \textsf{movie15} code being used in the 3D portion of this package.
%    \begin{macrocode}
\def\@MXV@newlabel#1#2{{%
  \expandafter\xdef\csname#1\endcsname{#2}}}%
\def\@MXV@getlabelvalue#1{%
  \expandafter\ifx\csname#1\endcsname\relax%
    undefined%
  \else%
    \csname#1\endcsname%
  \fi%
}%
%    \end{macrocode}
% Macro for writing labels to external \texttt{*.aux} file
%    \begin{macrocode}
\def\@MXV@labeltoaux#1#2{%
  \@bsphack\protected@write\@auxout{}{%
    \string\@MXV@newlabel{#1}{#2}%
    \string\@MXV@newlabel{@#1@}{\@MXV@getlabelvalue{#1}}%
  }\@esphack%
  \ifthenelse{%
    \equal{\@MXV@getlabelvalue{#1}}{undefined}\OR%
    %double check that the value hasn't changed
    \NOT\equal{\@MXV@getlabelvalue{#1}}{\@MXV@getlabelvalue{@#1@}}%
  }{%
%    \end{macrocode}
% Issue warning only once, at end of document
%    \begin{macrocode}
    \ifthenelse{\isundefined{\@MXV@warning}}{%
      \gdef\@MXV@warning{}%
      \AtEndDocument{%
        \PackageWarningNoLine{rmannot}{%
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak
        @@ Rerun to get object references right! @@\MessageBreak
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}%
      }%
    }{}%
  }{}%
}%
%    \end{macrocode}
% \DescribeMacro{\RefObjRm} holds the indirect reference to
% the annotation with name of \texttt{\#1}, used with RM3DA in \texttt{/GoTo3DView}
%    \begin{macrocode}
\def\RefObjRm#1{{\@MXV@getlabelvalue{rmAnnot_#1}}}
%    \end{macrocode}
% \paragraph*{Configuration File.}
%
% We supply a configuration file, after the definition of \cs{pathToSkins}
% to to read in the path to the skins on the local file system.
%    \begin{macrocode}
\InputIfFileExists{rmannot.cfg}{}{}
%    \end{macrocode}
%    \begin{macro}{\saveNamedPath}
%    \begin{macro}{\rma@useNamedPath}
% Paths to \textsf{SWF} and \textsf{FLV} files can be saved under unique names with the command
% \cs{saveNamedPath}. The first parameter is a symbolic name (unique) and is
% used in the fourth argument of \cs{rmAnnot} and as values
% of the \texttt{resources} key. The path is sanitized using the hyperref
% command \cs{hyper@normalise}.
%    \begin{macrocode}
%    \end{macrocode}
% When we are processing a \textsf{MP3} file, we need to embed the poster image only once.
% the following command  embeds the poster, then redefines itself to relax. This
% macro is used in \cs{rm@saveNamedPath}.
%    \begin{macrocode}
\def\rma@embed@mpiii@Poster{%
    \embedEPS[hiresbb]{ramp3poster}{ramp3poster}%
    \global\let\rma@embed@mpiii@Poster\relax
}
%    \end{macrocode}
% This is the MP3 poster image, but we'll only use it once. The command
% redefines itself to \cs{relax}.
%    \begin{macrocode}
\def\rma@set@mpiiiposter{%
    \begin{sp@createImage}{\bboxOf{ramp3poster}}{nramp3poster}%
        \rma@invisible
        \ps@mark{ramp3poster} /SP pdfmark
    \end{sp@createImage}%
    \global\let\rma@set@mpiiiposter\relax
}
%    \end{macrocode}
% \DescribeMacro{\saveNamedPath} \textbf{Syntax:} \verb!\saveNamedPath[<MimeType>]{<name>}{<path>}!\\
% (12/27/10) The default for \texttt{[\#1]} was \cs{rma@mimetype@swf}, have now
% changed this to \cs{@empty}.
%    \begin{macrocode}
\newcommand{\saveNamedPath}[2][]{%
    \edef\rm@argii{#2}\@ifundefined{rma@@#2}%
    {\gdef\rm@thisPath{rma@@#2}}{\rma@PkEr@ii}%
    \gdef\rm@thisMimeType{#1}%
    \hyper@normalise\rm@saveNamedPath
}
\def\rm@saveNamedPath#1{%
    \expandafter\gdef\csname\rm@thisPath\endcsname{#1}%
    \expandafter\xdef\csname rma@mt@\rm@argii\endcsname
        {\rm@thisMimeType}%
%    \end{macrocode}
% We check to see if this is an MP3 file. If so, we embed the screen shot
% of the \texttt{AudioPlayer} controls as a default poster. The graphic file
% \texttt{ramp3poster.eps} needs to be on the graphics search path of \LaTeX.
%    \begin{macrocode}
    \rma@edefexecute{\noexpand\filename@parse{#1}}%
    \@ifundefined{filename@ext}{\rma@PkEr@iii{#1}}{}%
    \rma@edefexecute{\noexpand
        \uppercase{\noexpand\def\noexpand\rma@tempi
        {\filename@ext}}}
%    \end{macrocode}
% We define the filename with extension under a convenience command. Authors
% are encouraged to use this command when referencing an embedded file
% in the \texttt{flashvars} key. Its value should be basename.ext, unless
% part of the path is enclosed in braces, in which case, a folder may be
% included, for example \texttt{assets/myVideo.flv}. This value is the one
% that appears in the \textbf{Resources} tab of the \textbf{Edit Flash}
% under \textbf{Name}.
%    \begin{macrocode}
    \expandafter\xdef\csname\rm@argii FileName\endcsname{%
        \filename@base.\filename@ext}%
    \expandafter\xdef\csname\rm@argii URL\endcsname{%
       \filename@area\filename@base.\filename@ext}%
%    \end{macrocode}
% Embed the file \texttt{ramp3poster.eps}. \textsf{GraphicxSP} required.
%    \begin{macrocode}
    \ifx\rma@tempi\rma@rmAnnot@type@mpiii\rma@embed@mpiii@Poster\fi
}
%    \end{macrocode}
% \cs{rma@useNamedPath} is used internally to access the path through its name.
%    \begin{macrocode}
\def\rma@useNamedPath#1{\@nameuse{rma@@#1}}
\def\rma@resource#1{\csname#1FileName\endcsname}
\def\rma@urlresource#1{\csname#1URL\endcsname}
%    \end{macrocode}
% Within an \textsf{eforms} widget, \cs{Name} and \cs{urlName} are defined. This is to
% make \textsf{eforms} consistent with \cs{rmAnnot}, where \cs{Name} and \cs{urlName}
% are let to \cs{rma@resource} and to \cs{rma@urlresource}, respectively.
%    \begin{macrocode}
\expandafter\def\expandafter\makeJSspecials\expandafter{\makeJSspecials
    \let\Name\rma@resource\let\urlName\rma@urlresource
}
%    \end{macrocode}
%    \begin{macro}{\rmaName}
%    \begin{macro}{\rmaUrlName}
% Public versions of \cs{rma@resource} and \cs{rma@urlresource}.
% (10/18/2011) Added public versions of \cs{rma@resource} and \cs{rms@urlresource} that have parentheses
% to delimit argument. This way they can be used inside the \texttt{insDLJS} env.
%    \begin{macrocode}
\let\rmaName\rma@resource
\def\rmaNameP(#1){\rma@resource{#1}}
\let\rmaUrlName\rma@urlresource
\def\rmaUrlNameP(#1){\rma@urlresource{#1}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
% \paragraph*{Supported Extensions \& Mime Types.}
%
% A couple of text macros, used to compare with the extensions provided by
% the document author. Currently, we support \textsf{SWF}, \textsf{FLV},
% \textsf{MP3} files, and \textsf{F4V} files (Acrobat 10 or
% later).\par\medskip\noindent \texttt{(2011/11/03)} Added support for
% \textsf{MP4}, \textsf{M4V}, \textsf{MOV}, \textsf{3GP}, \textsf{3G2}, all
% require \textsf{H.264} encoding; if these files do not have
% \textsf{H.264} encoding, rmannot/distiller will embed anyway, but the
% video will not play. (2011/12/10) Added \textsf{U3D} and \textsf{PRC} to the list of
% file types supported.
%    \begin{macrocode}
\def\getargsiii#1#2#3{\def\aeb@argi{#1}\def\aeb@argii{#2}%
    \def\aeb@argiii{#3}}
\@tfor\rma@data:={{uiiid}{U3D}{model/u3d}}{{prc}{PRC}{model/prc}}%
    {{swf}{SWF}{application/x-shockwave-flash}}%
    {{flv}{FLV}{video/x-flv}}{{fiv}{F4V}{video/mp4}}%
    {{mpiv}{MP4}{video/mp4}}{{mivV}{M4V}{video/x-m4v}}%
    {{mov}{MOV}{video/quicktime}}{{iiiGP}{3GP}{video/3gpp}}%
    {{iiiGii}{3G2}{video/3gpp2}}{{mpiii}{MP3}{audio/x-mp3}}\do{%
    \expandafter\getargsiii\rma@data\expandafter\edef\csname%
        rma@rmAnnot@type@\aeb@argi\endcsname{\aeb@argii}
    \expandafter\edef\csname%
        rma@mimetype@\aeb@argi\endcsname{\aeb@argiii}
}
%    \end{macrocode}
% \DescribeMacro{VideoPlayer}\DescribeMacro{AudioPlayer}
% Symbolic name of the video player and audio players.
%\par\noindent\medskip
% We delay the definition of VideoPlayer until the beginning of the document,
% if the user can specify \cs{useVideoPlayerX} in the preamble, \cs{rma@VideoPlayer}
% will expand to \textsf{VideoPlayerX.swf}.
%    \begin{macrocode}
\AtBeginDocument{\saveNamedPath{VideoPlayer}%
    {\PathToSkins/Players/\rma@VideoPlayer}}
\saveNamedPath{AudioPlayer}{\PathToSkins/Players/AudioPlayer.swf}
%    \end{macrocode}
% \DescribeMacro{skin1}\DescribeMacro{skin2}\DescribeMacro{skin3}
% \DescribeMacro{skin4}\DescribeMacro{skin5}\DescribeMacro{skin6}
% \DescribeMacro{skin7} We predefine the seven skins, these should also be
% used as resources of \cs{rmAnnot} when either \texttt{VideoPlayerPlus} or
% \texttt{VideoPlayerX} is used, and when the skins are to be changed dynamically.
%    \begin{macrocode}
\saveNamedPath{skin1}{\PathToSkins/SkinOverAllNoFullNoCaption.swf}
\saveNamedPath{skin2}{\PathToSkins/SkinOverAllNoVolNoCaptionNoFull.swf}
\saveNamedPath{skin3}{\PathToSkins/SkinOverPlay.swf}
\saveNamedPath{skin4}{\PathToSkins/SkinOverPlayMute.swf}
\saveNamedPath{skin5}{\PathToSkins/SkinOverPlaySeekMute.swf}
\saveNamedPath{skin6}{\PathToSkins/SkinOverPlaySeekStop.swf}
\saveNamedPath{skin7}{\PathToSkins/SkinOverPlayStopSeekMuteVol.swf}
%    \end{macrocode}
% \DescribeMacro{none}\DescribeMacro{noChange} Two special convenience definitions.
% We make definitions so that \verb!\Name{none}! and \verb!\urlName{none}!
% expand to \cs{@empty}; \verb!\Name{noChange}! and \verb!\urlName{none}!
% both expand to the string \texttt{noChange}.
%    \begin{macrocode}
\@namedef{noneFileName}{}
\@namedef{noneURL}{}
\@namedef{noChangeFileName}{noChange}
\@namedef{noChange}{noChange}
%    \end{macrocode}
% The following is a convenience text macro, this string appears repeatedly
% throughout this file.
%    \begin{macrocode}
\def\rma@ANT{rmAssetsNameTree-\therm@Cnt}
%    \end{macrocode}
%
% \section{The \texorpdfstring{\cs{rmAnnot}}{\CMD{rmAnnot}} command}
%
% The \cs{rmAnnot} command creates a rich media annotation
% (\texttt{AnnotRichMedia}). Currently, this package supports \textsf{SWF},
% \textsf{FLV}, \textsf{F4V}, \textsf{MP4}, \textsf{M4V}, \textsf{MOV},
% \textsf{3GP}, \textsf{3G2}, and \textsf{MP3} files. Normally, \textsf{SWF}
% files are applications that contains their own navigation controls; the
% \textsf{FLV} and \textsf{F4V} files are played by a
% \texttt{VideoPlayer.swf} file, shipped with Acrobat 9 Pro, and a
% controlling skin, also shipped with Acrobat. The \cs{rmannot} tries to
% support most of the features available through the user interface.
%
% \textsf{Acrobat~9 Pro} supports \textsf{FLV}, \textsf{SWF}, and \textsf{MP3} files as well,
% \textsf{Acrobat~9 Pro Extension} supports other video formats, by
% first converting that format to \textsf{FLV} and embedding them in the
% document. Adobe Flash (CS5) Professional can save a movie as SWF, and
% the included utility \textsf{Adobe Flash Video Encoder} can convert movie files to the
% \textsf{FLV} or \textsf{F4V} format.
%
% Beginning with version 9.2, the direct inclusion of videos with extensions of
% \textsf{MP4}, \textsf{M4V}, \textsf{MOV}, \textsf{3GP}, \textsf{3G2} requires that
% the fils use the \textsf{H.264} codec.
%
% \paragraph*{3D Support.} (2011/12/10) Added \textsf{U3D} and \textsf{PRC} to the list of
% file types supported; when one of these files appears in \texttt{\#4} of
% \cs{rmAnnot} a RM3DA is created.
%
% Certain features of 3D, specifically \textbf{3D
% measurement} and \textbf{3D commenting}, as well the \textbf{Select
% Model}, \textbf{Select Face}, and \textbf{Select 3 Points} found in the
% \textbf{Camera Properties} dialog box, may or may not work, depending on
% the information is the 3D file. For example dice.u3d cannot be measured, unless
% it is imported by Acrobat, which apparently parses the file to obtain the
% required information for measuring.
%
% \subsection{Options for \texorpdfstring{\cs{rmAnnot}}{\CMD{rmAnnot}}}
%
% The \texttt{xkeyval} package is used to develop options for the \cs{rmAnnot} command.
%
% \subsubsection{Annot Name}
%
%    \begin{macro}{name}
% Use the name key to specify the annotation name. If not specified, this package generates the
% name \texttt{aebRM}\cs{therm@Cnt}.
%    \begin{macrocode}
\define@key{rmAnnot}{name}[aebRM\therm@Cnt]{\def\rma@Annot@name{#1}}
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Launch Settings}
%
%    \begin{macro}{enabled}
% This option determines how the annot is activated, there are three
% possible values: \texttt{onclick} (activated when user clicks on
% the annot, or by user script); \texttt{pageopen} (activated when
% the page is opened); \texttt{pagevisible} (activated when the page
% becomes visible).
%    \begin{macrocode}
\define@choicekey+{rmAnnot}{enabled}[\val\nr]%
    {onclick,pageopen,pagevisible}[onclick]{%
    \ifcase\nr\relax
        \def\rma@rmAnnot@enabled{/XA}\or
        \def\rma@rmAnnot@enabled{/PO}\or
        \def\rma@rmAnnot@enabled{/PV}\fi
}{\PackageWarning{rmannot}{Bad choice for enabled, permissible values
   are onclick, pageopen and pagevisible. Try again}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{deactivated}
% This option determines how the annot is de-activated, there are
% three possible values: \texttt{onclick} (de-activated by user
% script or by right-clicking on the annot and choosing Disable
% Content); \texttt{pageclose} (de-activated when the page is
% closed); \texttt{pageinvisible} (de-activated when the page becomes
% invisible).
%    \begin{macrocode}
\define@choicekey+{rmAnnot}{deactivated}[\val\nr]%
    {onclick,pageclose,pageinvisible}[onclick]{%
    \ifcase\nr\relax
        \def\rma@rmAnnot@deactivated{/XD}\or
        \def\rma@rmAnnot@deactivated{/PC}\or
        \def\rma@rmAnnot@deactivated{/PI}\fi
}{\PackageWarning{rmannot}{Bad choice for deactivated, permissible
    values are onclick, pageclose and pageinvisible. Try again}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{windowed}
% When this boolean option is set to true (or is just included in the option list),
% the video is viewed in a floating window. The default is to view the video
% within the annot.
%    \begin{macrocode}
\define@boolkey{rmAnnot}{windowed}[true]{}
%    \end{macrocode}
%    \end{macro}
% When the rich media annotation appears as a floating window, the initial dimensions
% and position of that window can be set by the following key-value pairs. Use
% \cs{setWindowDimPos} to set all these values.
%    \begin{macrocode}
\define@key{winDimPos}{width}{\def\rma@winDimPos@width{#1}}
    \define@key{winDimPosWidth}{default}[288]%
        {\def\rma@winDimPosWidth@def{#1}}
    \define@key{winDimPosWidth}{max}[576]%
        {\def\rma@winDimPosWidth@max{#1}}
    \define@key{winDimPosWidth}{min}[72]%
        {\def\rma@winDimPosWidth@min{#1}}
\define@key{winDimPos}{height}{\def\rma@winDimPos@height{#1}}
    \define@key{winDimPosHeight}{default}[216]%
        {\def\rma@winDimPosHeight@def{#1}}
    \define@key{winDimPosHeight}{max}[432]%
        {\def\rma@winDimPosHeight@max{#1}}
    \define@key{winDimPosHeight}{min}[72]%
        {\def\rma@winDimPosHeight@min{#1}}
\define@key{winDimPos}{position}{\def\rma@winDimPos@position{#1}}
    \define@choicekey+{winDimPosPos}{halign}[\val\nr]%
        {near,center,far}[far]{%
        \ifcase\nr\relax
            \def\rma@winDimPosPos@halign{/Near}\or
            \def\rma@winDimPosPos@halign{/Center}\or
            \def\rma@winDimPosPos@halign{/Far}\fi
    }{}
    \define@choicekey+{winDimPosPos}{valign}[\val\nr]%
        {near,center,far}[near]{%
        \ifcase\nr\relax
            \def\rma@winDimPosPos@valign{/Near}\or
            \def\rma@winDimPosPos@valign{/Center}\or
            \def\rma@winDimPosPos@valign{/Far}\fi
    }{}
    \define@key{winDimPosPos}{hoffset}[18]%
        {\def\rma@winDimPosPos@hoffset{#1}}
    \define@key{winDimPosPos}{voffset}[18]%
        {\def\rma@winDimPosPos@voffset{#1}}
%    \end{macrocode}
%    \begin{macro}{\setWindowDimPos}
%    \begin{macro}{\resetWindowDimPos}
% When the window is floating (\texttt{windowed=true}) there are a number of
% parameters that govern the dimensions and position on page. These key-value
% pairs are not set up as optional arguments of \cs{rmAnnot}. Set them in
% vertical mode, for the next rich media annotation.
%
% The command \cs{resetWindowDimPos} resets the window parameters to their
% default values.
%    \begin{macrocode}
\providecommand{\setWindowDimPos}[1]{%
    \setkeys{winDimPos}{#1}%
    \edef\temp@expand@sets{%
        \noexpand\setkeys{winDimPosWidth}{\rma@winDimPos@width}%
        \noexpand\setkeys{winDimPosHeight}{\rma@winDimPos@height}%
        \noexpand\setkeys{winDimPosPos}{\rma@winDimPos@position}%
    }\temp@expand@sets
}
\providecommand{\resetWindowDimPos}{%
    \setWindowDimPos{width={default,max,min},height={default,max,min},
        position={halign,valign,hoffset,voffset}}%
}
\resetWindowDimPos
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{url}
% Use the url key, a boolean, to indicate that the path to the file is a URL.
%    \begin{macrocode}
\define@boolkey{rmAnnot}{url}[true]{}
%    \end{macrocode}
%    \end{macro}
%\subsubsection{\texorpdfstring{\protect\cs{setRmOptions3D}}
%    {\CMD{setRmOptions3D}}: UI for 3D}
%    \begin{macro}{\setRmOptions3D}
% 3D options for the annot with name of \texttt{\#1}; the options are passed
% by \texttt{\#2}. This supports the 3D tab of the user interface for the \textsf{Edit 3D}
% dialog box.\par\medskip\noindent
% \textbf{Proposed syntax:}
%\begin{verbatim}
%\setRmOptions3D{<annot_name>}
%{
%   3DOptions={options for movie15},
%   3DResources={
%       none={rName=<name1>},...,
%       foreground={rName=<name2>,flashvars=<vars>},...,
%       background={rName=<name3>,flashvars=<vars>},...,
%       material={rName=<name4>,mName=<materialName>,flashvars=<vars>},...
%   }
%}
%\end{verbatim}
% When the \cs{rmAnnot} does not take a 3D file as its 4th argument, the above options are
% ignored.
%    \begin{macrocode}
\def\setRmOptions3D#1#2{%
    \expandafter\xdef\csname#1_3DOPTS\endcsname{#2}%
}
%    \end{macrocode}
%    \end{macro}
% \subsubsection{Annot appearance options}
%    \begin{macro}{borderwidth}
% The width of the border of the annot. Possible values are
% \texttt{none} (the default), \texttt{thin}, \texttt{medium}, and \texttt{thick}.
%    \begin{macrocode}
\define@choicekey+{rmAnnot}{borderwidth}[\val\nr]%
    {none,thin,medium,thick}[none]{%
    \ifcase\nr\relax
        \def\rma@rmAnnot@borderwidth{0}\or
        \def\rma@rmAnnot@borderwidth{1}\or
        \def\rma@rmAnnot@borderwidth{3}\or
        \def\rma@rmAnnot@borderwidth{5}\fi
}{\PackageWarning{rmannot}{Bad choice for borderwidth, permissible
    values are none,thin,medium,and thick. Try again}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{poster}
%    \begin{macro}{posternote}
% The name of a embedded graphic to be used as a poster for the video.
%
% If the \texttt{poster} key is not specified, a substitute poster will
% be generated, see the definition of \cs{defaultPoster}. This default poster
% has a little message, or note, in the lower left corner. The default message
% is an advertisement for {\AcroTeX} followed by the words Flash, Video, or
% MP3, depending on the file type.
%    \begin{macrocode}
\define@key{rmAnnot}{poster}[]{\def\rma@rmAnnot@poster{#1}}
\define@key{rmAnnot}{posternote}[AcroTeX \rma@poster@descrip]%
    {\def\rma@posternote{#1}}
%    \end{macrocode}
%    \begin{macro}{invisible}
% \texttt{(2010/09/29 v1.0a)} When the invisible option is used and there
% is no poster option, then the poster is transparent. This makes it useful
% when viewing the video in a window, and you want to hide the annot in an
% obscure corner of the page (or under a form field).
%    \begin{macrocode}
\define@key{rmAnnot}{invisible}[]%
    {\def\rma@invisible{\ps@mark/ca 0/SetTransparency pdfmark }}
\let\rma@invisible\@empty
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{transparentBG}
% This option is available only for SWF files. Set the background to
% transparent.
%    \begin{macrocode}
\define@boolkey{rmAnnot}{transparentBG}[true]{%
    \ifKV@rmAnnot@transparentBG
        \def\rma@rmAnnot@transparent{true}\else
        \def\rma@rmAnnot@transparent{false}\fi
}
\define@boolkey{rmAnnot}{toolbar}[true]{%
    \ifKV@rmAnnot@toolbar
        \def\rma@rmAnnot@toolbar{true}\else
        \def\rma@rmAnnot@toolbar{false}\fi
}
\define@boolkey{rmAnnot}{modeltree}[true]{%
    \ifKV@rmAnnot@modeltree
        \def\rma@rmAnnot@modeltree{true}\else
        \def\rma@rmAnnot@modeltree{false}\fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{passcontext}
% This option is available only for SWF files. SWF file developers
% can select this option to replace the Acrobat context menu with the
% context menu of the originating SWF file. When the user
% right-clicks the SWF file, the available options are from the
% originating file.
%
% Pass right-click context to Flash. Should be used only if there is a way of deactivating
% the annotation, perhaps through JavaScript.
%    \begin{macrocode}
\define@boolkey{rmAnnot}{passcontext}[true]{%
    \ifKV@rmAnnot@passcontext
    \def\rma@rmAnnot@PassContextClick{true}\else
    \def\rma@rmAnnot@PassContextClick{false}\fi
}
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Options for the skins}
%
% Skins are used with FLV video files.
%
%    \begin{macro}{skin}
% When playing an FLV file, various skins can be used. I've labeled them
% \texttt{skin1}--\texttt{skin7} and \texttt{none}. The names of the SWF
% files describe each skin.
% \par\medskip\noindent
% \textbf{Note:} By experimenting with the UI, it is apparent that one cannot have
% different controls for the same video file.
%    \begin{macrocode}
\define@choicekey+{rmAnnot}{skin}[\val\nr]%
    {none,skin1,skin2,skin3,skin4,skin5,skin6,skin7}[skin1]{%
    \edef\rma@skinName{#1}% 2011/10/18 changed from number to name
    \ifcase\nr\relax
        \let\rma@rmAnnot@Skin\@empty\or
        \def\rma@rmAnnot@Skin{SkinOverAllNoFullNoCaption.swf}\or
        \def\rma@rmAnnot@Skin{SkinOverAllNoVolNoCaptionNoFull.swf}\or
        \def\rma@rmAnnot@Skin{SkinOverPlay.swf}\or
        \def\rma@rmAnnot@Skin{SkinOverPlayMute.swf}\or
        \def\rma@rmAnnot@Skin{SkinOverPlaySeekMute.swf}\or
        \def\rma@rmAnnot@Skin{SkinOverPlaySeekStop.swf}\or
        \def\rma@rmAnnot@Skin{SkinOverPlayStopSeekMuteVol.swf}\fi
}{%
    \@ifundefined{rma@@#1}{%
    \PackageWarning{rmannot}{Bad choice for 'skin,' permissible
    values are skin1--skin7, or a custom skin already defined.
    Try again}}{%
%    \end{macrocode}
% If a value of \texttt{skin} is not one of the defaults, we allow the user to
% define a skin, name and path to a skin SWF must be declared using \cs{saveNamedPath}.
%    \begin{macrocode}
        \PackageWarning{rmannot}{Recording new skin, '#1'}%
        \edef\rma@skinName{#1}%
        \edef\rma@rmAnnot@Skin{\csname#1FileName\endcsname}%
        \expandafter\let\csname embedSkin#1\endcsname=1
    }%
}
%    \end{macrocode}
% We use \verb!\let\csname embedSkin<skinName>\endcsname! determining to
% embed or not to embed a particular skin. We initialize these markers
% to 1 (embed). After each annot, the marker corresponding to the skin
% used is set to 0; hence we will not embed it again.
%    \begin{macrocode}
\@tfor\rma@arg:={skin0}{skin1}{skin2}{skin3}{skin4}%
    {skin5}{skin6}{skin7}\do{%
    \expandafter\let\csname embedSkin\rma@arg\endcsname=1
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{skinAutoHide}
% A Boolean key that determines if the skin automatically hides itself
% when the mouse pointer is removed from the annot. The default is \texttt{true}.
%    \begin{macrocode}
\define@boolkey{rmAnnot}{skinAutoHide}[true]{%
    \ifKV@rmAnnot@skinAutoHide
    \def\rma@skinAutoHide{true}\else
    \def\rma@skinAutoHide{false}\fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{skinBGColor}
% The color of the skin, represented as a hex number, the default
% is \texttt{0x5F5F5F}.
%    \begin{macrocode}
\define@key{rmAnnot}{skinBGColor}[0x5F5F5F]%
    {\def\rma@skinBGColor{#1}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{skinBGAlpha}
% The alpha for the skin, a number between 0 and 1. The default is 0.75.
%    \begin{macrocode}
\define@key{rmAnnot}{skinBGAlpha}[0.75]%
    {\def\rma@skinBGAlpha{#1}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{volume}
% The initial volume of the audio track. Values range from 0 (muted) to 1. The default is
% 1.0. The volume may be adjusted by the user at run time, if the selected skin has a volume
% control, or by a JavaScript control.
%    \begin{macrocode}
\define@key{rmAnnot}{volume}[1.00]%
    {\def\rma@rmAnnot@volume{#1}}
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Animation Settings}
%
%    \begin{macro}{speed}
% Description quoted from the \textsl{Adobe Suppl.\ Doc}: A positive number specifying the
% speed to be used when running the animation. A value greater
% than one shortens the time it takes to play the animation, or
% effectively speeds up the animation.
%    \begin{macrocode}
\define@key{rmAnnot}{speed}[1]{%
    \def\rma@rmAnnot@speed{#1}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{playcount}
% Description quoted from the \textsl{Adobe Suppl.\ Doc}: An integer specifying the play count
% for this animation style. A nonnegative integer represents the
% number of times the animation is played. A negative integer
% indicates that the animation is infinitely repeated. The default is -1.
%    \begin{macrocode}
\define@key{rmAnnot}{playcount}[-1]{%
    \def\rma@rmAnnot@playcount{#1}%
}
%    \end{macrocode}
%    \end{macro}
% \subsubsection{Adding Resources}
%
% Some SWF files require other files to run. The resources key
% allows you  to list all files that are required to run the SWF
% file.
%    \begin{macro}{resources}
% Currently, the additional resources are other SWF files only.
% Items must be specified using \cs{useNamedPath} command, and is
% a lists of delimited by braces
%\begin{verbatim}
%  resources={mySWF1,mySWF2}
%\end{verbatim}
% where \texttt{mySWF1} and \texttt{mySWF2} are defined by \cs{saveNamedPath}.
%    \begin{macrocode}
\newtoks\rma@toks\rma@toks={}
\newcount\rma@nResources
\newif\ifrma@isiiid\rma@isiiidfalse
\define@key{rmAnnot}{resources}[]{\rma@toks={}\rma@nResources=0%
    \ifrma@isiiid\let\rma@next\relax
        \else\def\rma@next{\rma@proc@resources{#1}}\fi\rma@next
}
%    \end{macrocode}
% When we are doing 3D, we don't process resources through \texttt{rmAnnot} family.
% When we are processing 3D resources, the files are entered through a
% separate command \cs{setRmOptions3D}
%    \begin{macrocode}
\newcommand{\rma@proc@resources}[1]{%
    \def\rma@rmAnnot@resources{#1}%
    \ifx\rma@rmAnnot@resources\@empty\let\rma@addResources\@empty
    \let\rma@addFileSpecs\@empty\else
%    \end{macrocode}
% We process resources when there are some to process \texttt{:-)}
%    \begin{macrocode}
        \@for\rma@arg:=\rma@rmAnnot@resources\do{%
            \advance\rma@nResources1\relax
            \rma@edefexecute{\noexpand
                \filename@parse{\rma@useNamedPath{\rma@arg}}}%
            \@ifundefined{filename@ext}{%
              \rma@PkEr@iii{\rma@useNamedPath{\rma@arg}}}{}%
            \edef\rma@fs@expand{rmFileStrm\rma@arg}%
            \@ifundefined{\rma@fs@expand}{%
%    \end{macrocode}
% If this resource has not been used, we define it, and give it
% a indirect reference: \verb!rmfstream\therm@Cnt-\the\rma@nResources!
%    \begin{macrocode}
            \expandafter\xdef\csname\rma@fs@expand\endcsname
              {rmfstream\therm@Cnt-\the\rma@nResources}%
              \def\rma@embed{1}}{\def\rma@embed{0}}%
%    \end{macrocode}
% Add this file to our token list of all resources.
%    \begin{macrocode}
            \edef\rma@tmp@exp{\the\rma@toks%
              \noexpand\\{\the\rma@nResources}%
              {\filename@area}{\filename@base.\filename@ext}%
              {\rma@embed}{\csname\rma@fs@expand\endcsname}%
%    \end{macrocode}
% (12/27/10) changed the expansion to \verb!\expandafter\noexpand! to leave
% a token as as this argument. Later, in \cs{rm@appendFileSpecs} we test this token
% against \cs{@empty}. This argument is \texttt{\#6} in \cs{rm@appendFileSpecs}.
%    \begin{macrocode}
              {\expandafter\noexpand\csname rma@mt@\rma@arg\endcsname}}%
            \rma@toks=\expandafter{\rma@tmp@exp}%
        }%
        \let\\\rm@appendNameTree
        \expandafter\xdef\expandafter\rma@addResources%
            \expandafter{\the\rma@toks}%
        \let\\\rm@appendFileSpecs
        \expandafter\xdef\expandafter\rma@addFileSpecs%
            \expandafter{\the\rma@toks}%
    \fi
}
%    \end{macrocode}
%    \end{macro}
% The two commands \cs{rm@appendNameTree} and \cs{rm@appendFileSpecs} take
% the same six parameters, here they are
%\begin{itemize}
%    \item[\texttt{\#1}] The resource number, typically \verb!\the\rma@nResources!
%    \item[\texttt{\#2}] \cs{filename@area}
%    \item[\texttt{\#3}] \cs{filename@base.}\cs{filename@ext}
%    \item[\texttt{\#4}] The value of \cs{rma@embed}, 1 to embed, 0 for not embedding
%                        file has already been embedded.
%    \item[\texttt{\#5}] The indirect reference to the file stream
%    \item[\texttt{\#6}] The mime type of this resource
%\end{itemize}
% \DescribeMacro{\rm@appendNameTree}
% This is used with the token list \cs{rma@toks}, before this list is expanded,
% \verb!\\! is \cs{let} to \cs{rm@appendNameTree}. We create a name tree of
% additional resources specified by the \texttt{resources} key. This is saved
% in a macro \cs{rma@addFileSpecs} to be used later.
%    \begin{macrocode}
\def\rm@appendNameTree#1#2#3#4#5#6{%
     \ps@mark{\rma@ANT} (#3) /APPEND pdfmark^^J%
     \ps@mark{\rma@ANT} {rmfilespec\therm@Cnt-#1}/APPEND pdfmark^^J%
}
%    \end{macrocode}
% \DescribeMacro{\rm@appendFileSpecs}
% This is used with the token list \cs{rma@toks}, before this list is expanded,
% \verb!\\! is \cs{let} to \cs{rm@appendFileSpecs}. We create a set of
% file specs and file streams, if needed, for each of the resources.
% This is saved in a macro \cs{rma@addResources} to be used later.
%    \begin{macrocode}
\def\rm@appendFileSpecs#1#2#3#4#5#6{%
%    \end{macrocode}
% \paragraph*{File specs.} If things work out well, \verb!/F {#5}! is an
% indirect reference to the file stream, whether it is a new one that
% has never been embedded, or is one that has already been embedded.
%    \begin{macrocode}
    \ps@mark/_objdef {rmfilespec\therm@Cnt-#1}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmfilespec\noexpand\therm@Cnt-#1} <<%
        /F(#3)%
        /UF (#3)%
        /EF <</F {#5}>>%
        /Type/Filespec%
    >>/PUT pdfmark^^J%
%    \end{macrocode}
% \paragraph*{File stream:} We only embed if \texttt{\#4} is equal to 1, if it is
% 0, this particular file has already been embedded.
%    \begin{macrocode}
    \if#41
        \ps@mark/_objdef {#5} /type/stream/OBJ pdfmark^^J%
        \ps@mark{#5} (#2#3) (r) file /PUT pdfmark^^J%
        \ps@mark{#5}<<%
            /Type/EmbeddedFile%
%    \end{macrocode}
% (12/27/10) The \texttt{/Subtype} key is optional,
% so we make it optional if \texttt{\#6} is empty.
%    \begin{macrocode}
\ifx#6\@empty\else
            /Subtype(#6)%
\fi
          >>/PUT pdfmark^^J%
        \ps@mark{#5} /CLOSE pdfmark^^J%
    \fi
}
%    \end{macrocode}
%    \begin{macro}{flashvars}
% Flash variables to pass to a SWF file.
%    \begin{macrocode}
\define@key{rmAnnot}{flashvars}[]{%
    \def\rma@rmAnnot@flashvars{#1}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{cuepoints}
%
% Populate the \texttt{CuePoint} dictionary of the \texttt{Params}
% dictionary. This one is tricky. There are two types of cue points,
% Navigation and Event. Navigation corresponds to cue points that
% have been encoded onto the Flash media; Event corresponds a time
% value on the media, and is not, I believe, encoded on the media.
% We need the type (Navigation or Event), the Name, the Time and the action
% (A).
%
% Event cue points are used to trigger ActionScript methods when the
% cue point is reached, and let you synchronize the video playback to
% other events within the Flash presentation.
%
% Navigation cue points are used for navigation and seeking, and to
% trigger ActionScript methods when the cue point is reached.
% Embedding a navigation cue point inserts a keyframe at that point in
% the video clip to enable viewers to seek to that place in the video.
%
%    \begin{macrocode}
\define@key{rmAnnot}{cuepoints}[]{%
    \edef\rma@rmAnnot@cuepoints{#1}%
    \ifx\rma@rmAnnot@cuepoints\@empty\else
        \rma@nResources=0%
        \def\rma@array@hold{}\def\rma@dict@hold{}%
        \@for\arg:=\rma@rmAnnot@cuepoints\do{%
            \advance\rma@nResources1\relax
            \rma@edefexecute{\noexpand\setkeys{rmCuePt}{\arg}}%
            % need to build the array of indirect references,
            \edef\rma@array@hold{\rma@array@hold\space
                {rmCuePoints\therm@Cnt-\the\rma@nResources}}%
            % and the code for the cue point dictionary
            \edef\rma@dict@hold{\rma@dict@hold
                \ps@mark/_objdef %
                    {rmCuePoints\therm@Cnt-\the\rma@nResources}%
                    /type/dict/OBJ pdfmark^^J%
                \ps@mark{rmCuePoints\therm@Cnt-\the\rma@nResources} <<
                    /Type/CuePoint
\ifx\rma@rmCuePt@name\@empty
                    /Name (RMACP \the\rma@nResources)
\else
                    /Name (\rma@rmCuePt@name)
\fi
                    /Subtype \rma@rmCuePt@type
                    /Time \rma@rmCuePt@time
\ifx\rma@rmCuePt@action\@empty\else
                    /A << /Type/Action\JS{\rma@rmCuePt@action} >>
\fi
                   >> /PUT pdfmark^^J%
            }%
        }% end of \@for
    \fi
}
%    \end{macrocode}
% These are the key-value pairs used for defining cue points, they
% are \texttt{type}, \texttt{name}, \texttt{time}, and
% \texttt{action}. These keys are entered as a value of the
% \texttt{cuepoints} key, like so,
%\begin{verbatim}
%\newcommand{\myCuePoints}{%
% {type=nav,name=Chapter1,time=0,action={console.println("Chapter1")}},%
% {type=nav,name=Chapter2,time=1883,action={console.println("Chapter2")}},%
% {type=nav,name=Chapter3,time=5197,action={console.println("Chapter3")}},%
% {type=nav,name=Chapter4,time=6817,action={console.println("Chapter4")}},%
% {type=nav,name=Chapter5,time=9114,action={console.println("Chapter6")}},%
% {type=nav,name=Chapter6,time=12712,action={console.println("Chapter6")}}
%}
%\end{verbatim}
% Note the use of the comment symbol \texttt{\%} following at the end of each line.
% We define the cue points using a command, then pass it to \cs{rmAnnot}, like so,
%\begin{verbatim}
%   \rmAnnot[cuepoints={\myCuePoints}]{320bp}{240bp}{sample}
%\end{verbatim}
% Note the parentheses around \cs{myCuePoints}, the command expands to contain commas,
% so the rules of \textsf{xkeyval} say to enclose in parentheses.
%
% The structure generated in the PDF file seems to be correct, but we get JavaScript errors.
% Could this be a bug in Acrobat? For now, this a temporary feature.
%
%    \begin{macrocode}
\define@choicekey+{rmCuePt}{type}[\val\nr]%
    {event,nav}[nav]{%
    \ifcase\nr\relax
        \def\rma@rmCuePt@type{/Event}\or
        \def\rma@rmCuePt@type{/Navigation}\fi
}{\PackageWarning{rmannot}{Bad choice for type, permissible values
   are event and nav. Try again}}
\define@key{rmCuePt}{name}[]{%
    \def\rma@rmCuePt@name{#1}%
}
\define@key{rmCuePt}{time}[0]{%
    \def\rma@rmCuePt@time{#1}%
}
\define@key{rmCuePt}{action}[]{%
    \def\rma@rmCuePt@action{#1}%
}
%    \end{macrocode}
%    \end{macro}
%
% \paragraph*{Default values of key-values pairs.} We set the default values of all the keys on startup.
%    \begin{macrocode}
\setkeys{rmAnnot}{name,url=false,enabled,deactivated,borderwidth,%
    windowed=false,poster,posternote,skin,skinAutoHide,skinBGColor,%
    skinBGAlpha,volume,speed,playcount,resources,flashvars,%
    transparentBG=false,passcontext=false,cuepoints,toolbar,%
    modeltree=false}
%    \end{macrocode}
%
% \subsection{The definition of \texorpdfstring{\cs{rmAnnot}}{\CMD{rmAnnot}}}
%
% The following two utility commands are used in the definition of \cs{rmAnnot}
% to record the embedding of the video/audio player, and to set switches to prevent
% the re-embedding of the player again.
%    \begin{macrocode}
\def\rma@recordVideoPlayer{%
    \ifrma@EmbedVideoPlayer
        \global\let\rma@isVPEmbedded=1\global\rma@EmbedVideoPlayerfalse
    \else
        \if\rma@isVPEmbedded0\global\rma@EmbedVideoPlayertrue\fi
    \fi
}
\def\rma@recordAudioPlayer{%
    \ifrma@EmbedAudioPlayer
        \global\let\rma@isAPEmbedded=1\global\rma@EmbedAudioPlayerfalse
    \else
        \if\rma@isAPEmbedded0\global\rma@EmbedAudioPlayertrue\fi
%    \end{macrocode}
% If the file is \textsf{MP3}, and there is no poster defined for it, we use the default
% \textsf{MP3} poster, a screen shot of the \texttt{AudioPlayer} controls.
%    \begin{macrocode}
        \ifx\rma@rmAnnot@poster\@empty\rma@set@mpiiiposter\fi
    \fi
}
%    \end{macrocode}
% A switch to indicate success or failure when looking for a Video extension. Used
% in \cs{rmAnnot}.
%    \begin{macrocode}
\newif\if@FndSuppExt \@FndSuppExtfalse
%    \end{macrocode}
%    \begin{macro}{\rmAnnot}
%The \cs{rmAnnot} command creates a rich media annotation. This package
%supports file types \textsf{SWF}, \textsf{FLV}, \textsf{F4V},
%\textsf{MP4}, \textsf{M4V}, \textsf{MOV}, \textsf{3GP}, \textsf{3G2}, and
%\textsf{MP3}, the latter being a sound format. The command takes
%four parameters, the first optional, the others required.
%\begin{enumerate}
%   \item[\texttt{[\#1]}:] Insert key-value pairs for changing the appearance, launch, and control settings
%   \item[\texttt{\#2}:] The width of the annot
%   \item[\texttt{\#3}:] The height of the annot
%   \item[\texttt{\#4}:] The name of the file to play (the name is defined by the \cs{saveNamedPath} command)
%\end{enumerate}
%    \begin{macrocode}
\newcommand{\rmAnnot}[4][]{\begingroup
%    \end{macrocode}
% We \cs{let} \cs{Name} to \cs{rma@resource}. The author can then refer to
% the name of the resource within, for example, the \texttt{flashvars} key.
%    \begin{macrocode}
    \let\Name\rma@resource
    \let\urlName\rma@urlresource
    \makeJSspecials
%    \end{macrocode}
% Empty these to macros for they might contain content from a previous
% annot with resources.
%    \begin{macrocode}
    \let\rma@addResources\@empty\let\rma@addFileSpecs\@empty
%    \end{macrocode}
% We begin by passing the dimensions through a length so the author
% can use the \texttt{calc} package.
%    \begin{macrocode}
    {\setlength{\dimen@}{#2}\xdef\rm@Annot@width{\the\dimen@}%
     \setlength{\dimen@}{#3}\xdef\rm@Annot@height{\the\dimen@}}%
%    \end{macrocode}
% Next we increment a running counter, to give each annot, and all indirect
% references a unique name.
%    \begin{macrocode}
    \stepcounter{rm@Cnt}%
%    \end{macrocode}
% We take the 4th parameter, a named path, and pass it to \cs{useNamedPath},
% then use \cs{filename@parse} to extract the components of the path.
%    \begin{macrocode}
    \rma@edefexecute{\noexpand\filename@parse{\rma@useNamedPath{#4}}}%
%    \end{macrocode}
% We record this named path as \verb!rmFileStrm#4!, if this command is
% undefined, we define it. It's value is the indirect reference to the
% steam; if already defined, the command should contain the indirect
% reference to the same file that has been already embedded. If undefined
% we set a boolean to embed this stream, otherwise, we don't embed.
%    \begin{macrocode}
    \edef\rma@fs@expand{rmFileStrm#4}\@ifundefined{\rma@fs@expand}{%
    \expandafter\xdef\csname\rma@fs@expand\endcsname
        {rmfstream\therm@Cnt}\global\rma@EmbedFiletrue}%
        {\global\rma@EmbedFilefalse}%
%    \end{macrocode}
% After having parsed the path, we now save the pieces for later use.
%    \begin{macrocode}
    \edef\rma@thisfilepath{\filename@area}%
    \edef\rma@basefilename{\filename@base}%
    \edef\rma@extension{\filename@ext}%
    \rma@edefexecute{\noexpand\uppercase{\noexpand
        \def\noexpand\rma@tempi{\rma@extension}}}%
%    \end{macrocode}
% Take a look at the file extension, if it is a 3D type extension,
% mark it as a RM3D annot by setting \cs{rma@isiiidtrue}.
%    \begin{macrocode}
    \ifx\rma@tempi\rma@rmAnnot@type@uiiid\rma@isiiidtrue
        \else\ifx\rma@tempi\rma@rmAnnot@type@prc\rma@isiiidtrue
        \else\rma@isiiidfalse
    \fi\fi
%    \end{macrocode}
% \paragraph*{Process Options.} We finally get around to processing the options.
% We put \cs{setkeys} in an \cs{edef} to allow the user to use macros to specify
% some of the options. The next line are the options passed by \texttt{\#1} of
% \cs{rmAnnot}.
%    \begin{macrocode}
    \rma@edefexecute{\noexpand\setkeys{rmAnnot}{#1}}%
\ifx\rma@input@iiidCode\relax\else
\ifrma@isiiid
%    \end{macrocode}
% Process the options of the RM3D annot, as passed to us by \cs{setRmOptions3D}.
%    \begin{macrocode}
    \@ifundefined{\rma@Annot@name_3DOPTS}{%
%    \end{macrocode}
% \textbf{To Do.} Here, we can insert some default options if the user did not
% specify anything. Including a reminder to make a declaration.
%    \begin{macrocode}
    }{%
%    \end{macrocode}
% If the user has specified the \texttt{use3D} option and
% the file specified in \texttt{\#4} is a 3D model (U3D or PRC),
% then the switch \cs{ifrma@isiiid} is true, and we process
% any 3D options as specified by \cs{setRmOptions3D}. The command
% sequence \cs{rma@Annot@name\_3DOPTS} is defined for this annot
% by \cs{setRmOptions3D}; we only process if there are options
% for this annot.
%    \begin{macrocode}
        \def\rma@Instances{}\def\rma@appendToNameTree{}%
%    \end{macrocode}
% Expand the arguments of \cs{setkeys} before allowing
% \cs{setkeys} to execute.
%    \begin{macrocode}
        \rma@edefexecute{\noexpand\setkeys{rm3DOptsTopLevel}%
            {\@nameuse{\rma@Annot@name_3DOPTS}}}%
        \edef\additional@Instances{\rma@Instances}%
        \edef\rma@addResources{\rma@appendToNameTree}%
%    \end{macrocode}
% \paragraph*{3Djscript:} We determine if there is one or more
% javascript files specified.
%    \begin{macrocode}
        \ifx\rma@rmAnnot@iiiDjs\@empty\else
            \def\@MXV@jscriptiiid{}%
            \literalps@out{%
                \ps@mark/_objdef {jscriptiiid\therm@Cnt}%
                    /type/array/OBJ pdfmark^^J%
                \rmiiid@addToScriptsArray
                \rma@addFileSpecs
            }%
%    \end{macrocode}
% We save the key-value pair for the \texttt{Scripts} key.
%    \begin{macrocode}
            \edef\@MXV@jscriptiiid{%
                /Scripts {jscriptiiid\therm@Cnt}%
            }%
        \fi
%    \end{macrocode}
% Build the array of 3D views
%    \begin{macrocode}
        \@MXV@buildva%
    }%
\fi\fi
%    \end{macrocode}
% \paragraph*{Identify the Extension.} We try to identify the extension provided
% by the author. We take the \cs{filename@base} (saved as \cs{rma@extension}), convert
% it to upper case and compare with the text macros containing \textsf{SWF}, \textsf{FLV}, \textsf{MP3},
% or one of the other supported extensions. The macro \cs{rma@tempi} contains the upper case
% form of the extension.
%    \begin{macrocode}
    \rma@edefexecute{\noexpand\uppercase{\noexpand
        \def\noexpand\rma@tempi{\rma@extension}}}%
%    \end{macrocode}
% \subparagraph*{3D Model.} Search for a \textsf{U3D} or \textsf{PRC}. We earlier
% did a test to see if this is 3D or not, so the boolean \cs{ifrma@isiiid} has already
% been set.
%    \begin{macrocode}
\ifrma@isiiid
    \def\rma@poster@descrip{3D}%
    \def\rma@RMCSubtype{/3D}%
    \ifx\rma@tempi\rma@rmAnnot@type@uiiid
        \def\rma@rmAnnot@type{U3D}%
        \edef\rma@mimeType{\rma@mimetype@uiiid}%
    \else
    \ifx\rma@tempi\rma@rmAnnot@type@prc
        \def\rma@rmAnnot@type{PRC}%
        \edef\rma@mimeType{\rma@mimetype@prc}%
    \fi\fi
\else
%    \end{macrocode}
% Not a 3D model, so we'll check for more conventional types.
%
% \subparagraph*{Flash Application.} Search for a \textsf{SWF} file, we set the identifiers for later use.
%    \begin{macrocode}
    \def\rma@poster@descrip{Flash}%
    \ifx\rma@tempi\rma@rmAnnot@type@swf
        \def\rma@rmAnnot@type{SWF}\edef\rma@mimeType{\rma@mimetype@swf}%
        \def\rma@RMCSubtype{/Flash}%
    \else % if not flash
%    \end{macrocode}
% \subparagraph*{Video Formats.} We search for extension that is generally classified
% as video.
%    \begin{macrocode}
    \def\rma@poster@descrip{Video}\def\rma@rmAnnot@type{FLV}%
    \@FndSuppExtfalse
    \@tfor\rma@type:={flv}{fiv}{mpiv}{mivV}{mov}{iiiGP}{iiiGii}\do{%
        \expandafter\ifx\expandafter\rma@tempi\csname%
         rma@rmAnnot@type@\rma@type\endcsname
         \@FndSuppExttrue
            \edef\rma@mimeType{\csname%
                rma@mimetype@\rma@type\endcsname}%
            \rma@recordVideoPlayer\@break@tfor
        \fi
    }%
    \if@FndSuppExt
        \def\rma@RMCSubtype{/Video}%
        \xdef\FileStrmVideoPlayer{rmVideoPlayer\therm@Cnt}%
    \else % if not video
%    \end{macrocode}
% \subparagraph*{Audio Formats.} Test for a \textsf{MP3} file, we need
% to embed the \texttt{AudioPlayer} once and only once. The Boolean
% \cs{ifrma@EmbedAudioPlayer} and the marker \cs{rma@isAPEmbedded} are used
% to keep track of whether the player has been embedded.
%    \begin{macrocode}
    \ifx\rma@tempi\rma@rmAnnot@type@mpiii
    \def\rma@rmAnnot@type{MP3}\edef\rma@mimeType{\rma@mimetype@mpiii}%
    \def\rma@poster@descrip{MP3}\def\rma@RMCSubtype{/Sound}%
    \xdef\FileStrmAudioPlayer{rmAudioPlayer\therm@Cnt}%
    \let\rma@rmAnnot@resources\@empty
    \rma@recordAudioPlayer
    \else % not mp3
%    \end{macrocode}
% \subparagraph*{Error.} The extension is not recognized.
%    \begin{macrocode}
        \rma@PkEr@i
%    \end{macrocode}
% end testing for 3D (u3d and prc), flash, video, and audio
%    \begin{macrocode}
\fi\fi\fi\fi
%    \end{macrocode}
% Define \cs{rma@thisfileName} and \cs{rma@fullpath} for later use.
%    \begin{macrocode}
    \def\rma@thisfileName{\rma@basefilename.\rma@extension}%
    \def\rma@fullpath{\rma@thisfilepath\rma@thisfileName}%
%    \end{macrocode}
% If this is an FLV video file, we don't let the user created flash variables
%    \begin{macrocode}
    \ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv
        \let\rma@rmAnnot@flashvars\@empty\fi
    \ifx\rma@rmAnnot@type\rma@rmAnnot@type@mpiii
        \let\rma@rmAnnot@flashvars\@empty\fi
%    \end{macrocode}
% If there is no poster, we supply one. For \textsf{MP3}, it is an image of
% the \texttt{AudioPlayer} controls, otherwise, it is the default poster.
%    \begin{macrocode}
\ifx\rma@rmAnnot@poster\@empty
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@mpiii
    \def\rma@rmAnnot@poster{nramp3poster}%
\else
    \Gin@defaultbp\this@width\rm@Annot@width
    \Gin@defaultbp\this@height\rm@Annot@height
    \ifdim\rm@Annot@width < \rm@Annot@height
        \edef\calc@prop{\this@width}\else
        \edef\calc@prop{\this@height}\fi
    \def\this@bbox{0 0 \this@width\space\this@height}%
    \begin{sp@createImage}{\this@bbox}{rmAP@#4@\therm@Cnt}%
    \rma@invisible
    \rma@psgraphics@poster
    \end{sp@createImage}%
    \def\rma@rmAnnot@poster{rmAP@#4@\therm@Cnt}%
\fi\fi
%    \end{macrocode}
% \paragraph*{Begin the construction of the RMA.}
% Place the dimensions input by the author in a \cs{Bbox} within \cs{pdf@rect}.
% \cs{Bbox} is defined in the \textsf{eForms} package.
%    \begin{macrocode}
    \pdf@rect{\Bbox{\rm@Annot@width}{\rm@Annot@height}}%
%    \end{macrocode}
%    \begin{macrocode}
    \@MXV@newlabel{rmAnnot_\rma@Annot@name}{rmAnnot\therm@Cnt}%
    \@MXV@labeltoaux{rmAnnot_\rma@Annot@name}{rmAnnot\therm@Cnt}%
%    \end{macrocode}
% Begin writing the rich media annotation through a PostScript special.
% The command \cs{literalps@out} is defined in \textsf{hyperref}.
%    \begin{macrocode}
    \literalps@out{%
%    \end{macrocode}
%
% \paragraph*{Create the RichMedia Annotation.}
%
%    \begin{macrocode}
  \ps@mark/_objdef {rmAnnot\therm@Cnt}%
    /Type/Annot%
    /Subtype/RichMedia%
    /NM (\rma@Annot@name)%                  % Annotation name
\ifx\rma@rmAnnot@poster\@empty\else
    /AP <</N {\rma@rmAnnot@poster}>>%       % poster appearance
\fi
    /F 68%                                  % Annotation flags
    /P {ThisPage}%                          % Parent
    /Border [ 0 0 \rma@rmAnnot@borderwidth ]% Border
    /BS <</Type/Border%                     % Border Style dictionary
        /W \rma@rmAnnot@borderwidth%        % Width
        /S/S%                               % Border style (Solid)
    >>%
%    \end{macrocode}
% The \textbf{RichMedia} annot has a \textbf{RichMediaContent} dictionary, and
% a \textbf{RichMediaSettings} dictionary, give indirect references
% to these.
%    \begin{macrocode}
    /RichMediaContent {rmContent\therm@Cnt}%
    /RichMediaSettings {rmSettings\therm@Cnt}
    H.B /ANN pdfmark^^J%
%    \end{macrocode}
%
% \paragraph*{The RichMediaContent dictionary.} We include the
% \texttt{Configurations} key, an array of indirect references to
% \texttt{RichMediaConfiguration} dictionaries, and the
% \texttt{Assets} key, an indirect reference to the Assets
% dictionary.
%
%    \begin{macrocode}
    \ps@mark/_objdef {rmContent\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmContent\therm@Cnt} <<%
        /Type/RichMediaContent%
%    \end{macrocode}
% If this is a RM3DA, we declare it in the \texttt{RichMediaContent}
% dictionary. Here we declare \texttt{/Subtype/3D} and insert a views
% array.
%    \begin{macrocode}
\ifrma@isiiid
        /Subtype/3D%
\ifx\@MXV@varray\@empty\else
        /Views [\@MXV@varray]%
\fi\fi
        /Configurations [{rmConfig\therm@Cnt}]%
        /Assets {rmAssets\therm@Cnt}%
    >>/PUT pdfmark^^J%
%    \end{macrocode}
%
% \paragraph*{The RichMediaConfiguration dictionary.} We set the primary
% content type of the configuration (\texttt{Flash}, \texttt{Video}, or \texttt{Sound}),
% and reference the corresponding instances, the \textsf{SWF} file to play, the \texttt{VideoPlayer} to
% play a \textsf{FLV} file, and the \texttt{AudioPlayer}, to play \textsf{MP3} files.
%
%    \begin{macrocode}
    \ps@mark/_objdef {rmConfig\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmConfig\therm@Cnt} <<%
        /Type/RichMediaConfiguration%
        /Name (RMConfig\therm@Cnt)%
%    \end{macrocode}
% The \texttt{Subtype} is \texttt{3D}, \texttt{Flash}, \texttt{Video}, or \texttt{Sound},
% here, \cs{rma@RMCSubtype} was determined earlier.
%    \begin{macrocode}
        /Subtype\rma@RMCSubtype%
        /Instances {rmInstances\therm@Cnt}%
    >> /PUT pdfmark^^J%
%    \end{macrocode}
% \paragraph*{The Instances Array.}\strut\par\medskip\noindent
% This version of the Instances array is used, same as the SWF version.
%    \begin{macrocode}
    \ps@mark/_objdef {rmInstances\therm@Cnt}/type/array/OBJ pdfmark^^J%
\ifrma@isiiid
    \ps@mark{rmInstances\therm@Cnt} {rmInstance\therm@Cnt}%
        /APPEND pdfmark^^J%
    \additional@Instances
\else
%    \end{macrocode}
% We load the indirect reference to the VideoPlayer
%    \begin{macrocode}
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv
    \ps@mark{rmInstances\therm@Cnt} {rmVideoPlayer\therm@Cnt}%
        /APPEND pdfmark^^J%
\else\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf
%    \end{macrocode}
% The Instances array will be populated later by resources.
%    \begin{macrocode}
    \ps@mark{rmInstances\therm@Cnt} {rmInstance\therm@Cnt}%
        /APPEND pdfmark^^J%
\else
%    \end{macrocode}
% We load the indirect reference to the AudioPlayer
%    \begin{macrocode}
    \ps@mark{rmInstances\therm@Cnt} {rmAudioPlayer\therm@Cnt}%
        /APPEND pdfmark^^J%
\fi\fi\fi
%    \end{macrocode}
%
% \paragraph*{The Assets name tree.} Reference by the \texttt{RichMediaContent} dictionary,
% this name tree lists the files needed, and indirect references to their respective
% file specification dictionaries. The assets are a function of whether the file type
% is \textsf{SWF}, \textsf{FLV} or \textsf{MP3}. For \textsf{FLV}, there are a number of skins that can be selected from, so
% the skin select through the skin key is included as assets, and its corresponding \textsf{SWF} needs
% to be embedded, if not embedded already.
%    \begin{macrocode}
    \ps@mark/_objdef {rmAssets\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmAssets\therm@Cnt} <<%
        /Names {\rma@ANT}>>/PUT pdfmark^^J%
    \ps@mark/_objdef {\rma@ANT}/type/array/OBJ pdfmark^^J%
\ifrma@isiiid
    \ps@mark{\rma@ANT} (\rma@thisfileName) /APPEND pdfmark^^J%
    \ps@mark{\rma@ANT} {rmfilespec\therm@Cnt} /APPEND pdfmark^^J%
    \rma@addResources
\else
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf
    \ifKV@rmAnnot@url\else
        \ps@mark{\rma@ANT} (\rma@thisfileName)/APPEND pdfmark^^J%
        \ps@mark{\rma@ANT} {rmfilespec\therm@Cnt}/APPEND pdfmark^^J%
        \rma@addResources
    \fi
\else\ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv
    \ifKV@rmAnnot@url\else
        \ps@mark{\rma@ANT} (\rma@thisfileName)/APPEND pdfmark^^J%
        \ps@mark{\rma@ANT} {rmfilespec\therm@Cnt}/APPEND pdfmark^^J%
        \ifVideoPlayerEx\rma@addResources\fi
    \fi
    \ifx\rma@rmAnnot@Skin\@empty\else
        \ps@mark{\rma@ANT} (\rma@rmAnnot@Skin)/APPEND pdfmark^^J%
        \ps@mark{\rma@ANT} {rmfilespecSkin\rma@skinName}%
            /APPEND pdfmark^^J%
    \fi
    \ps@mark{\rma@ANT} (\rma@VideoPlayer)/APPEND pdfmark^^J%
    \ps@mark{\rma@ANT} {rmfilespecVP}/APPEND pdfmark^^J%
\else
    \ps@mark{\rma@ANT} (AudioPlayer.swf)/APPEND pdfmark^^J%
    \ps@mark{\rma@ANT} {rmfilespecAP}/APPEND pdfmark^^J%
    \ps@mark{\rma@ANT} (\rma@thisfileName)/APPEND pdfmark^^J%
    \ps@mark{\rma@ANT} {rmfilespec\therm@Cnt}/APPEND pdfmark^^J%
\fi\fi\fi
%    \end{macrocode}
%
% \paragraph*{The \texttt{RichMediaInstance} dictionary.} Describes a single instance of an asset.
% The asset being described is the \texttt{VideoPlayer} (in the case of \textsf{FLV} files),
% the Flash file in the case of \textsf{SWF} files, and the \texttt{AudioPlayer} (for \textsf{MP3} files).
%
%    \begin{macrocode}
\ifrma@isiiid
    \ps@mark/_objdef {rmInstance\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmInstance\therm@Cnt}%
\else
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv
    \ps@mark/_objdef {rmVideoPlayer\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmVideoPlayer\therm@Cnt}%
\else\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf
    \ps@mark/_objdef {rmInstance\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmInstance\therm@Cnt}%
\else
    \ps@mark/_objdef {rmAudioPlayer\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmAudioPlayer\therm@Cnt}%
\fi\fi\fi
    <<%
        /Type/RichMediaInstance%
\ifrma@isiiid
        /Subtype/3D%
        /Asset {rmfilespec\therm@Cnt}%
\else
        /Subtype/Flash%
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv
        /Asset {rmfilespecVP}%
\else\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf
        /Asset {rmfilespec\therm@Cnt}%
\else
        /Asset {rmfilespecAP}%
\fi\fi\fi
\ifrma@isiiid\else
        /Params {rmParams\therm@Cnt}%
\fi
    >> /PUT pdfmark^^J%
%    \end{macrocode}
%
% \paragraph*{The Params dictionary.} Contains parameters
% related to an active Flash subtype in a \texttt{RichMediaInstance}
% dictionary; the user, through the UI or through this package, can set
% the value of the \texttt{FlashVars} entry. For content subtypes other
% than Flash, the argument for \texttt{FlashVars} is not under user control,
% and is determined by the PDF creation application, this package.
%
%    \begin{macrocode}
    \ps@mark/_objdef {rmParams\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmParams\therm@Cnt} <<%
        /Type/RichMediaParams%
%    \end{macrocode}
% If there are no additional resources specified, we bind the animation
% to the  background, if there are (\textsf{SWF}) resources, we bind to the foreground.
%    \begin{macrocode}
\ifrma@isiiid\else
\ifx\rma@rmAnnot@resources\@empty
        /Binding/Background%
\else
        /Binding/Foreground%
\fi\fi
%    \end{macrocode}
% If this is a FLV (video), we use the custom flash variables of Acrobat (reverse engineering).
% If it is a url, we specify the full URL, otherwise, we specify the file name as the source.
%    \begin{macrocode}
\ifrma@isiiid\else
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv
    \ifKV@rmAnnot@url
        /FlashVars (source=\rma@fullpath&%
    \else
        /FlashVars (source=\rma@thisfileName&%
    \fi
    \ifx\rma@rmAnnot@Skin\@empty\else
        skin=\rma@rmAnnot@Skin&%
    \fi
        skinAutoHide=\rma@skinAutoHide&%
        skinBackgroundColor=\rma@skinBGColor&%
        skinBackgroundAlpha=\rma@skinBGAlpha&%
        volume=\rma@rmAnnot@volume)
\ifx\rma@rmAnnot@cuepoints\@empty\else
        /CuePoints [\rma@array@hold]%
\fi
\else\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf
%    \end{macrocode}
% If this is a \textsf{SWF} file, we allow the author to introduce custom flash variables,
% hope s/he knows what is s/he is doing.
%    \begin{macrocode}
    \ifx\rma@rmAnnot@flashvars\@empty\else
        /FlashVars (\rma@rmAnnot@flashvars)%
    \fi
\else
        /FlashVars (source=\ifKV@rmAnnot@url\rma@fullpath\else
            \rma@thisfileName\fi&autoPlay=true&%
            volume=\rma@rmAnnot@volume)%
\fi\fi\fi
    >> /PUT pdfmark^^J%
%    \end{macrocode}
%
% \paragraph*{The RichMediaSettings Dictionary.} The second dictionary
% referenced in the \texttt{RichMedia} annot is the \texttt{RichMediaSettings} dictionary.
% The \texttt{RichMediaSettings} dictionary stores the conditions and responses
% that occur in response to certain events, such as activation and
% deactivation of the annotation, and contains two dictionaries.
%
%    \begin{macrocode}
    \ps@mark/_objdef {rmSettings\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmSettings\therm@Cnt} <<%
        /Type/RichMediaSettings%
%    \end{macrocode}
% The Activation key is a dictionary that describes how the annot is to be activated
% and played.
%    \begin{macrocode}
        /Activation <<%
            /Type/RichMediaActivation%
            /Condition\rma@rmAnnot@enabled
            /Configuration {rmConfig\therm@Cnt}%
%    \end{macrocode}
% (2011/11/08) Used for Keyframe animation, normally not needed. Will uncomment when I
% develop an example of usage. Note, the \texttt{speed} and \texttt{playcount} keys are now ignored.
%    \begin{macrocode}
\ifrma@isiiid
           /Animation%
            <<%
                /Type/RichMediaAnimation%
                /Subtype/Linear%
                /Speed \rma@rmAnnot@speed
                /PlayCount \rma@rmAnnot@playcount
            >>%
\ifx\@MXV@defaultview\@empty\else
             /View \@MXV@defaultview
\fi
\ifx\@MXV@jscriptiiid\@empty\else
            \@MXV@jscriptiiid
\fi\fi
            /Presentation {rmPresentation\therm@Cnt}%
        >>
%    \end{macrocode}
% The Deactivation key is a dictionary that describes how the annot is to be deactivated.
%    \begin{macrocode}
        /Deactivation<<%
            /Type/RichMediaDeactivation%
            /Condition\rma@rmAnnot@deactivated
        >>%
>>/PUT pdfmark^^J%
%    \end{macrocode}
% \paragraph*{The CuePoints Array.}
%
%    \begin{macrocode}
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv
\ifx\rma@rmAnnot@cuepoints\@empty\else\rma@dict@hold\fi\fi
%    \end{macrocode}
%
% \paragraph*{The RichMediaPresentation Dictionary.} Referenced within
% the Activation entry of the RichMediaSettings dictionary above, this
% dictionary determines whether the background is transparent, and whether
% the media is to be played within the page or in a floating window.
%
%    \begin{macrocode}
    \ps@mark/_objdef {rmPresentation\therm@Cnt}%
        /type/dict/OBJ pdfmark^^J%
    \ps@mark{rmPresentation\therm@Cnt}<<%
        /Type/RichMediaPresentation%
\ifrma@isiiid
        /NavigationPane \rma@rmAnnot@modeltree % need key
        /Toolbar \rma@rmAnnot@toolbar % need key
        /Transparent \rma@rmAnnot@transparent
\else
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf
        /Transparent \rma@rmAnnot@transparent
        /PassContextClick \rma@rmAnnot@PassContextClick
        /NavigationPan false%
\else
        /Transparent false%
        /NavigationPan false%
\fi\fi
\ifKV@rmAnnot@windowed
        /Style/Windowed%
        /Window {rmWindow\therm@Cnt}%
\else
        /Style/Embedded%
\fi
    >>/PUT pdfmark^^J%
%    \end{macrocode}
%
% \paragraph*{The RichMediaWindow Dictionary.} When the style is Windowed
% as specified in the \texttt{RichMediaPresentation} dictionary, we include
% the \texttt{RichMediaWindow} dictionary to set the parameters of the window.
% Currently, the parameters are hard-wired to the defaults, as specified by
% the \textsl{Adobe Suppl. Doc}.
%
%    \begin{macrocode}
\ifKV@rmAnnot@windowed
    \ps@mark/_objdef {rmWindow\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmWindow\therm@Cnt}<<%
        /Type/RichMediaWindow%
        /Height<<%
            /Default \rma@winDimPosHeight@def
            /Max \rma@winDimPosHeight@max
            /Min \rma@winDimPosHeight@min
        >>%
        /Width<<%
            /Default \rma@winDimPosWidth@def
            /Max \rma@winDimPosWidth@max
            /Min \rma@winDimPosWidth@min
        >>%
        /Position<<%
            /Type/RichMediaPosition % RichMediaPosition dictionary
            /HAlign\rma@winDimPosPos@halign
            /VAlign\rma@winDimPosPos@valign
            /HOffset \rma@winDimPosPos@hoffset
            /VOffset \rma@winDimPosPos@voffset
        >>%
    >>/PUT pdfmark^^J%
\fi
%    \end{macrocode}
%
% \paragraph*{File Specifications and Streams.} In this section, we
% insert the Filespec dictionaries of the various assets. There are
% four type of assets: (1) the one specified by the 4th argument of
% the \cs{rmAnnot}; (2) additional assets specified through the
% \texttt{resources} key; (3) the VideoPlayer; and (4) the AudioPlayer.
% The first two we'll call \textit{Author Supplied Assets}, the latter two, we'll
% call \textit{System Supplied Assets}.
%
% \paragraph*{Author Supplied Assets.} We first insert the file spec and stream for
% the 4th parameter, its filename is \cs{rma@thisfileName} and its full path name is
% \cs{rma@fullpath}.
%
% \subparagraph*{File specs: Filespec dictionary}
%    \begin{macrocode}
    \ps@mark/_objdef {rmfilespec\therm@Cnt}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmfilespec\therm@Cnt} <<%
\ifKV@rmAnnot@url
        /F(\rma@fullpath)%
        /FS/URL%
\else
        /F(\rma@thisfileName)%
        /UF (\rma@thisfileName)%
        /EF <</F {\csname rmFileStrm#4\endcsname}>>
\fi
        /Type/Filespec
    >>/PUT pdfmark^^J%
%    \end{macrocode}
% \paragraph*{File stream: EmbeddedFile dictionary}
%    \begin{macrocode}
\ifKV@rmAnnot@url\else
\ifrma@EmbedFile
    \ps@mark/_objdef {\csname rmFileStrm#4\endcsname}%
        /type/stream/OBJ pdfmark^^J%
    \ps@mark{\csname rmFileStrm#4\endcsname} (\rma@fullpath)
        (r) file /PUT pdfmark^^J%
    \ps@mark{\csname rmFileStrm#4\endcsname} <<%
        /Type/EmbeddedFile%
        /Subtype(\rma@mimeType)%
    >>/PUT pdfmark^^J%
    \ps@mark{\csname rmFileStrm#4\endcsname} /CLOSE pdfmark^^J%
\fi\fi
%    \end{macrocode}
% If we are dealing with a \textsf{SWF} or 3D file, we'll then include additional file specs and streams
% as specified by the \texttt{resources} key of \cs{rmAnnot}.
%    \begin{macrocode}
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf\rma@addFileSpecs\fi
\ifrma@isiiid\rma@addFileSpecs\fi
%    \end{macrocode}
%
% \paragraph*{System Supplied Assets.} We have the various skins, the \texttt{VideoPlayer}, and
% the \texttt{AudioPlayer}. We'll start with the skins.
%
% \paragraph*{File specs for skin}
%    \begin{macrocode}
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv
\ifVideoPlayerEx\rma@addFileSpecs\fi
\ifx\rma@rmAnnot@Skin\@empty\else
    \ps@mark/_objdef {rmfilespecSkin\rma@skinName}%
        /type/dict/OBJ pdfmark^^J%
    \ps@mark{rmfilespecSkin\rma@skinName} <<%
        /F (\rma@rmAnnot@Skin)%
        /Type/Filespec%
        /UF (\rma@rmAnnot@Skin)%
        /EF <</F {rmfstreamSkin\rma@skinName}>>
    >>/PUT pdfmark^^J%
%    \end{macrocode}
%\paragraph*{File stream for skin}
%    \begin{macrocode}
\expandafter\if\csname embedSkin\rma@skinName\endcsname1
    \ps@mark/_objdef {rmfstreamSkin\rma@skinName}%
        /type/stream/OBJ pdfmark^^J%
    \ps@mark{rmfstreamSkin\rma@skinName}%
        (\rma@pathToSkins/\rma@rmAnnot@Skin) (r) file%
        /PUT pdfmark^^J%
    \ps@mark{rmfstreamSkin\rma@skinName} <<%
        /Type/EmbeddedFile
        /Subtype (\rma@mimetype@swf)
    >>/PUT pdfmark^^J%
    \ps@mark{rmfstreamSkin\rma@skinName}/CLOSE pdfmark^^J%
\fi\fi\fi
%    \end{macrocode}
% Now the specs and stream of the \texttt{VideoPlayer}
%
%\paragraph*{File specs for video player}
%    \begin{macrocode}
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv
    \ps@mark/_objdef {rmfilespecVP}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmfilespecVP} <<%
        /Type/Filespec%
        /F (\rma@VideoPlayer)%
        /UF (\rma@VideoPlayer)%
        /EF <</F {rmfstreamVP}>>
    >>/PUT pdfmark^^J%
%    \end{macrocode}
% We'll only embed once, provided \cs{ifrma@EmbedVideoPlayer} is true.
%
% \paragraph*{File stream for video player}
%    \begin{macrocode}
\ifrma@EmbedVideoPlayer
    \ps@mark/_objdef {rmfstreamVP}/type/stream/OBJ pdfmark^^J%
    \ps@mark{rmfstreamVP} (\rma@pathToPlayers/\rma@VideoPlayer)
        (r) file /PUT pdfmark^^J%
    \ps@mark{rmfstreamVP} <<%
        /Type/EmbeddedFile%
        /Subtype (\rma@mimetype@swf)%
    >>/PUT pdfmark^^J%
    \ps@mark{rmfstreamVP} /CLOSE pdfmark^^J%
\fi\fi
%    \end{macrocode}
% Now the specs and stream of the \texttt{AudioPlayer}
%
% \paragraph*{File specs for audio player}
%    \begin{macrocode}
\ifx\rma@rmAnnot@type\rma@rmAnnot@type@mpiii
    \ps@mark/_objdef {rmfilespecAP}/type/dict/OBJ pdfmark^^J%
    \ps@mark{rmfilespecAP} <<%
        /F (AudioPlayer.swf)%
        /Type/Filespec%
        /UF (AudioPlayer.swf)%
        /EF <</F {rmfstreamAP}>>%
    >>/PUT pdfmark^^J%
%    \end{macrocode}
% We'll only embed once, provided \cs{ifrma@EmbedAudioPlayer} is true.
%
%\paragraph*{File stream for audio player}
%    \begin{macrocode}
\ifrma@EmbedAudioPlayer
    \ps@mark/_objdef {rmfstreamAP}/type/stream/OBJ pdfmark^^J%
    \ps@mark{rmfstreamAP}(\rma@pathToPlayers/AudioPlayer.swf)
        (r) file /PUT pdfmark^^J%
    \ps@mark{rmfstreamAP} <<%
        /Type/EmbeddedFile%
        /Subtype (\rma@mimetype@mpiii)%
    >>/PUT pdfmark^^J%
    \ps@mark{rmfstreamAP} /CLOSE pdfmark^^J%
\fi\fi}%
%    \end{macrocode}
% If we are using user defined skins, we set the skin just used
% so that this skin will not be embedded a second time, let's hope.
%    \begin{macrocode}
\ifx\rma@rmAnnot@type@flv\rma@rmAnnot@type
\ifx\rma@rmAnnot@Skin\@empty\else
\expandafter\global\expandafter
    \let\csname embedSkin\rma@skinName\endcsname=0\relax
\fi\fi
%    \end{macrocode}
% \paragraph*{End of \cs{rmAnnot}.} Close off the group, and end the \cs{rmAnnot} command definition.
%    \begin{macrocode}
\endgroup}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{Poster Appearances}
%
%    \begin{macro}{\defaultPoster}
%
% The command \cs{defaultPoster} defines the default poster
% appearance and is used when a poster appearance is not specified
% by the \texttt{poster} key. If the file is an \textsf{MP3}, then there is
% a graphic that is the default poster appearance.
%
% \cs{defaultPoster} can be defined to something else, if desired. The
% commands should be PostScript graphic operators.
%
% This command defines a text macro \cs{rma@psgraphics@poster} that
% is expanded in the definition of \cs{rmAnnot}, before the start of
% the annot itself.
%
%    \begin{macrocode}
\newcommand{\defaultPoster}[1]{\def\rma@psgraphics@poster{#1}}
\defaultPoster
{%
    \rma@ps@bg@setcolor
    0 0 \this@width\space\this@height\space rectfill
    \rma@ps@txt@x\adj@measure\rma@ps@txt@y\adj@measure moveto
    \rma@ps@txt@setcolor/\rma@ps@font\this@height\space
    \rma@ps@relfontsize div selectfont
    \rma@ps@msg
}
%    \end{macrocode}
% The definitions of the text macros that enable the document author
% to make minor changes in color, font, and placement of text, to
% the default poster.
%    \begin{macrocode}
\def\adj@measure{\calc@prop\space mul 100 div }%
\def\rma@ps@bg@setcolor{.7529 setgray }
\def\rma@ps@txt@x{10 }\def\rma@ps@txt@y{10 }
\def\rma@ps@txt@setcolor{.4 setgray }
\def\rma@ps@font{Helvetica }\def\rma@ps@relfontsize{10 }%
\def\rma@ps@msg{(\rma@posternote) show}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\makePoster}
%
% A convenience command for making posters. Assuming you have an eps of the
% appropriate aspect ratio to use as poster, you can say
%\begin{verbatim}
%   \makePoster[<graphics_options>]{<name>}{<graphics_file>}
%\end{verbatim}
% for example
%\begin{verbatim}
%   \makePoster[hiresbb]{AcroAd_poster}{AcroAd_poster}
%\end{verbatim}
% Then you can say
%\begin{verbatim}
%   \rmAnnot[poster=AcroAd_poster]{612bp}{265bp}{AcroAd}
%\end{verbatim}
%
%    \begin{macrocode}
\providecommand{\makePoster}[3][]{%
    \embedEPS[#1]{rma@#2}{#3}%
    \begin{createImage}{\bboxOf{rma@#2}}{#2}%
        \ps@mark{rma@#2} /SP pdfmark
    \end{createImage}%
}
\@onlypreamble{\makePoster}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
%    \end{macrocode}
% Finally, we define several error messages.
%    \begin{macrocode}
\def\rma@PkEr@i{%
\PackageError{rmannot}{%
    You must specify a file with an extension\MessageBreak
    of .swf, .flv, .f4v, .mp4, .m4v, .mov, .3gp,\MessageBreak
    .3g2, .mp3}{Specify one of the supported file extensions to
    embed in this annotation.\MessageBreak
    See the rmannot manual for details on supported extensions.}}
\def\rma@PkEr@ii{%
\PackageError{reannot}{%
    The name `\rm@argii' has already been used. Either\MessageBreak
    you are defining the same path, or a different path\MessageBreak
    with the same name}{%
    Names must be unique to the document, choose another}}
\def\rma@PkEr@iii#1{%
\PackageError{rmannot}{%
    No extension supplied with this file name,\MessageBreak#1.%
    \MessageBreak Please include a file extension of\MessageBreak
     .swf, .flv, or .mp3, as appropriate}{%
    Include an extension of .swf, .flv, or .mp3}}
%</package>
%    \end{macrocode}
% \subsection{Support for 3D Annotations}
% This section supports of options of the command \cs{setRmOptions3D}, used
% for passing a set of options to a RM3DA. At this writing, there are two
% recognized keys, \texttt{3DResources} and \texttt{3DOptions}. The former
% holds the key-values of my own construction; the latter holds the
% key-values of the \texttt{movie15} package by Alexander Grahn.
%    \begin{macrocode}
%<*3Dcode>
%    \end{macrocode}
%\begin{verbatim}
%\setRmOptions3D{myDice}
%{
%    3DOptions={options from movie15},
%    3DResources={%
%       none={rName=<name1>},...,
%       foreground={rName=<name2>,flashvars=<vars>},...,
%       background={rName=<name3>,flashvars=<vars>},...,
%       material={rName=<name4>,mName=<materialName>,flashvars=<vars>},...
%   }
%}
%\end{verbatim}
% The \texttt{rm3DOptsTopLevel} family supports to top-level keys
% of \cs{setRmOptions3D}: \texttt{3DOptions} and \texttt{3DResources}.
%    \begin{macrocode}
\define@key{rm3DOptsTopLevel}{3DOptions}{%
    \def\rmiiiDTLOpts{#1}%
%    \end{macrocode}
% This \cs{define@key}, in turn, executes the family \texttt{MXV@user},
% taken from \textsf{movie15}.
%    \begin{macrocode}
    \setkeys{MXV@user}{#1}%
}
\define@key{rm3DOptsTopLevel}{3DResources}{%
    \def\rmiiiDOptsTLRes{#1}%
%    \end{macrocode}
% This \cs{define@key}, in turn, executes the family \texttt{rm3DOpts},
% an original family defined in this package.
%    \begin{macrocode}
    \setkeys{rm3DOpts}{#1}%
}
%    \end{macrocode}
% \paragraph*{3DResources.} This key recognizes the keys \texttt{none},
% \texttt{foreground}, \texttt{background}, and \texttt{material}.
% The keys are optional, and may be repeated more than once.
% This paragraph processes the keys of the \texttt{rm3DOpts} family.
%\par\medskip\noindent
% \cs{rma@ckFileForEmbed} determines if the current resource is
% already embedded, and defines \cs{rma@embed} to indicated this,
% if not embedded, it defines the \texttt{rmFileStrm\#1}, and
% defines \cs{rm@irfstrm} for later use.
%    \begin{macrocode}
\def\rma@ckFileForEmbed#1#2{%
    \edef\rma@fs@expand{rmFileStrm#1}%
    \@ifundefined{\rma@fs@expand}{%
        \expandafter\xdef\csname\rma@fs@expand\endcsname{%
            rmfstream\therm@Cnt-#2#1}\def\rma@embed{1}}%
            {\def\rma@embed{0}}%
    \edef\rm@irfstrm{\@nameuse{rmFileStrm#1}}%
}
%    \end{macrocode}
% \paragraph*{The \texttt{none} key}
%    \begin{macrocode}
\define@key{rm3DOpts}{none}{%
%    \end{macrocode}
% We use nested key-values, the \texttt{none} key calls the family
% rm3DOpts@no, defined further below.
%    \begin{macrocode}
    \setkeys{rm3DOpts@no}{rName,#1}%
%    \end{macrocode}
% Parse the symbolic name, by using \cs{filename@parse}.
%    \begin{macrocode}
    \rma@edefexecute{\noexpand
        \filename@parse{\rma@useNamedPath{\rmiiiDOpts@no@rName}}}%
    \rma@ckFileForEmbed{\rmiiiDOpts@no@rName}{NONE}%
%    \end{macrocode}
% Add to the instance array, file specs/stream, and name tree.
%    \begin{macrocode}
    \edef\rma@Instances{\rma@Instances
        \ps@mark{rmInstances\therm@Cnt} %
        {rmInstance\therm@Cnt_NONE\rmiiiDOpts@no@rName}%
        /APPEND pdfmark^^J%
        \ps@mark/_objdef{rmInstance\therm@Cnt_NONE%
            \rmiiiDOpts@no@rName}/type/dict/OBJ pdfmark^^J%
        \ps@mark{rmInstance\therm@Cnt_NONE\rmiiiDOpts@no@rName}<<%
            /Asset {rmfilespec\therm@Cnt-NONE\rmiiiDOpts@no@rName}%
            /Type/RichMediaInstance>>/PUT pdfmark^^J%
        \rm@appendFileSpecs{NONE\rmiiiDOpts@no@rName}%
            {\filename@area}{\filename@base.\filename@ext}%
            {\rma@embed}{\rm@irfstrm}{}%
    }%
    \edef\rma@appendToNameTree{\rma@appendToNameTree
        \rm@appendNameTree{NONE\rmiiiDOpts@no@rName}%
            {\filename@area}{\filename@base.\filename@ext}%
            {\rma@embed}{\rm@irfstrm}{}%
    }%
}
%    \end{macrocode}
% \paragraph*{The \texttt{foreground} key}
%    \begin{macrocode}
\define@key{rm3DOpts}{foreground}{%
    \setkeys{rm3DOpts@fg}{rName,flashvars,#1}%
%    \end{macrocode}
% Parse the symbolic name, by using \cs{filename@parse}.
%    \begin{macrocode}
    \rma@edefexecute{\noexpand
        \filename@parse{\rma@useNamedPath{\rmiiiDOpts@fg@rName}}}%
    \rma@ckFileForEmbed{\rmiiiDOpts@fg@rName}{FG}%
%    \end{macrocode}
% Add to the instance array, file specs/stream, and name tree.
%    \begin{macrocode}
    \edef\rma@Instances{\rma@Instances
        \ps@mark{rmInstances\therm@Cnt} %
        {rmInstance\therm@Cnt_FG\rmiiiDOpts@fg@rName}%
        /APPEND pdfmark^^J%
        \ps@mark/_objdef{rmInstance\therm@Cnt_FG%
            \rmiiiDOpts@fg@rName}/type/dict/OBJ pdfmark^^J%
        \ps@mark{rmInstance\therm@Cnt_FG\rmiiiDOpts@fg@rName}<<%
            /Asset {rmfilespec\therm@Cnt-FG\rmiiiDOpts@fg@rName}%
            /Params <</Binding/Foreground%
                /FlashVars(\rmiiiDOpts@fg@flashvars)>>%
            /Type/RichMediaInstance%
        >>/PUT pdfmark^^J%
        \rm@appendFileSpecs{FG\rmiiiDOpts@fg@rName}{\filename@area}%
            {\filename@base.\filename@ext}{\rma@embed}%
            {\rm@irfstrm}{}%
    }%
    \edef\rma@appendToNameTree{\rma@appendToNameTree
        \rm@appendNameTree{FG\rmiiiDOpts@fg@rName}{\filename@area}%
            {\filename@base.\filename@ext}{\rma@embed}%
            {\rm@irfstrm}{}%
    }%
}
%    \end{macrocode}
% \paragraph*{The \texttt{background} key}
%    \begin{macrocode}
\define@key{rm3DOpts}{background}{%
    \setkeys{rm3DOpts@bg}{rName,flashvars,#1}%
%    \end{macrocode}
% Parse the symbolic name, by using \cs{filename@parse}.
%    \begin{macrocode}
    \rma@edefexecute{\noexpand
        \filename@parse{\rma@useNamedPath{\rmiiiDOpts@bg@rName}}}%
    \rma@ckFileForEmbed{\rmiiiDOpts@bg@rName}{BG}%
%    \end{macrocode}
% Add to the instance array, file specs/stream, and name tree.
%    \begin{macrocode}
    \edef\rma@Instances{\rma@Instances
        \ps@mark{rmInstances\therm@Cnt} %
        {rmInstance\therm@Cnt_BG\rmiiiDOpts@bg@rName}%
        /APPEND pdfmark^^J%
        \ps@mark/_objdef{rmInstance\therm@Cnt_BG%
            \rmiiiDOpts@bg@rName}/type/dict/OBJ pdfmark^^J%
        \ps@mark{rmInstance\therm@Cnt_BG\rmiiiDOpts@bg@rName}<<%
            /Asset {rmfilespec\therm@Cnt-BG\rmiiiDOpts@bg@rName}%
            /Params <</Binding/Background%
                /FlashVars(\rmiiiDOpts@bg@flashvars)>>%
            /Type/RichMediaInstance%
        >>/PUT pdfmark^^J%
        \rm@appendFileSpecs{BG\rmiiiDOpts@bg@rName}{\filename@area}%
            {\filename@base.\filename@ext}{\rma@embed}%
            {\rm@irfstrm}{}%
    }%
    \edef\rma@appendToNameTree{\rma@appendToNameTree
        \rm@appendNameTree{BG\rmiiiDOpts@bg@rName}{\filename@area}%
            {\filename@base.\filename@ext}{\rma@embed}%
            {\rm@irfstrm}{}%
    }%
}
\define@key{rm3DOpts}{material}{%
    \setkeys{rm3DOpts@mat}{rName,mName,flashvars,#1}%
%    \end{macrocode}
% Parse the symbolic name, by using \cs{filename@parse}.
%    \begin{macrocode}
    \rma@edefexecute{\noexpand
        \filename@parse{\rma@useNamedPath{\rmiiiDOpts@mat@rName}}}%
    \rma@ckFileForEmbed{\rmiiiDOpts@mat@rName}{MAT}%
%    \end{macrocode}
% Add to the instance array, file specs/stream, and name tree.
%    \begin{macrocode}
    \edef\rma@Instances{\rma@Instances
        \ps@mark{rmInstances\therm@Cnt} %
        {rmInstance\therm@Cnt_MAT\rmiiiDOpts@mat@rName}%
        /APPEND pdfmark^^J%
        \ps@mark/_objdef{rmInstance\therm@Cnt_MAT%
            \rmiiiDOpts@mat@rName}/type/dict/OBJ pdfmark^^J%
        \ps@mark{rmInstance\therm@Cnt_MAT\rmiiiDOpts@mat@rName}<<%
            /Asset {rmfilespec\therm@Cnt-MAT\rmiiiDOpts@mat@rName}%
            /Params <</Binding/Material%
                /BindingMaterialName(\rmiiiDOpts@mat@mName)%
                /FlashVars(\rmiiiDOpts@mat@flashvars)>>%
            /Type/RichMediaInstance%
        >>/PUT pdfmark^^J%
        \rm@appendFileSpecs{MAT\rmiiiDOpts@mat@rName}{\filename@area}%
            {\filename@base.\filename@ext}{\rma@embed}%
            {\rm@irfstrm}{}%
    }%
    \edef\rma@appendToNameTree{\rma@appendToNameTree
        \rm@appendNameTree{MAT\rmiiiDOpts@mat@rName}{\filename@area}%
            {\filename@base.\filename@ext}{\rma@embed}%
            {\rm@irfstrm}{}%
    }%
}
%    \end{macrocode}
% \paragraph*{Process \texttt{none} values}
%    \begin{macrocode}
\define@key{rm3DOpts@no}{rName}[]{\def\rmiiiDOpts@no@rName{#1}}
%    \end{macrocode}
% \paragraph*{Process \texttt{foreground} values}
%    \begin{macrocode}
\define@key{rm3DOpts@fg}{rName}[]{\def\rmiiiDOpts@fg@rName{#1}}
\define@key{rm3DOpts@fg}{flashvars}[]{\def\rmiiiDOpts@fg@flashvars{#1}}
%    \end{macrocode}
% \paragraph*{Process \texttt{background} values}
%    \begin{macrocode}
\define@key{rm3DOpts@bg}{rName}[]{\def\rmiiiDOpts@bg@rName{#1}}
\define@key{rm3DOpts@bg}{flashvars}[]{\def\rmiiiDOpts@bg@flashvars{#1}}
%    \end{macrocode}
% \paragraph*{Process \texttt{material} values}
%    \begin{macrocode}
\define@key{rm3DOpts@mat}{rName}[]{\def\rmiiiDOpts@mat@rName{#1}}
\define@key{rm3DOpts@mat}{mName}[]{\def\rmiiiDOpts@mat@mName{#1}}
\define@key{rm3DOpts@mat}{flashvars}[]{%
    \def\rmiiiDOpts@mat@flashvars{#1}}
%    \end{macrocode}
% \subsubsection{Code from \textsf{movie15}}
% My gracious thanks to Alexander Grahn for granting permission to use
% some of his \textsf{movie15} code.
%    \begin{macrocode}
\newread\@MXV@@viewsfile% file handle for views file
\newboolean{@MXV@eof}%
\newcount\@MXV@viewscount%counter for number of 3D views per inclusion
\newboolean{@MXV@viewsprovided}%3d views file provided?
\newboolean{@MXV@defaultviewprovided}%default 3D view provided?
\newcount\@MXV@nodecount% number of node dicts
\newcount\@MXV@cscount% number of cross section dicts
%    \end{macrocode}
% Default values
%    \begin{macrocode}
\def\@MXV@aac{30}% aperture angle of camera
\def\@MXV@roll{0}% camera roll angle
\def\@MXV@defaultbg{1 1 1}%
\def\@MXV@background{/BG<</CS/DeviceRGB/C[1 1 1]>>}%
\def\@MXV@defaultlights{}%
\def\@MXV@lights{}%
\def\@MXV@defaultrender{Solid}%
\def\@MXV@render{/RM <</Subtype/Solid>>}%
\def\@MXV@naentry{}% %takes array of Node dicts
\def\@MXV@saentry{}% %takes array of cross section  dicts
\let\@MXV@jscriptiiid\@empty
\let\rma@rmAnnot@iiiDjs\@empty
\let\@MXV@varray\@empty
\let\additional@Instances\@empty
\def\@MXV@defaultview{}
\def\@MXV@coo{0 0 0}% centre of orbit
\def\@MXV@ctoc{0 -1 0}% centre of orbit to camera vector
\def\@MXV@roo{0}% radius of orbit
\def\@MXV@viewsfileii{}%file of views of the 3D object (new format)
\setboolean{@MXV@viewsprovided}{false}%
\setboolean{@MXV@defaultviewprovided}{false}%
\def\@MXV@iiidview{}%
%    \end{macrocode}
%\DescribeMacro{\@MXV@ciiwmatrix}is a macro for building the transformation matrix
%\begin{itemize}
% \item[]\texttt{\#1},\texttt{\#2},\texttt{\#3} centre of orbit coordinates (coo)
% \item[]\texttt{\#4},\texttt{\#5},\texttt{\#6} centre of orbit to camera direction vector (c2c)
% \item[]\texttt{\#7} orbital radius (roo)
% \item[]\texttt{\#8} camera roll (roll)
%\end{itemize}
%    \begin{macrocode}
\def\@MXV@ciiwmatrix#1 #2 #3 #4 #5 #6 #7 #8 {%
%    \end{macrocode}
%View vector (opposite to c2c)
%    \begin{macrocode}
    \FPupn\@MXV@viewx{#4 neg}%
    \FPupn\@MXV@viewy{#5 neg}%
    \FPupn\@MXV@viewz{#6 neg}%
%    \end{macrocode}
% Normalize view vector
%    \begin{macrocode}
    \FPupn\@MXV@modulo{\@MXV@viewx{} copy mul %
      \@MXV@viewy{} copy mul + %
      \@MXV@viewz{} copy mul + 2 swap root%
    }%
    \FPupn\@MXV@viewx{\@MXV@viewx{} \@MXV@modulo{} div}%
    \FPupn\@MXV@viewy{\@MXV@viewy{} \@MXV@modulo{} div}%
    \FPupn\@MXV@viewz{\@MXV@viewz{} \@MXV@modulo{} div}%
%    \end{macrocode}
% Camera roll
%    \begin{macrocode}
    \FPupn\@MXV@sinroll{#8 180.0 div \FPpi{} mul sin}%
    \FPupn\@MXV@cosroll{#8 180.0 div \FPpi{} mul cos}%
%    \end{macrocode}
% Top and bottom views
%    \begin{macrocode}
    \FPupn\@MXV@leftx{-1.0}%
    \FPupn\@MXV@lefty{0.0}%
    \FPupn\@MXV@leftz{0.0}%
    \FPifneg\@MXV@viewz% top view
      %up-vector
      \FPupn\@MXV@upx{0.0}%
      \FPupn\@MXV@upy{1.0}%
      \FPupn\@MXV@upz{0.0}%
    \else% bottom view
      %up-vector
      \FPupn\@MXV@upx{0.0}%
      \FPupn\@MXV@upy{-1.0}%
      \FPupn\@MXV@upz{0.0}%
    \fi%
    \FPupn\@MXV@sumxy{\@MXV@viewx{} abs \@MXV@viewy{} abs add}%
    \FPifeq\@MXV@sumxy{0}\else% other views than top and bottom
      %up-vector = up_world - (up_world dot view) view
      \FPupn\@MXV@upx{\@MXV@viewz{} \@MXV@viewx{} mul neg}%
      \FPupn\@MXV@upy{\@MXV@viewz{} \@MXV@viewy{} mul neg}%
      \FPupn\@MXV@upz{\@MXV@viewz{} \@MXV@viewz{} mul neg 1.0 add}%
      %normalize up-vector
      \FPupn\@MXV@modulo{\@MXV@upx{} copy mul \@MXV@upy{} copy %
        mul + \@MXV@upz{} copy mul + 2 swap root}%
      \FPupn\@MXV@upx{\@MXV@upx{} \@MXV@modulo{} div}%
      \FPupn\@MXV@upy{\@MXV@upy{} \@MXV@modulo{} div}%
      \FPupn\@MXV@upz{\@MXV@upz{} \@MXV@modulo{} div}%
      %left vector = up x view
      \FPupn\@MXV@leftx{\@MXV@viewz{} \@MXV@upy{} mul %
        \@MXV@viewy{} \@MXV@upz{} mul sub}%
      \FPupn\@MXV@lefty{\@MXV@viewx{} \@MXV@upz{} mul %
        \@MXV@viewz{} \@MXV@upx{} mul sub}%
      \FPupn\@MXV@leftz{\@MXV@viewy{} \@MXV@upx{} mul %
        \@MXV@viewx{} \@MXV@upy{} mul sub}%
      %normalize left vector
      \FPupn\@MXV@modulo{\@MXV@leftx{} copy mul \@MXV@lefty{} %
        copy mul + \@MXV@leftz{} copy mul + 2 swap root}%
      \FPupn\@MXV@leftx{\@MXV@leftx{} \@MXV@modulo{} div}%
      \FPupn\@MXV@lefty{\@MXV@lefty{} \@MXV@modulo{} div}%
      \FPupn\@MXV@leftz{\@MXV@leftz{} \@MXV@modulo{} div}%
    \fi%
%    \end{macrocode}
% Apply camera roll
%    \begin{macrocode}
    \FPupn\@MXV@leftxprime{\@MXV@leftx{} \@MXV@cosroll{} mul %
        \@MXV@upx{} \@MXV@sinroll{} mul +}%
    \FPupn\@MXV@leftyprime{\@MXV@lefty{} \@MXV@cosroll{} mul %
        \@MXV@upy{} \@MXV@sinroll{} mul +}%
    \FPupn\@MXV@leftzprime{\@MXV@leftz{} \@MXV@cosroll{} mul %
        \@MXV@upz{} \@MXV@sinroll{} mul +}%
    \FPupn\@MXV@upxprime{\@MXV@upx{} \@MXV@cosroll{} mul %
        \@MXV@leftx{} \@MXV@sinroll{} mul sub}%
    \FPupn\@MXV@upyprime{\@MXV@upy{} \@MXV@cosroll{} mul %
        \@MXV@lefty{} \@MXV@sinroll{} mul sub}%
    \FPupn\@MXV@upzprime{\@MXV@upz{} \@MXV@cosroll{} mul %
        \@MXV@leftz{} \@MXV@sinroll{} mul sub}%
    \FPupn\@MXV@leftx{\@MXV@leftxprime}%
    \FPupn\@MXV@lefty{\@MXV@leftyprime}%
    \FPupn\@MXV@leftz{\@MXV@leftzprime}%
    \FPupn\@MXV@upx{\@MXV@upxprime}%
    \FPupn\@MXV@upy{\@MXV@upyprime}%
    \FPupn\@MXV@upz{\@MXV@upzprime}%
%    \end{macrocode}
% Translation vector
%    \begin{macrocode}
    \FPupn\@MXV@roo{#7 abs}%
    \FPifeq\@MXV@roo{0}\FPupn\@MXV@roo{0.0000001}\fi%
    \FPupn\@MXV@transx{#1 \@MXV@roo{} \@MXV@viewx{} mul sub}%
    \FPupn\@MXV@transy{#2 \@MXV@roo{} \@MXV@viewy{} mul sub}%
    \FPupn\@MXV@transz{#3 \@MXV@roo{} \@MXV@viewz{} mul sub}%
%    \end{macrocode}
% Rotation matrix
%    \begin{macrocode}
    \xdef\@MXV@matrix{%
        \@MXV@leftx\space\@MXV@lefty\space\@MXV@leftz\space%
        \@MXV@upx\space\@MXV@upy\space\@MXV@upz\space%
        \@MXV@viewx\space\@MXV@viewy\space\@MXV@viewz}%
%    \end{macrocode}
% Transformation matrix
%    \begin{macrocode}
    \xdef\@MXV@matrix{%
      \@MXV@matrix\space\@MXV@transx\space%
        \@MXV@transy\space\@MXV@transz%
    }%
}% end of \@MXV@ciiwmatrix
%    \end{macrocode}
% Macro for parsing one line of 3D views file (old format)
%    \begin{macrocode}
\newcommand{\@MXV@parseline}[6][]{%
    \pdfstringdef\@MXV@xname{#1}% name of the view (optional)
    \ifthenelse{\equal{#2}{}}{%
      \xdef\@MXV@coo{0 0 0}%
    }{%
      \xdef\@MXV@coo{#2}%
    }%
    \ifthenelse{\equal{#3}{}}{%
      \xdef\@MXV@ctoc{0 -1 0}%
    }{%
      \xdef\@MXV@ctoc{#3}%
    }%
    \ifthenelse{\equal{#4}{}}{%
      \xdef\@MXV@roo{0}%
    }{%
      \xdef\@MXV@roo{#4}%
    }%
    \ifthenelse{\equal{#5}{}}{%
      \xdef\@MXV@roll{0}%
    }{%
      \xdef\@MXV@roll{#5}%
    }%
    \ifthenelse{\equal{#6}{}}{%
      \xdef\@MXV@aac{30}%
    }{%
      \xdef\@MXV@aac{#6}%
    }%
}
%    \end{macrocode}
% For parsing lines of views file (new format)
%    \begin{macrocode}
\define@key{MXV@view}{VIEW}[]{%
    \ifnum\@MXV@cursection<\z@\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        A VIEW section cannot be nested into another section%
      }{}%
    \fi%
    \def\@MXV@cursection{0}%
    \pdfstringdef\@MXV@xname{#1}% name of the view (optional)
    %default camera settings
    \gdef\@MXV@coo{0 0 0}%
    \gdef\@MXV@ctoc{0 -1 0}%
    \gdef\@MXV@roo{0}%
    \gdef\@MXV@roll{0}%
    \gdef\@MXV@aac{30}%
    %default background, lights, render mode
    \xdef\@MXV@background{/BG <</CS/DeviceRGB/C [\@MXV@defaultbg]>>}%
    \xdef\@MXV@lights{/LS <</Subtype/\@MXV@defaultlights>>}%
    \gdef\@MXV@render{/RM <</Subtype/\@MXV@defaultrender>>}%
    %initialise array of node dicts
    \gdef\@MXV@naarray{}%
    \global\@MXV@nodecount=\z@
    %initialise array of crosssection dicts
    \gdef\@MXV@saarray{}%
    \global\@MXV@cscount=\z@
}
\define@key{MXV@view}{COO}{%
    \ifnum\@MXV@cursection=\z@\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        COO entry not allowed here; must go into a VIEW section%
      }{}%
    \fi%
    \xdef\@MXV@coo{#1}%
}
\define@key{MXV@view}{C2C}{%
    \ifnum\@MXV@cursection=\z@\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        C2C entry not allowed here; must go into a VIEW section%
      }{}%
    \fi%
    \xdef\@MXV@ctoc{#1}%
}
\define@key{MXV@view}{ROO}{%
    \ifnum\@MXV@cursection=\z@\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        ROO entry not allowed here; must go into a VIEW section%
      }{}%
    \fi%
    \xdef\@MXV@roo{#1}%
}
\define@key{MXV@view}{AAC}{%
    \ifnum\@MXV@cursection=\z@\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        AAC entry not allowed here; must go into a VIEW section%
      }{}%
    \fi%
    \xdef\@MXV@aac{#1}%
}
\define@key{MXV@view}{ROLL}{%
    \ifnum\@MXV@cursection=\z@\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        ROLL entry not allowed here; must go into a VIEW section%
      }{}%
    \fi%
    \xdef\@MXV@roll{#1}%
}
\define@key{MXV@view}{BGCOLOR}{%
    \ifnum\@MXV@cursection=\z@\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        BGCOLOR entry not allowed here; must go into a VIEW section%
      }{}%
    \fi%
    \def\@MXV@background{/BG<</CS/DeviceRGB/C[#1]>>}%
}
\define@key{MXV@view}{LIGHTS}{%
    \ifnum\@MXV@cursection=\z@\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        LIGHTS entry not allowed here; must go into a VIEW section%
      }{}%
    \fi%
    \def\@MXV@lights{/LS <</Subtype/#1>>}%
}
\define@key{MXV@view}{RENDERMODE}{%
    \ifnum\@MXV@cursection=\z@
      \def\@MXV@render{/RM <</Subtype/#1>>}%
    \else%
      \ifnum\@MXV@cursection=\@ne
        \def\@MXV@nrender{/RM <</Subtype/#1>>}%
      \else%
        \PackageError{rmannot}{%
          File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
            RENDERMODE entry not allowed here; must go into %
            either a VIEW or a PART section%
        }{}%
      \fi%
    \fi%
}
\define@key{MXV@view}{PART}[]{%
    \ifnum\@MXV@cursection=\z@\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        PART not allowed here; must be a sub-section of %
        a VIEW section%
      }{}%
    \fi%
    \ifthenelse{\equal{#1}{}}{%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        You must provide a valid PART name (PART=<part name>), as
        shown in the model tree of the 3D object %
        (go to `View'->`Navigation Panels'->`Model Tree' %
        in Adobe Reader)%
      }{}%
    }{}%
    \def\@MXV@cursection{1}%
    \pdfstringdef\@MXV@partname{#1}% name of the part
    \gdef\@MXV@nopacity{}%
    \gdef\@MXV@nvisibility{}%
    \gdef\@MXV@nrender{}%
    \gdef\@MXV@ntransform{}%
}
\define@key{MXV@view}{CROSSSECT}[]{%
    \ifnum\@MXV@cursection=\z@\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        CROSSSECT not allowed here; must be a sub-section of %
        a VIEW section%
      }{}%
    \fi%
    \ifthenelse{\equal{#1}{}}{}{%
      \PackageWarning{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        CROSSECT does not take a value%
      }%
    }%
    \def\@MXV@cursection{2}%
    \gdef\@MXV@cscenter{0 0 0}%
    \gdef\@MXV@csorient{null 0 0}%
}
\define@key{MXV@view}{OPACITY}{%
    \ifnum\@MXV@cursection=\@ne\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        OPACITY entry not allowed here; must go into a PART section%
      }{}%
    \fi%
    \gdef\@MXV@nopacity{/O #1}%
}
\define@key{MXV@view}{VISIBLE}{%
    \ifnum\@MXV@cursection=\@ne\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        VISIBLE entry not allowed here; must go into a PART section%
      }{}%
    \fi%
    \gdef\@MXV@nvisibility{/V #1}%
}
\define@key{MXV@view}{MATRIX}{%
    \ifnum\@MXV@cursection=\@ne\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        MATRIX entry not allowed here; must go into a PART section%
      }{}%
    \fi%
    \gdef\@MXV@ntransform{/M [#1]}%
}
\define@key{MXV@view}{CENTER}{%
    \ifnum\@MXV@cursection=2\relax\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        CENTER entry not allowed here; must go into a CROSSECT section%
      }{}%
    \fi%
    \gdef\@MXV@cscenter{#1}%
}
\define@key{MXV@view}{ORIENTATION}{%
    \ifnum\@MXV@cursection=2\relax\else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        ORIENT entry not allowed here; must go into a CROSSECT section%
      }{}%
    \fi%
    \gdef\@MXV@csorient{#1}%
}
\define@key{MXV@view}{END}[]{%
    \ifcase\@MXV@cursection%
      %END VIEW
      \edef\@MXV@args{%
        \@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space%
        \@MXV@roll\space}%
      \expandafter\@MXV@ciiwmatrix\@MXV@args% build C2W matrix
      \global\advance\@MXV@viewscount by \@ne%
      \ifthenelse{\equal{\@MXV@xname}{}}{% default view name
        \pdfstringdef\@MXV@xname{View \the\@MXV@viewscount}%
      }{}%
      \ifthenelse{\equal{\@MXV@naarray}{}}{}{%
        \gdef\@MXV@naentry{/NR true/NA [\@MXV@naarray]}%
      }%
      \ifthenelse{\equal{\@MXV@saarray}{}}{}{%
        \gdef\@MXV@saentry{/SA [\@MXV@saarray]}%
      }%
      \@MXV@viewobj% create pdf object of 3D view
      %append current view obj ref to VA array
      \xdef\@MXV@varray{\@MXV@varray\space\@MXV@@viewobj}%
      \global\@MXV@viewsprovidedtrue%
      \def\@MXV@cursection{-1}%
    \or%
      %END PART
      \global\advance\@MXV@nodecount by \@ne
      \@MXV@nodeobj% create pdf object of 3D node dict
      %append it to node array
      \xdef\@MXV@naarray{\@MXV@naarray\space\@MXV@@nodeobj}%
      \def\@MXV@cursection{0}%
    \or%
      %END CROSSSECT
      \global\advance\@MXV@cscount by \@ne
      \@MXV@csobj% create pdf object of 3D cross section dict
      %append it to cross section array
      \xdef\@MXV@saarray{\@MXV@saarray\space\@MXV@@csobj}%
      \def\@MXV@cursection{0}%
    \else%
      \PackageError{rmannot}{%
        File \@MXV@viewsfileii, line \the\@MXV@inputlineno: %
        There is nothing to be ENDed here%
      }{}%
    \fi%
}%
%    \end{macrocode}
% Macro for generating an array of 3D views (varray)
%    \begin{macrocode}
\def\@MXV@procinputline#1{\setkeys{MXV@view}{#1}}
\newcount\@MXV@inputlineno
\def\@MXV@buildva{%
    \global\@MXV@viewscount=0%
    \xdef\@MXV@varray{}% empty varray
%
%default view (one of the command options 3Dcoo, 3Dc2c, etc. given)
    \edef\@MXV@args{%
      \@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space%
      \@MXV@roll\space}%
    \expandafter\@MXV@ciiwmatrix\@MXV@args% build C2W matrix
    \pdfstringdef\@MXV@xname{Default}%
    \if@MXV@defaultviewprovided%
      \@MXV@viewobj% create pdf object of 3D view
%      \edef\@MXV@defaultview{/3DV \@MXV@@viewobj}%
      \edef\@MXV@defaultview{\@MXV@@viewobj}%
    \fi%
%    \end{macrocode}
% Read out 3D views file (new version)
%    \begin{macrocode}
    \def\@MXV@cursection{-1}% views file is divided in sections
    \IfFileExists{\@MXV@viewsfileii}{%
      \begingroup%
      \endlinechar=-1% suppress trailing space at input line end
      \@MXV@inputlineno=\z@%
      \openin\@MXV@@viewsfile=\@MXV@viewsfileii%
      \read\@MXV@@viewsfile to \@MXV@inputline%
      \ifeof\@MXV@@viewsfile\setboolean{@MXV@eof}{true}\else%
        \setboolean{@MXV@eof}{false}\fi%
      \whiledo{\NOT\boolean{@MXV@eof}}{%
        \advance\@MXV@inputlineno by \@ne%
        %process input line
        \edef\@MXV@@inputline{{\@MXV@inputline}}%
        \expandafter\@MXV@procinputline\@MXV@@inputline%
        \read\@MXV@@viewsfile to \@MXV@inputline%
        \ifeof\@MXV@@viewsfile%
          \setboolean{@MXV@eof}{true}%
        \else%
          \setboolean{@MXV@eof}{false}%
        \fi%
      }%
      \closein\@MXV@@viewsfile%
      \endgroup%
    }{}%
%    \end{macrocode}
% Make the first view in the VA array the default view, if no default one has
% explicitly been provided, but if the VA array itself is empty too (no
% additional views provided) use our fallback view (c2c=0 -1 0) as default
%    \begin{macrocode}
    \ifthenelse{\NOT\boolean{@MXV@defaultviewprovided}%
      \AND\boolean{@MXV@viewsprovided}}{%
%      \xdef\@MXV@defaultview{/3DV/F}%
      \xdef\@MXV@defaultview{/F}%
    }{}%
    \ifthenelse{\NOT\boolean{@MXV@defaultviewprovided}%
      \AND\NOT\boolean{@MXV@viewsprovided}}{%
      \@MXV@viewobj% create pdf object of 3D view
%      \edef\@MXV@defaultview{/3DV \@MXV@@viewobj}%
      \edef\@MXV@defaultview{\@MXV@@viewobj}%
    }{}%
}
%    \end{macrocode}
% Following macros, including the 3D inclusion macro have driver specific
% implementations dvips versions
% macro for creating 3D view object and associated projection dict
%    \begin{macrocode}
\def\@MXV@viewobj{\literalps@out{%
  %projection dict
  \ps@mark/_objdef {pdict\therm@Cnt_\the\@MXV@viewscount}%
        /type/dict/OBJ pdfmark^^J%
  \ps@mark{pdict\therm@Cnt_\the\@MXV@viewscount} <<%
        /Subtype/P/FOV \@MXV@aac/PS/Min>>/PUT pdfmark^^J%
  \ps@mark/_objdef {viewobj\therm@Cnt_\the\@MXV@viewscount}%
        /type/dict/OBJ pdfmark^^J%
  \ps@mark{viewobj\therm@Cnt_\the\@MXV@viewscount} <<%
        /MS/M%
        /CO \@MXV@roo%
        /P {pdict\therm@Cnt_\the\@MXV@viewscount}%
        /C2W[\@MXV@matrix]%
        /XN(\@MXV@xname)%
/IN(\@MXV@xname)%
        \@MXV@background%
        \@MXV@lights%
        \@MXV@render%
        \@MXV@naentry%
        \@MXV@saentry%
      >>%
    /PUT pdfmark
  }%
  \xdef\@MXV@@viewobj{{viewobj\therm@Cnt_\the\@MXV@viewscount}}%
}%
%3D node object
\def\@MXV@nodeobj{\literalps@out{%
    \ps@mark/type/dict%
      /_objdef {nodeobj\therm@Cnt_\the\@MXV@viewscount_%
        \the\@MXV@nodecount}/OBJ pdfmark^^J%
    \ps@mark{nodeobj\therm@Cnt_\the\@MXV@viewscount_%
        \the\@MXV@nodecount}<<%
            /Type/3DNode%
            /N (\@MXV@partname)%
            \@MXV@nopacity\@MXV@nvisibility\@MXV@ntransform%
                \@MXV@nrender%
      >>/PUT pdfmark
  }%
  \xdef\@MXV@@nodeobj{%
    {nodeobj\therm@Cnt_\the\@MXV@viewscount_%
            \the\@MXV@nodecount}}%
}%
%3D cross section object
\def\@MXV@csobj{\literalps@out{%
    \ps@mark/type/dict%
        /_objdef {csobj\therm@Cnt_\the\@MXV@viewscount_%
        \the\@MXV@cscount}/OBJ pdfmark^^J%
    \ps@mark{csobj\therm@Cnt_\the\@MXV@viewscount_%
        \the\@MXV@cscount}<<%
            /Type/3DCrossSection%
            /C [\@MXV@cscenter]%
            /O [\@MXV@csorient]%
        >>/PUT pdfmark
  }%
  \xdef\@MXV@@csobj{%
    {csobj\therm@Cnt_\the\@MXV@viewscount_\the\@MXV@cscount}}%
}%
%    \end{macrocode}
% \paragraph*{MXV@user family}
%    \begin{macrocode}
\define@key{MXV@user}{3Dbg}[1 1 1]{%
    \def\@MXV@defaultbg{#1}%
    \def\@MXV@background{/BG<</CS/DeviceRGB/C[#1]>>}%
}
\define@key{MXV@user}{3Djscript}{%
    \def\rma@rmAnnot@iiiDjs{#1}%
    \ifx\rma@rmAnnot@iiiDjs\@empty\let\rma@addResources\@empty
    \let\rma@addFileSpecs\@empty\else
%    \end{macrocode}
% We process resources when there are some to process \texttt{:-)}
%    \begin{macrocode}
        \rma@toks={}\def\rmiiid@addToScriptsArray{}%
        \@for\rma@arg:=\rma@rmAnnot@iiiDjs\do{%
            \rma@edefexecute{\noexpand
                \filename@parse{\rma@useNamedPath{\rma@arg}}}%
            \@ifundefined{filename@ext}{%
              \rma@PkEr@iii{\rma@useNamedPath{\rma@arg}}}{}%
            \edef\rmiiid@addToScriptsArray{\rmiiid@addToScriptsArray
                \ps@mark{jscriptiiid\therm@Cnt}%
                {rmfilespec\therm@Cnt-JS\rma@arg}%
                /APPEND pdfmark^^J%
            }%
            \edef\rma@fs@expand{rmFileStrm\rma@arg}%
            \@ifundefined{\rma@fs@expand}{%
            \expandafter\xdef\csname\rma@fs@expand\endcsname
              {rmfstream\therm@Cnt-JS\rma@arg}%
              \def\rma@embed{1}}{\def\rma@embed{0}}%
            \edef\rma@tmp@exp{\the\rma@toks%
              \noexpand\\{JS\rma@arg}%
              {\filename@area}{\filename@base.\filename@ext}%
              {\rma@embed}{\csname\rma@fs@expand\endcsname}%
              {\expandafter\noexpand\csname rma@mt@\rma@arg\endcsname}}%
            \rma@toks=\expandafter{\rma@tmp@exp}%
        }%
        \let\\\rm@appendNameTree
        \expandafter\xdef\expandafter\rma@addResources%
            \expandafter{\the\rma@toks}%
        \let\\\rm@appendFileSpecs
        \expandafter\xdef\expandafter\rma@addFileSpecs%
            \expandafter{\the\rma@toks}%
    \fi
}
\define@key{MXV@user}{3Dcoo}{%
    \def\@MXV@coo{#1}%
    \setboolean{@MXV@defaultviewprovided}{true}%
}
\define@key{MXV@user}{3Dc2c}{%
    \def\@MXV@ctoc{#1}%
    \setboolean{@MXV@defaultviewprovided}{true}%
}
\define@key{MXV@user}{3Droo}{%
    \def\@MXV@roo{#1}%
    \setboolean{@MXV@defaultviewprovided}{true}%
}
\define@key{MXV@user}{3Daac}{%
    \def\@MXV@aac{#1}%
    \setboolean{@MXV@defaultviewprovided}{true}%
}
\define@key{MXV@user}{3Droll}{%
    \def\@MXV@roll{#1}%
    \setboolean{@MXV@defaultviewprovided}{true}%
}
%    \end{macrocode}
% Since we are starting fresh, we don't use the old format used
% by \textsf{movie15}, so I am renaming \texttt{3Dviews2} to \texttt{3Dviews}
% and eliminating the old format and code completely.
%    \begin{macrocode}
\define@key{MXV@user}{3Dviews}{%
    \IfFileExists{#1}{%
      \def\@MXV@viewsfileii{#1}%
    }{%
      \PackageError{rmannot}{3D views  file `#1' cannot be opened%
      }{%
        Make sure file `#1' exists and is readable!%
      }%
    }%
}
\define@choicekey+{MXV@user}{3Dlights}%
    {None,White,Day,Night,Hard,Primary,Blue,%
        Red,Cube,CAD,Headlamp}[Cube]{%
    \gdef\@MXV@defaultlights{#1}%
    \gdef\@MXV@lights{/LS <</Subtype/#1>>}%
}{\PackageWarning{rmannot}{Bad choice for 3Dlights, permissible
    values are None, White, Day, Night, Hard, Primary, Blue,
        Red, Cube, CAD, HeadLamp. Try again}}
\define@choicekey+{MXV@user}{3Drender}%
    {Solid,SolidWireframe,Transparent,TransparentWireframe,%
     BoundingBox,TransparentBoundingBox,TransparentBoundingBoxOutline,%
     Wireframe,ShadedWireframe,HiddenWireframe,Vertices,ShadedVertices,%
     SolidOutline,Illustration,ShadedIllustration}[Solid]{%
    \gdef\@MXV@defaultrender{#1}%
    \gdef\@MXV@render{/RM <</Subtype/#1>>}%
}{\PackageWarning{rmannot}{Bad choice for 3Dlights, permissible
    values are Solid, SolidWireframe, Transparent, TransparentWireframe,
     BoundingBox, TransparentBoundingBox, TransparentBoundingBoxOutline,
     Wireframe, ShadedWireframe, HiddenWireframe, Vertices,
     ShadedVertices, SolidOutline, Illustration, ShadedIllustration.
     Try again}}
%    \end{macrocode}
%    \begin{macrocode}
%</3Dcode>
%<*package>
\rma@input@iiidCode
%</package>
%    \end{macrocode}
\endinput

History:
    (2010/27/12 v1.1d) Made some minor changes, labeled as 12/27/10
    (2010/22/12 v1.1c) Made the definition \saveNamedPath global, needed
    for the fldigigal package.
    (2010/14/12 v1.1b) Corrected the definition of borderwidth. Acrobat
    uses for none, thin, medium, and thick the values of 0,1,3,5 not
    0,1,2,3 (for some reason).
    (2010/17/07 v1.1a) Added definitions for none and noChange that can be
    recognized by JS to indicate that the video should have no skin, and
    the video should have the same skin as the previous video (noChange)
    (2010/10/07 v1.1) Added definitions for skins so they can be
    referenced by name in the resources key. Added support for
    \Name and \urlName inside a eform field.
    (2010/10/01 v1.0c) Added \let\rma@addResources\@empty\let\rma@addFileSpecs\@empty
        to clean out these macros, if one \rmAnnot had resources, these
        were included in the next \rmAnnot as well causing distiller to
        cough a fur ball.  The problem manifests itself when
        \useVideoPlayerPlus or \useVideoPlayerX is used.
    (2010/09/29 v1.0b) Experimental use of VideoPlayerPlus.swf and
    VideoPlayerX.swf
    (2010/09/29 v1.0a) Added an invisible option for \rmAnnot. The annot
    is given a transparent poster, if no poster is specified.
    (2010/09/24 v1.0) Made a correction to a typo for CuePoints (I had
        Cuepoints). Now the cue points feature works.
        Removed some spurious spaces from \rmAnnot
