/***************************************************************************
 *
 *   NAME 
 *      Call_Pack -- load an ANIM 
 *
 *   SYNOPSIS
 *      patriarch = Call_Pack( animnamestring, bitmap1, bitmap2, 
 *       viewport1, viewport2 );
 *
 *      FrameNode *patriarch;
 *
 *	char *animnamestring;
 *      struct BitMap *bitmap1, *bitmap2;
 *      struct ViewPort *viewport1, *viewport2;
 *
 *   DESCRIPTION
 *      Load an ANIM from disk.  Exit if Read error.  This particular
 *      ANIM packing method has two standard IFF files for the first
 *      two frames, followed by specially packed files.  Even files 
 *	modify only each other, as do odd files.  Files always start
 *      at "1".  Files "1" and "2" are standard IFF.
 *  
 *      copyright (c) 1987 Martin D. Hash
 *
 *   LAST EDITED
 *      Martin Hash			23 Aug 1987
 *
 *   EDIT HISTORY
 *      27 Mar 1987  MH  Created.
 *      20 Apr           Saved palette also.
 *       9 Jun           Faster playback.
 *      16 Aug		 ANIM standard.
 *
 **********************************************************************/

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include "df1:FileCons.h"
#include "df1:ANIMCons.h"

/* LOCAL CONSTANTS */

#define Abort()		goto Read_Error_Exit

/* FUNCTION */

FrameNode *Call_Pack( animnamestring, bitmap1, bitmap2, viewport1, viewport2 )

char *animnamestring;
struct BitMap *bitmap1, *bitmap2;
struct ViewPort *viewport1, *viewport2;
{
   /* LOCAL VARIABLES */

   int frame,
       i,
       count,
       colors;
   char name[STRINGSIZE],
	header[HEADERSIZE],
	frametext[MAXNUMBERTEXT];
   BPTR file;
   ULONG size,
	 cmapsize = 0,
	 datasize;
   ANHD anhd;
   UWORD *cmap, *cmapptr,
	 *data;
   FrameNode *prevframenode = NULL,
	     *framenode,
	     *patriarch = NULL,
	     **uplink;
   ColorReg colorreg;
   
   /* CODE */

   colors = COLORS;

   uplink = &patriarch;
   for (frame = 1; TRUE; ++frame) {
      stci_d( frametext, frame, sizeof(frametext));
      strcpy( name, animnamestring );
      strcat( name, "/" );
      strcat( name, frametext );
      if ((file = Open( name, MODE_OLDFILE )) == 0)
         return patriarch;
      
      if (frame == 1) {
         if (!ReadPicture( file, bitmap1, viewport1 ))
	    Abort();
         if (Read( file, &header, HEADERSIZE*sizeof(char)) == -1)
	    Abort();
         if (Read( file, &size, sizeof(ULONG)) == -1)
            Abort();
         if (Read( file, &header, HEADERSIZE*sizeof(char)) == -1)
	    Abort();
         if (Read( file, &header, HEADERSIZE*sizeof(char)) == -1)
	    Abort();
         if (Read( file, &size, sizeof(ULONG)) == -1)
            Abort();
         if (Read( file, &anhd, sizeof(ANHD)) == -1)
            Abort();

         if ((cmap = (UWORD *)AllocMem( colors*sizeof(UWORD),
          MEMF_CHIP )) == NULL)
	    Abort();
	 cmapptr = (UWORD *)viewport1->ColorMap->ColorTable;
	 for (i = 0; i < colors; ++i)
	    cmap[i] = cmapptr[i];
	 data = NULL;
	 datasize = 0;
      }
      else if (frame == 2) {
         if (!ReadPicture( file, bitmap2, viewport2 ))
	    Abort();
         if (Read( file, &header, HEADERSIZE*sizeof(char)) == -1)
	    Abort();
         if (Read( file, &size, sizeof(ULONG)) == -1)
            Abort();
         if (Read( file, &header, HEADERSIZE*sizeof(char)) == -1)
	    Abort();
         if (Read( file, &header, HEADERSIZE*sizeof(char)) == -1)
	    Abort();
         if (Read( file, &size, sizeof(ULONG)) == -1)
            Abort();
         if (Read( file, &anhd, sizeof(ANHD)) == -1)
            Abort();

         if ((cmap = (UWORD *)AllocMem( colors*sizeof(UWORD),
          MEMF_CHIP )) == NULL)
	    Abort();
	 cmapptr = (UWORD *)viewport1->ColorMap->ColorTable;
	 for (i = 0; i < colors; ++i)
	    cmap[i] = cmapptr[i];
	 data = NULL;
	 datasize = 0;
      }
      else {
         if (Read( file, &header, HEADERSIZE*sizeof(char)) == -1)
            Abort();
         if (Read( file, &size, sizeof(ULONG)) == -1)
            Abort();
         if (Read( file, &header, HEADERSIZE*sizeof(char)) == -1)
            Abort();
         if (Read( file, &header, HEADERSIZE*sizeof(char)) == -1)
            Abort();
         if (Read( file, &cmapsize, sizeof(ULONG)) == -1)
            Abort();
         count = cmapsize/3;
         if ((cmap = (UWORD *)AllocMem( colors*sizeof(UWORD),
          MEMF_CHIP )) == NULL)
	    Abort();
	 cmapptr = cmap;
	 while (count--) {
            if (Read( file, &colorreg, sizeof(ColorReg)) == -1) { 
	       FreeMem((UBYTE *)cmap, colors*sizeof(UWORD));
               Abort();
	    }
            *cmapptr++ = ((colorreg.red   >>4) <<8) | 
		         ((colorreg.green >>4) <<4) |
		          (colorreg.blue  >>4);
         }
         if (Read( file, header, HEADERSIZE*sizeof(char)) == -1) {
	    FreeMem((UBYTE *)cmap, colors*sizeof(UWORD));
            Abort();
	 }
         if (Read( file, &datasize, sizeof(ULONG)) == -1) {
	    FreeMem((UBYTE *)cmap, colors*sizeof(UWORD));
            Abort();
	 }
         if ((data = (UWORD *)AllocMem( datasize, 0 )) == NULL) {
	    FreeMem((UBYTE *)cmap, colors*sizeof(UWORD));
	    Abort();
         }
         if (Read( file, data, datasize ) == -1) {
            FreeMem((UBYTE *)cmap, colors*sizeof(UWORD));
            Abort();
	 }
      }

      Close( file );
      if ((framenode = (FrameNode *)AllocMem( sizeof(FrameNode), 0 ))
       == NULL) {
         FreeMem((UBYTE *)cmap, colors*sizeof(UWORD));
         FreeMem((UBYTE *)data, datasize );
         Abort();
      } 	
      framenode->prev = prevframenode;
      framenode->next = NULL;
      prevframenode = framenode;
      *uplink = framenode;
      uplink = &framenode->next;
      framenode->cmap = cmap;
      framenode->cmapsize = colors*sizeof(UWORD);
      framenode->data = data;
      framenode->datasize = datasize;
   }
   return patriarch;

Read_Error_Exit:
   Close( file );
   return patriarch;  
}

