/**********************************************************
 *
 *   NAME
 *      Display_Aud -- animates a prerendered vignette
 *
 *   SYNOPSIS
 *      Display_Aud();
 *
 *   DESCRIPTION
 *      This function systematically displays a prerendered vignette.
 *
 *      copyright (c) 1987 Martin D. Hash
 *
 *   LAST EDITED
 *      Martin Hash                        23 Aug 1987
 *
 *   EDIT HISTORY
 *      21 Mar 1987  MH  Created.
 *	 5 Jul		 Signals for interrupts.
 *      12 Jul		 Switch copyright.
 *      16 Aug		 ANIM standard.
 *
 **********************************************************/

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/interrupts.h>
#include <hardware/intbits.h>
#include <intuition/intuition.h>
#include <graphics/gfxbase.h>
#include "df1:FileCons.h"
#include "df1:KeyCons.h"
#include "df1:ANIMCons.h"

/* LOCAL CONSTANTS */

#define UP			1
#define STEADY			0
#define DOWN			-1

/* EXTERNAL VARIABLES */

extern struct Window *window;
extern struct View view1, view2;
extern struct ViewPort viewport1, viewport2;
extern struct RastPort rastport1, rastport2;
extern struct BitMap bitmap1, bitmap2;
extern struct IntuiText framenumbertext;
extern char numbertext[];
extern ULONG *size;
extern struct Interrupt *VertBIntr;
extern FrameNode *patriarch;

/* EXTERNAL FUNCTIONS */

void Copyright(),
     LoadIFF(),
     Timer();
int XORDLTAshort(),
    Call_Pack();
struct Task *FindTask();

/* GLOBAL VARIABLES */

struct Task *task;
int mask, signal;

/* FILE VARIABLES */

static char blanktext[] = "           ";
static struct IntuiText blank = {
  1, 0, JAM2,
  0, 0, NULL,
  blanktext,
  NULL
};

/* FUNCTION */

