/*------------ INCLUDE FILES ----------------*/

#include "common.h"


/*------------	DEFINES  -------------*/

#define NO_OUTPUT_FILE 1L
#define NO_ICON_FILE   2L
#define NO_INPUT_FILE  3L

#define CkErr(expression)  {if (ifferr == IFF_OKAY) ifferr = (expression);}


/*---------------  EXTERNAL STRUCTURES	-------------*/

extern struct Menu Menu1;
extern struct NewWindow NewWindowStructure1;
extern struct NewScreen NewScreenStructure;


/*---------------  EXTERNAL DATA  ------------------*/

extern USHORT Palette[4];
extern BOOL titleon;
extern AllPlotData *apd;


/*------------------ STRUCTURES ---------------*/

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct IconBase *IconBase;
struct ArpBase *ArpBase;
struct Library *ColorBase;
struct IFFBase *IFFBase;
struct ILBMBase *ILBMBase;

struct Screen *scr;
struct Window *win;
struct RastPort *rastport;
struct ViewPort *viewport;

struct Screen *setscr;
struct Window *setwin;
struct RastPort *setrastport;
struct ViewPort *setviewport;

static struct NewScreen newscr = {
   0,0,320,200,5,    /* LeftEdge, TopEdge, Width, Height, Depth */
   0,1, 	     /* DetailPen, BlockPen */
   NULL,	     /* ViewModes */
   CUSTOMSCREEN,     /* Type */
   NULL,	     /* Font */
   "3DPlot v2.0   1990 Randy Finch  (All Rights Reserved)", /* DefaultTitle */
   NULL,	     /* Gadgets */
   NULL 	     /* CustomBitMap */
};

static struct NewWindow newwin = {
    0,0,320,200,		/* LeftEdge, TopEdge, Width, Height */
    0,1,			/* DetailPen, BlockPen */
    MENUPICK | GADGETUP | GADGETDOWN | REQCLEAR,  /* IDCMPFlags */
    BACKDROP | ACTIVATE |
    SMART_REFRESH | BORDERLESS, /* Flags */
    NULL,			/* FirstGadget */
    NULL,			/* CheckMark */
    NULL,			/* Title */
    NULL,			/* Screen */
    NULL,			/* BitMap */
    20,20,			/* MinWidth, MinHeight */
    320,200,			/* MaxWidth, MaxHeight */
    CUSTOMSCREEN		/* Type */
};


/*----------------- EXTERNAL FUNCTIONS ----------------*/

extern VOID FreeAllPlotData(AllPlotData *);


/*------------------ FUNCTIONS -----------------*/

void finishup(code)
   LONG code;
{
   if(apd) FreeAllPlotData(apd);
   if(win) CloseWindow(win);
   if(scr) CloseScreen(scr);
   if(setwin) CloseWindow(setwin);
   if(setscr) CloseScreen(setscr);
   if(IntuitionBase) CloseLibrary(IntuitionBase);
   if(GfxBase) CloseLibrary(GfxBase);
   if(IconBase) CloseLibrary(IconBase);
   if(ArpBase) CloseLibrary(ArpBase);
   if(ColorBase) CloseLibrary(ColorBase);
   if(IFFBase) CloseLibrary(IFFBase);
   if(ILBMBase) CloseLibrary(ILBMBase);

   exit(code);

}  /* finishup */


void openlibraries()
{
   IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",33);
   if(!IntuitionBase) {
      puts("Unable to open Intuition Library\n");
      finishup(FALSE);
   }

   GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",33);
   if(!GfxBase) {
      puts("Unable to open Graphics Library\n");
      finishup(FALSE);
   }

   IconBase = (struct IconBase *) OpenLibrary("icon.library",33);
   if (!IconBase) {
      puts("Can't open icon.library\n");
      finishup(FALSE);
   }

   ArpBase = (struct ArpBase *) OpenLibrary("arp.library",0);
   if (!ArpBase) {
      puts("Can't open arp.library\n");
      finishup(FALSE);
   }

   ColorBase = (struct Library *) OpenLibrary("color.library",0);
   if (!ColorBase) {
      puts("Can't open color.library\n");
      finishup(FALSE);
   }

   IFFBase = (struct IFFBase *) OpenLibrary("iff.library",0);
   if (!IFFBase) {
      puts("Can't open iff.library\n");
      finishup(FALSE);
   }

   ILBMBase = (struct ILBMBase *) OpenLibrary("ilbm.library",0);
   if (!ILBMBase) {
      puts("Can't open ilbm.library\n");
      finishup(FALSE);
   }

}   /* openlibraries */


void opendisplay()
{
   scr = (struct Screen *) OpenScreen(&newscr);

   if(!scr) {
      puts("Screen failed\n");
      finishup(FALSE);
   }

   newwin.Screen = scr;
   win = (struct Window *) OpenWindow(&newwin);

   if(!win) {
       puts("Window failed.\n");
       finishup(FALSE);
   }

   if(titleon) {
      ShowTitle(scr, TRUE);
   }
   else {
      ShowTitle(scr, FALSE);
   }
   SetMenuStrip(win, &Menu1);

   viewport = (struct ViewPort *) ViewPortAddress(win);
   rastport = win->RPort;

}    /* opendisplay */


