/*
 *  ScreenSave.c --  Carolyn Scheppner  CBM  10/86
 *                   Saves front screen as ILBM file
 *                   Saves a CAMG chunk for HAM, etc.
 *
 *  Renamed to SaveIt-Modifications by Steven Dillon for the M.A.K.
 *
 *     Uses IFF rtns by J.Morrison and S.Shaw of Electronic Arts
 *
 *
 */

#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <graphics/gfxbase.h>
#include <graphics/rastport.h>
#include <graphics/gfx.h>
#include <graphics/view.h>

#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>

#include "iff/ilbm.h"

/* CAMG Stuff */
typedef struct {
   ULONG ViewModes;
   } CamgChunk;

#define PutCAMG(context, camg)  \
    PutCk(context, ID_CAMG, sizeof(CamgChunk),(BYTE *)camg)

#define bufSize 512


extern struct IntuitionBase *IntuitionBase;
extern struct Screen *FirstScreen;
extern struct Window *NoBorder;

struct Screen   *frontScreen;

struct ViewPort *picViewPort;
struct BitMap   *picBitMap;
WORD            *picColorTable;
ULONG            picViewModes;


#define INBUFSZ 40
char sbuf[INBUFSZ];
char nbuf[INBUFSZ];


SaveIt(File_Name)
char *File_Name;
  {
   LONG file;
   IFFP iffp = NO_FILE;
  
   WindowToFront(NoBorder);
   
   if (!(file = Open(File_Name, MODE_NEWFILE)))
     {
      printf("Can't open file %s",File_Name," for output\n");
      return(FALSE);
     } 
  
     
   Write(file,"x",1);  /* 1.1 so Seek to beginning works ? */

  
   frontScreen  = FirstScreen; 
  
   picViewPort = &(frontScreen->ViewPort);
   picBitMap = (struct BitMap*)picViewPort->RasInfo->BitMap;
   picColorTable = (WORD *)picViewPort->ColorMap->ColorTable;
   picViewModes = (ULONG)picViewPort->Modes;

  
   iffp = PutPicture(file, picBitMap, picColorTable, picViewModes);
   Close(file);

   
  } /* SaveIt */



/** PutPicture() ***********************************************************
 *
 * Put a picture into an IFF file.
 * This procedure calls PutAnILBM, passing in an <x, y> location of <0, 0>,
 * a NULL mask, and a locally-allocated buffer. It also assumes you want to
 * write out all the bitplanes in the BitMap.
 *
 ***************************************************************************/
Point2D nullPoint = {0, 0};

IFFP PutPicture(file, bitmap, colorMap, viewmodes)
      LONG file;  struct BitMap *bitmap;
      WORD *colorMap;  ULONG viewmodes;
   {
   BYTE buffer[bufSize];
   return( PutAnILBM(file, bitmap, NULL,
           colorMap, bitmap->Depth, viewmodes,
           &nullPoint, buffer, bufSize) );
   }    

   
/** PutAnILBM() ************************************************************
 *
 * Write an entire BitMap as a FORM ILBM in an IFF file.
 * This version works for any display mode (C. Scheppner).
 *
 * Normal return result is IFF_OKAY.
 *
 * The utility program IFFCheck would print the following outline of the
 * resulting file:
 *
 *   FORM ILBM
 *     BMHD
 *     CAMG
 *     CMAP
 *     BODY       (compressed)
 *
 ***************************************************************************/
#define CkErr(expression)  {if (ifferr == IFF_OKAY) ifferr = (expression);}

IFFP PutAnILBM(file, bitmap, mask, colorMap, depth,
                                viewmodes, xy, buffer, bufsize)
      LONG file;
      struct BitMap *bitmap;
      BYTE *mask;  WORD *colorMap; UBYTE depth;
      ULONG viewmodes;
      Point2D *xy; BYTE *buffer;  LONG bufsize;
   {
   BitMapHeader bmHdr;
   CamgChunk    camgChunk;
   GroupContext fileContext, formContext;
   IFFP ifferr;
   WORD pageWidth, pageHeight;

   pageWidth  = (bitmap->BytesPerRow) << 3;
   pageHeight = bitmap->Rows;

   ifferr = InitBMHdr(&bmHdr, bitmap, mskNone,
                      cmpByteRun1, 0, pageWidth, pageHeight);
   /* You could write an uncompressed image by passing cmpNone instead
    * of cmpByteRun1 to InitBMHdr. */
   bmHdr.nPlanes = depth;   /* This must be  <= bitmap->Depth */
   if (mask != NULL) bmHdr.masking = mskHasMask;
   bmHdr.x = xy->x;   bmHdr.y = xy->y;

   camgChunk.ViewModes = viewmodes;

   CkErr( OpenWIFF(file, &fileContext, szNotYetKnown) );
   CkErr(StartWGroup(&fileContext, FORM, szNotYetKnown, ID_ILBM, &formContext));

   CkErr( PutBMHD(&formContext, &bmHdr) );
   CkErr( PutCAMG(&formContext, &camgChunk) );
   CkErr( PutCMAP(&formContext, colorMap, depth) );
   CkErr( PutBODY(&formContext, bitmap, mask, &bmHdr, buffer, bufsize) );

   CkErr( EndWGroup(&formContext) );
   CkErr( CloseWGroup(&fileContext) );
   return( ifferr );
   }
   

