%%% -*- Mode: LaTeX -*-

%%%
%%% Copyright 1992, Patrick A. O'Donnell
%%% Written at the MIT Artificial Intelligence Laboratory
%%% All rights reserved.
%%%
%%% This software may be freely copied and distributed subject to the
%%% following restrictions.  Any distribution of this software must return
%%% no profit, must be for educational or scientific use, and must include
%%% these copyright and distribution notices without modification.  The
%%% author also grants to individuals the license to modify or enhance this
%%% software, however distribution of these derivative works is prohibited.
%%% Such enhancements or modifications may be returned to the author to be
%%% included in future versions.  Distribution of this sofware contrary to
%%% the terms of this notice may be subject to penalties under applicable
%%% law.
%%% 
%%% Permission to copy or distribute this software other than under
%%% these conditions may be granted by the author in writing.
%%%

%%% Add ``movies'' to the margin of your document.
%%% Originally designed for the Handey book; slightly modified for
%%% public consumption.

%%% Usage:
%%%     \documentstyle[margin-movies]{whatever}
%%%	\renewcommand{\oddmovies}{good stuff --- see below}
%%%
%%%
%%% This style file adds a column of figures to the outside margin of
%%% your document.  If these figures are frames of an animated movie
%%% (drawings), then flipping the pages of your document will allow the
%%% reader to view your movie.
%%%
%%% In the right margin of each page (in two-sided mode, on the
%%% even-numbered pages, the left margin is used instead) a column of
%%% movie frames is added to the document.  One frame of each movie
%%% appears on each page.  Frame 1 appears on page 1, frame 2 on page 2,
%%% and so on.  (In two-sided mode, frame 2 of the movies on the odd
%%% pages appears on page 3, of course.  For the movies on the even
%%% pages, frame 1 appears on the page specified by the counter
%%% evenmoviestart, and the movie goes backward, through lower numbered
%%% pages.  That is, frame 2 appears on page evenmoviestart-2, and so
%%% on.  This makes them easier to view, actually.)  You can have
%%% several movies in the margin, one above the other.
%%%
%%% In this style, each frame of each movie is assumed to be in a
%%% separate Postscript file.  The macro \psadobepercent is used to
%%% incorporate the Postscript file into your document.  (If you do not
%%% use this macro for your figure inclusions, you can modify the \movie
%%% macro, below, to suit your purposes.)
%%%
%%% Very simply, the commands \oddmovies and \evenmovies are executed to
%%% create a box (the column) to attach to the side of your text.  (If
%%% you're creating a single-sided document, only \oddmovies is used.)
%%% You are expected to define these macros to contain anything you
%%% would normally put in a \mbox.  For example (see the definition of
%%% the movie command, below),
%%%
%%%     \renewcommand{\oddmovies}{%
%%%       \movie{3in}{100}{dduck-}{25}%
%%%       \vspace{2in}%
%%%       \movie{3in}{74}{mmouse-}{32}}
%%%
%%% would put two movies, each three inches tall, separated by two
%%% inches in the margin.  Each frame of the Donald Duck movie (for
%%% example) is contained in a file named as dduck-1.ps, dduck-2.ps, and
%%% so on.  The Donald Duck movie has twenty-five frames and is to be
%%% included at full size.  The Micky Mouse movie has thirty-two frames,
%%% and they are to be reduced to 74 percent before inclusion.  Frame
%%% numbers start at 1 on page 1.
%%%
%%%
%%% \movie{HEIGHT}{SCALE}{PATH}{MAXFRAME}
%%% 
%%% Within the definitions (which you supply) of the \oddmovies and
%%% \evenmovies commands, the \movie command can be used to include a
%%% Postscript file which contains one frame of a movie.  HOWEVER, THIS
%%% COMMAND ASSUMES THAT the \psadobe macros are available at your site,
%%% and loaded (these do the actual file operations), and that the
%%% Postscript files are named as <path><frame>.ps, where <path> is the
%%% path prefix specified as the third argument to \movie, and <frame>
%%% is the frame number.  The result of this command is a box of the
%%% specified height---the figure read in from the file is flushed to
%%% the left and bottom of this box.  MAXFRAME is the number of the last
%%% frame in the movie (movies always start at frame 1); this is used to
%%% tell when to stop looking for frames of this movie.  (Note that when
%%% you're past MAXFRAME, the box is still returned, it just has zero
%%% width.)  (If you use a different macro than \psadobe to include
%%% Postscript figures in your TeX documents, you can modify the \movie
%%% command appropriately.)
%%%
%%%
%%% Parameters:  [The default values are specified in brackets.]
%%%
%%% Length parameters:
%%%    \moviewidth	This defines the width of the column of movies.
%%%			If the figures created are wider than this, they
%%%			will overlap into the text.  [1.2 in]
%%%
%%%    \movietextsep	The (nominal) space between the block of text on
%%%			the page and the column of movies.  [.1 in]
%%%
%%% The movies appear in the MARGINS of the document.  \textwidth is not
%%% affected by this style, nor does it affect this style, except that
%%% changing \textwidth moves the odd movies to maintain the
%%% \movietextsep distance between the text and the movie columns.
%%% Similarly, in two-sided mode, changing \evensidemargin moves the
%%% left edge of the text, and thus moves the movie column (again to
%%% maintain \movietextsep).  It is the responsibility of the user to
%%% set \textwidth and \evensidemargin appropriately so that the movies
%%% fit on the page.  (Another implication of the \textwidth behavior is
%%% that running heads do not extend over the movies.  If you want this,
%%% you'll have to redefine \@oddhead and \@evenhead to create boxes of
%%% the appropriate widths.  Since styles of running heads vary so much,
%%% it is beyond the scope of these instructions to provide examples of
%%% doing this.)
%%%
%%% The height of the movie column is just \textheight.  However, it is
%%% filled at the bottom with stretchable glue (\vss), so this is
%%% probably irrelevant.
%%%
%%% Count parameters:
%%%    evenmoviestart	The page number where the movies on the even-
%%%			numbered pages start with frame 1.  The movies
%%%			created in two-sided mode with \evenmovies run
%%%			backward in your document, starting at the page
%%%			specified by this counter.  This makes them
%%%			easier to view, actually.  (I could be persuaded
%%%			to conditionalize this behavior on this counter
%%%			being non-zero.)  [200]
%%%
%%% Commands:
%%%    \oddmovies
%%%    \evenmovies
%%%    \movie{HEIGHT}{SCALE}{PATH}{MAXFRAME}
%%%			These commands are described above.  The user is
%%%			expected to define \oddmovies and \evenmovies.
%%%			They are null by default.
%%%
%%%    \moviestrue	This command turns movies on.  By default,
%%%			movies will not appear even though this style
%%%			file is included.  The purpose of this is to
%%%			prevent movies from appearing in the front
%%%			matter of books.  Use \moviestrue just before
%%%			beginning the actual text of your book; then
%%%			frame 1 will appear on the real page 1 of your
%%%			book.  \moviesfalse can be used to turn off the
%%%			movies.
%%%
%%%    \moviesampletrue This turns movies on, but reads a special sample
%%%			frame.  We used this to create a page in the
%%%			front matter which explained the movies.  Use
%%%			\moviesamplefalse after that page is emitted to
%%%			make sure the correct frames are then output.
%%%			\moviestrue must be on, also.  This command just
%%%			causes the \movie command to select a special
%%%			frame out of the movie, rather than a numbered
%%%			frame.
%%%
%%%
%%% You do not have to use the \movie command to create the frames of
%%% your movie.  You can put anything in the movie column you wish; it's
%%% just a box.  If this appeals to you, you may find the following
%%% primitives helpful:
%%%
%%%    \moviebox[HEIGHT]{MAXFRAME}{COMMANDS}
%%%			Creates a box whose contents are filled in by
%%%			COMMANDS.  The commands are not executed unless
%%%			a frame is supposed to appear.  The frame number
%%%			is accessible via the movieidx counter.  If the
%%%			optional argument HEIGHT is omitted, the natural
%%%			height of the stuff created by COMMANDS is used.
%%%
%%%    \@testmovie{MAXFRAME}
%%%			Makes sure a movie frame should appear on this
%%%			page.  Sets the movieidx counter and the
%%%			\if@thisframe conditional.
%%%
%%%    movieidx		Counter.  (In TeX, this is \c@movieidx.)  This
%%%			is set by \@testmovie to the correct frame
%%%			number to appear on this page.
%%%
%%%    \if@thisframe	A conditional that is set to true iff a frame
%%%			should appear on this page, according to the
%%%			MAXFRAME argument (and the evenmoviestart
%%%			counter if in two-side mode on an even page).
%%%

% The page setup resembles the following:
% Note that the text dimensions are set by the overall style.
% The movie width is fixed, as is the spacing from the text.
% The movie height is specified with the movie definition.
% You can specify how they are spaced along the page when you define the
%  movies.

%               +------------------------------------------+
%               |				           |
%               |   page#___________________chapter_mark   |
%               |   +---------+   +--------------------+   |
%               |   |Movie Box|   |		       |   |
%               |   |<   B   >| C |<    Text          >|   |
%               |   +---------+   |		       |   |
%               |                 |		       |   |
%               |   +---------+   |		       |   |
%               |   |         |   |		       |   |
%               |   |         |   |		       |   |
%               |   +---------+   |		       |   |
%               |	          |		       |   |       odd page is
%	        |	          |		       |   |	   mirror image
%               |	          |		       |   |	   of even page
%               |		  |		       |   |
%               |		  +--------------------+   |
%               |					   |
%               +------------------------------------------+
%           outside edge          even page          bound edge
%
%   Lengths:  B -  \moviewidth
%	      C -  \movietextsep
%

\typeout{Margin movies, version 1.1, <28 May 1992>}

%%% Movie parameters:

\newlength{\moviewidth}	      \setlength{\moviewidth}{1.2in}
\newlength{\movietextsep}     \setlength{\movietextsep}{.1in}
\newcounter{evenmoviestart}   \setcounter{evenmoviestart}{200}

%%% MAKING MOVIES
%%% The width of a movie box is declared above to be \moviewidth (1.2 inches).  The
%%% PERCENT argument of the \psadobepercent command must be adjsted for the actual
%%% drawings to make this come true.

%%% The difference between even movies and odd movies is just the page
%%% numbering---really, just the direction the movies go and where they
%%% start.

\newcounter{movieidx}
\newif\ifmovies\moviesfalse
\newif\if@thisframe
\newif\ifmoviesample\moviesamplefalse

%%% \@testmovie{MAXFRAME}
%%% See if we should try to load a frame for the current movie.
%%% Sets \if@thisframe accordingly, and \c@movieidx to the frame number
%%% in the movie of the frame to display on this page.  This is computed
%%% as: if we're in one-sided mode, it's the page number; otherwise if
%%% we're on an odd page, it's page+1/2; if we're on an even page, we
%%% have to count backward from {evenmoviestart}, as
%%% (evenmoviestart-page)/2+1.  MAXFRAME is the largest frame number in
%%% the movie.  If \if@thisframe is false after this runs, no movie
%%% should appear on this page.

\def\@testmovie#1{\@thisframefalse
  \c@movieidx\c@page
  \ifmoviesample\@thisframetrue\else
    %% Compute the movie frame index.
    \if@twoside
      \ifodd\c@page
	\advance\c@movieidx 1\divide\c@movieidx 2\relax
      \else
	\c@movieidx -\c@page
	\advance\c@movieidx\c@evenmoviestart
	\divide\c@movieidx 2
	\advance\c@movieidx 1\relax\fi
    \fi
    \ifnum\c@movieidx<1\else
      \ifnum\c@movieidx>#1\else\@thisframetrue\fi\fi\fi}


%%% \movie{HEIGHT}{SCALE}{PATH}{MAXPAGE}

\def\movie#1#2#3#4{\@testmovie{#4}%
  \hbox{\vbox to #1{\vss  % flush it to the bottom
    \if@thisframe
      \ifmoviesample\psadobepercent{#2}{#3sample.ps}\else
	\psadobepercent{#2}{#3\the\c@movieidx.ps}\fi\fi}}}

%%% \@moviestrip
%%% This creates the actual box to attach to the output box.  It selects
%%% the correct command, \oddmovies or \evenmovies, to execute, and
%%% makes sure that line spacing commands are zeroed so that the spacing
%%% in the movie specifications is followed more predictably.  The
%%% movies are flushed to the top and left of the box.  Overlap in both
%%% horizontal and vertical to the right and bottom is allowed.

\def\@moviestrip{%
  \hbox to\moviewidth{%
    \vbox to\textheight{\parindent=0pt\baselineskip=0pt\lineskip=0pt
      \parskip=0pt
      \if@twoside\ifodd\c@page\oddmovies\else\evenmovies\fi
	\else\oddmovies\fi\vss
    }%
    \hss}}


%%% \moviebox[HEIGHT]{MAXFRAME}{COMMANDS}
%%% See main documentation for explanation.


\def\moviebox{\@ifnextchar [{\@moviebox}{\@nmoviebox}} %]
\def\@moviebox[#1]#2#3{\@testmovie{#2}%
  \hbox{\vbox to #1{\vss\if@thisframe {#3}\fi}}}
\def\@nmoviebox#1#2{\@testmovie{#1}\hbox{\vbox{\if@thisframe {#2}\fi}}}

%%% These are to be defined by the user.

\def\evenmovies{}
\def\oddmovies{}

%%%
%%% Modify the output routine to add the movie strip.
%%%

%%% We do this semi-transparently by redefining \@outputpage such that
%%% it attaches the strip to \@outputbox, then does whatever else it
%%% does.  The attached strip adds no width to the text box, and no
%%% height or depth if the text box is \textheight high.  In LaTeX,
%%% \@outputbox is supposed to contain the block of text to be output.
%%% Notice that this includes both columns of two-column mode, so that
%%% works, too.  Nothing special is done

\let\@originaloutputpage\@outputpage

\def\@oaddrightmovies{%
  \setbox\@outputbox\hbox
    {\box\@outputbox\rlap{\hskip\movietextsep\@moviestrip}}}

\def\@oaddleftmovies{%
  \setbox\@outputbox\hbox
    {\llap{\@moviestrip\hskip\movietextsep}\box\@outputbox}}

\def\@outputaddmovies{%
  \if@twoside
    \ifodd\c@page
      \@oaddrightmovies\else\@oaddleftmovies\fi
  \else\@oaddrightmovies\fi}

\def\@outputpage{\ifmovies\@outputaddmovies\fi\@originaloutputpage}