void Display_Aud()
{
   /* LOCAL VARIABLES */

   struct View *view;
   struct ViewPort *viewport;
   struct IntuiMessage *message;
   ULONG class;
   UWORD code,
         frame_rate = 5;
   BYTE up_or_down = UP;
   int frame = 3,
       counter = 1;
   struct BitMap *bitmap;
   struct RastPort *rastport;
   BOOL odd_frame = TRUE,
	display_frame_number = FALSE,
        looping = TRUE,
	next = FALSE,
	stop = FALSE;
   WORD direction = STEADY;
   FrameNode *prevframenode, *framenode;

   /* CODE */

   task = FindTask( NULL );
   if ((signal = AllocSignal( -1 )) == -1)
      return;
   mask = 1<<signal;
   SetSignal( 0, mask );

   Timer();
   window->Flags |= RMBTRAP;

   if (patriarch == NULL | patriarch->next == NULL)
      return;
   else
      framenode = patriarch->next;

   frame = 2;
   viewport = &viewport2;
   view = &view2;
   rastport = &rastport2;

   while (looping) {
      if (1<<window->UserPort->mp_SigBit)
         while (message = (struct IntuiMessage *)GetMsg( window->UserPort)) {
            class = message->Class;
            code = message->Code;

            ReplyMsg( message );
            switch (class) {
	       case RAWKEY:
	          switch (code) {
	             case RETURN:
			if (display_frame_number) {
		           display_frame_number = FALSE;
			   strcpy( numbertext, "   " );
	                   PrintIText( &rastport1, &framenumbertext, 310, 30 );
	                   PrintIText( &rastport2, &framenumbertext, 310, 30 );
			   PrintIText( &rastport1, &blank, 300, 221 );
			   PrintIText( &rastport2, &blank, 300, 221 );
		        }
		        else {
			   display_frame_number = TRUE;
	                   stci_d( numbertext, frame, 5 );
	                   strncat( numbertext, "   ", 4 );
	                   PrintIText( rastport, &framenumbertext, 310, 30 );
			/**** retain this call  *****/
			   Copyright( rastport );
			/****************************/
		        }
			break;
                     case ESC:
	                framenode = patriarch;
			while (framenode != NULL) {
			   if (framenode->datasize) 
			      FreeMem((UBYTE *)framenode->data,
			       framenode->datasize);
	                   FreeMem((UBYTE *)framenode->cmap,
			    framenode->cmapsize);
			   prevframenode = framenode;
			   framenode = framenode->next;
			   FreeMem((UBYTE *)prevframenode,sizeof(FrameNode));
			}
	                looping = FALSE;
	                break;
		     case F1:
		        frame_rate = 1;	/* 60 frames/second */
		        break;
		     case F2:
		        frame_rate = 2; /* 30 frames/second */
		        break;
		     case F3:
		        frame_rate = 3; /* 20 frames/second */
		        break;
		     case F4:
		        frame_rate = 4; /* 15 frames/second */
		        break;
		     case F5:
		        frame_rate = 5; /* 12 frames/second */
		        break;
		     case F6:
		        frame_rate = 6; /* 10 frames/second */
		        break;
		     case F7:
		        frame_rate = 8; /* 8 frames/second */
		        break;
		     case F8:
		        frame_rate = 10; /* 6 frames/second */
		        break;
		     case F9:
		        frame_rate = 12; /* 5 frames/second */
		        break;
		     case F10:
		        frame_rate = 15; /* 4 frames/second */
		        break;
		     case SPACE:
		        stop = FALSE;
			break;
		     case ARROWBACKWARD:
			if (up_or_down == UP)
			   direction = DOWN;
			break;
		     case ARROWFORWARD:
		        if (up_or_down == DOWN)
			   direction = UP;
		        break;
		     case ARROWUP:
			frame_rate += 1;
			break;
		     case ARROWDOWN:
		        frame_rate -= 1;
		        if (frame_rate < 1)
			   frame_rate = 1;
			break;
                  }
	       case MOUSEBUTTONS:
	          switch (code) {
		     case SELECTDOWN:
		        next = TRUE;
		        stop = TRUE;
			if (up_or_down == DOWN)
			   direction = UP;
		        break;
		     case MENUDOWN:
			next = TRUE;
			stop = TRUE;
			if (up_or_down == UP)
			   direction = DOWN;
		        break;
                  }
	          break;
            }
         }

         while (counter++ < frame_rate)
	    Wait( mask );

         LoadView( view );
         counter = 1;
         if ((!stop || next) && looping) {
            if (odd_frame) {
               bitmap = &bitmap1;
	       viewport = &viewport1;
	       view = &view1;  
	       rastport = &rastport1;
	       odd_frame = FALSE;
            }
            else {
               bitmap = &bitmap2;
	       viewport = &viewport2;
	       view = &view2;
	       rastport = &rastport2;
               odd_frame = TRUE;
            }

            if (framenode->next == NULL || direction == DOWN) {
               up_or_down = DOWN;
	       frame += up_or_down;
	       framenode = framenode->prev;
	       direction = STEADY;
	    }
            else if (framenode->prev == NULL || direction == UP) { 
               up_or_down = UP;
	       frame += up_or_down;
	       framenode = framenode->next;
	       direction = STEADY;
            }
            else {
	       frame += up_or_down;
	       if (up_or_down == DOWN) {
		  framenode = framenode->prev;
                  LoadRGB4( viewport, framenode->cmap, COLORS );
		  XORDLTAshort( bitmap, framenode->next->next->data );
	       }
	       else {
		  framenode = framenode->next;
                  LoadRGB4( viewport, framenode->cmap, COLORS );
		  XORDLTAshort( bitmap, framenode->data );
	       }
	    }

	    if (display_frame_number) {
	       stci_d( numbertext, frame, MAXNUMBERTEXT );
	       strncat( numbertext, "   ", MAXNUMBERTEXT-1 );
	       PrintIText( rastport, &framenumbertext, 310, 30 );
	    /**** retain this call  ****/
	       Copyright( rastport );
	    /***************************/
            }
            next = FALSE;
         }
   }
   window->Flags &= (RMBTRAP^0xFFFFFFFF);

   FreeSignal( signal );
   RemIntServer( INTB_VERTB, VertBIntr );
   FreeMem( VertBIntr, sizeof(struct Interrupt));
}