LONG loaddisplay(STRPTR fn)
   /* fn is filename */
{
   APTR ifffile = NULL;
   long count;
   UWORD colortable[128];
   struct BitMapHeader *bmhd;

   /* Close current screen first */
   ClearMenuStrip(win);
   CloseWindow(win);
   CloseScreen(scr);

   /* Open new file and get bitmap header */
   if(!(ifffile=OldOpenIFF(fn)))        return IffError();
   if(!(bmhd=GetIFFBMHD(ifffile)))   return IffError();

   newscr.Width      = bmhd->w;
   newscr.Height     = bmhd->h;
   newscr.Depth      = bmhd->nPlanes;
   newscr.ViewModes  = GetViewModes(ifffile);

   scr = (struct Screen *) OpenScreen(&newscr);
   if(!scr) {
      puts("Screen failed\n");
      finishup(FALSE);
   }

   newwin.Screen = scr;
   newwin.Width = newscr.Width;
   newwin.MaxWidth = newscr.Width;
   newwin.Height = newscr.Height;
   newwin.MaxHeight = newscr.Height;

   win = (struct Window *) OpenWindow(&newwin);
   if(!win) {
       puts("Window failed.\n");
       finishup(FALSE);
   }

   count = GetColorTab(ifffile,colortable);
   if(count>32L) count = 32L; /* Some HAM pictures have 64 colors ?! */
   LoadRGB4(&(scr->ViewPort),colortable,count);

   viewport = (struct ViewPort *) ViewPortAddress(win);
   rastport = win->RPort;
   SetMenuStrip(win, &Menu1);
   ShowTitle(scr, FALSE);  /* Turn off for loading pic */
   if(!DecodePic(ifffile,rastport->BitMap)) {
      CloseWindow(win);
      CloseScreen(scr);
      return IffError();
   }

   /* Turn on title if necessary */
   if(titleon) {
      ShowTitle(scr, TRUE);
   }

   CloseIFF(ifffile);

   return 0L;
}    /* loaddisplay */


LONG loadcolors(STRPTR fn)
   /* fn is filename */
{
   APTR ifffile = NULL;
   long count;
   UWORD colortable[128];

   /* Open new file and get colors */
   if(!(ifffile=OldOpenIFF(fn)))   return IffError();
   count = GetColorTab(ifffile,colortable);
   if(count>32L) count = 32L; /* Some HAM pictures have 64 colors ?! */
   LoadRGB4(&(scr->ViewPort),colortable,count);

   CloseIFF(ifffile);

   return 0L;
}    /* loadcolors */


IFFP savecolors(STRPTR filename)
{
  LONG		 file;
  IFFP		 ifferr = IFF_OKAY;
  GroupContext	 fileContext, formContext;

  if (!(file = Open(filename, MODE_NEWFILE))) {
     printf("Can't open output file\n");
     return (NO_OUTPUT_FILE);
  }

  Write(file,"x",1);  /* 1.1 so Seek to beginning works ? */

#if DEBUG
  printf("\nSaving...\n");
#endif

  CkErr( OpenWIFF(szNotYetKnown, file, &fileContext) );
  CkErr( StartWGroup(FORM,szNotYetKnown,ID_ILBM,&fileContext,&formContext) );
  CkErr( PutCMAP(scr->BitMap.Depth, &formContext, viewport->ColorMap->ColorTable) );
  CkErr( EndWGroup(&formContext) );
  CkErr( CloseWGroup(&fileContext) );

  Close(file);

#if DEBUG
  if (ifferr == IFF_OKAY) {
     printf("3DPL IFF saved\n");
  }
  else {
     printf("Error on save\n");
  }
#endif

  return(ifferr);

}  /* savecolors */


void opendisplayset()
{
   setscr = (struct Screen *) OpenScreen(&NewScreenStructure);

   if(!setscr) {
      puts("Screen failed\n");
      finishup(FALSE);
   }

   NewWindowStructure1.Screen = setscr;
   setwin = (struct Window *) OpenWindow(&NewWindowStructure1);

   if(!setwin) {
       puts("Window failed.\n");
       finishup(FALSE);
   }

  SetMenuStrip(setwin, &Menu1);

  setviewport = (struct ViewPort *) ViewPortAddress(setwin);
  setrastport = setwin->RPort;

  LoadRGB4(setviewport, Palette, 4);

}    /* opendisplayset */


void ChangeResolution(res)
  UBYTE res;
{
  BOOL change = FALSE;

  switch(res) {

     case SCREENLOWRES:
	if(newscr.Width != 320) {
	   newscr.Width = 320;
	   newscr.Depth = 5;
	   newscr.ViewModes &= ~HIRES;

	   newwin.Width = 320;
	   newwin.MaxWidth = 320;

	   change = TRUE;
	}
	break;

     case SCREENHIGHRES:
	if(newscr.Width != 640) {
	   newscr.Width = 640;
	   newscr.Depth = 4;
	   newscr.ViewModes |= HIRES;

	   newwin.Width = 640;
	   newwin.MaxWidth = 640;

	   change = TRUE;
	}
	break;

     case SCREENINTERLACE:
	if(newscr.Height != 400) {
	   newscr.Height = 400;
	   newscr.ViewModes |= LACE;

	   newwin.Height = 400;
	   newwin.MaxHeight = 400;

	   change = TRUE;
	}
	break;

     case SCREENNONINTERLACE:
	if(newscr.Height != 200) {
	   newscr.Height = 200;
	   newscr.ViewModes &= ~LACE;

	   newwin.Height = 200;
	   newwin.MaxHeight = 200;

	   change = TRUE;
	}
	break;

     case SCREENNORMAL:
     case SCREENMEDIUMOVERSCAN:
     case SCREENSEVEREOVERSCAN:
	break;

     default:
	break;

  } /* switch */

  if (change == TRUE) {
     ClearMenuStrip(win);
     CloseWindow(win);
     CloseScreen(scr);

     opendisplay();

  } /* if */

} /* ChangeResolution */

