#include "pz.h"
#include "smalliff.h"

/* IFF2PCS, main() and various other routines...
** IFF2PCS (c)1987 Ali T. Ozer
** Nov 1987
*/
struct Library *IntuitionBase, *GfxBase, *LayersBase;
 
PicInfoStruct      pic;
struct Screen     *scr0;
struct FileHandle *fp, *ParseArgs ();

int runningfromcli;

extern struct Menu pzmenu;
int textcolor, bordercolor, normcolor, nonzerocolor;
int puzpn, puzdepth;   /* These are the parameters for a piece */
int picx, picy;        /* Where the picture is */
int picw, pich;        /* The size of the picture */

struct BitMap picbm;  /* All plane pointers start as NULL */

/* Panic puts up a requester with a single "Sigh..." box. The string
** provided in "reason" is printed in the body of the  requester. 
** If user hits "Retry," then Panic returns. Else it exits.
*/
void Panic (reason)
UBYTE *reason;
{
  static struct IntuiText negtxt  = {0,1,COMPLEMENT,4,4,NULL,(UBYTE *)"Sigh...",NULL};
  static struct IntuiText bodytxt = {0,1,COMPLEMENT,10,6,NULL,NULL,NULL};

  if (reason) {
    if (runningfromcli == true) puts (reason);
    else {
      bodytxt.IText = reason;
      WBenchToFront ();
      if (AutoRequest (NULL, &bodytxt, NULL, &negtxt, 0L, 0L, 
                             (long)(Max(Min(strlen(reason)*10+50,625),200)),
                             54L) == TRUE) return;
    }
  };
  CleanUp ();
  exit (5);
}


CleanUp ()
{
  FreePzMenu ();  

  FreeBM (&picbm);

  if (pic.rawsource) FreeMem (pic.rawsource, pic.rawsourcesize);

  if (scr0) {
    if (scr0->FirstWindow) {
    /*if (scr0->FirstWindow->MenuStrip) ClearMenuStrip (scr0->FirstWindow);*/
      CloseWindow (scr0->FirstWindow);  /* Assume only 1 */
    };
    CloseScreen  (scr0);
  };
 
  if (LayersBase)        CloseLibrary (LayersBase);
  if (GfxBase)           CloseLibrary (GfxBase);
  if (IntuitionBase)     CloseLibrary (IntuitionBase);
}

int Min ();
int Max ();

struct TextAttr NormalFontDesc = {(STRPTR)"topaz.font", 8, 0, 0};

struct Screen *OpenPictureScreen (pic, borderpen, detailpen)
PicInfoStruct *pic;
{
  struct NewScreen ns;
  struct NewWindow nw;

  setmem (&ns, sizeof(ns), 0);
  setmem (&nw, sizeof(nw), 0);

  ns.DefaultTitle  = (UBYTE *)PROGNAME;
  ns.Font = &NormalFontDesc; 
  ns.Width  = nw.Width  = 
       ((struct GfxBase *)GfxBase)->NormalDisplayColumns;    /* pic->bmhd.w; */
  ns.Height = nw.Height =
       ((struct GfxBase *)GfxBase)->NormalDisplayRows * 2; /* pic->bmhd.h; */
  ns.DetailPen = nw.DetailPen = detailpen; 
  ns.BlockPen  = nw.BlockPen  = borderpen;  
  ns.Depth  = pic->bmhd.nPlanes;  
  ns.Type   = nw.Type   = CUSTOMSCREEN;
  nw.Flags  = SMART_REFRESH | BORDERLESS | BACKDROP | RMBTRAP | ACTIVATE;
  nw.IDCMPFlags = MOUSEBUTTONS | MOUSEMOVE | GADGETUP /*| MENUPICK*/;
  ns.ViewModes  = HIRES | LACE;  /* pic->viewmodes; */
  if (nw.Screen = OpenScreen (&ns)) {
    if (OpenWindow (&nw)) return (nw.Screen);
    else CloseScreen (nw.Screen);
  } else {   /* Try with a smaller screen and see if we can open that. */
    ns.Width  = nw.Width  = 640;
    ns.Height = nw.Height = 400;
    if (nw.Screen = OpenScreen (&ns)) {
      if (OpenWindow (&nw)) return (nw.Screen);
      else CloseScreen (nw.Screen);
    } else return (NULL);
  }
}

/* Macros to extract the color components from a 12-bit RGB color value */
#define RED(c)   ((c & 0x0F00) >> 8)
#define GREEN(c) ((c & 0x00F0) >> 4)
#define BLUE(c)  (c & 0x000F)

/* Follows the 11% Blue, 30% Red, 59% Green rule, returns a number 0..15 */
UWORD RGBtoGray (c)
UWORD c;
{
  return (((RED(c) * 77) + (GREEN(c) * 151) + (BLUE(c) * 28)) >> 4);
}


FindColors (cmap, numcolors)
UWORD *cmap;
int numcolors;
{
  int fdiff = -1, cdiff = 256, ndiff = -1; /* Differences for various colors */
  int cnt, cur, color0;

  textcolor = 0;
  bordercolor = 1;
  normcolor = -1;
  if (numcolors > 2) {
    color0 = RGBtoGray (cmap[0]);
    for (cnt = 1; cnt < numcolors; cnt++) {
      cur = RGBtoGray (cmap[cnt]) - color0;
      cur = (cur < 0 ? -cur : cur);
      if (cur > fdiff) {fdiff = cur; textcolor = cnt;};
      if (cur > ndiff && cur < 150) {ndiff = cur; normcolor = cnt;};
      if (cur < cdiff && cur > color0+15) {cdiff = cur; bordercolor = cnt;};
    }  
  }
  if (normcolor == -1) normcolor = textcolor;
  else textcolor = normcolor;
  if (textcolor == bordercolor) textcolor = 0;
  if (normcolor == bordercolor) normcolor = 0;
  if (textcolor == 0) nonzerocolor = bordercolor; else nonzerocolor = textcolor;
}

extern struct WBStartup *WBenchMsg;

main(argc,argv)
int  argc;
char **argv;
{
  int scrw, scrh, scrd, scrc, cnt;

  runningfromcli = (argc == 0 ? false : true);

  if ((!(IntuitionBase = OpenLibrary ("intuition.library", 0L))) ||
      (!(GfxBase = OpenLibrary ("graphics.library", 0L))) ||
      (!(LayersBase = OpenLibrary ("layers.library", 0L)))) Panic ("No libs!");

  InitRnd ();  /* Initialize the random number generator */

  if ((fp = ParseArgs (argc, argv, WBenchMsg)) == NULL)
    Panic ("Could not open file");

  if (ReadILBM (fp, &pic) == false) {
    Close (fp); 
    Panic ("File error - Maybe not IFF?");
  };
  Close (fp); 

  scrw = pic.bmhd.w;         /* Screen width in BITS */
  scrh = pic.bmhd.h;         /* Screen height in SCANLINES */
  scrd = pic.bmhd.nPlanes;   /* Screen depth in BIT PLANES */
  scrc = pic.colorcount;     /* Screen colors in # of REGISTERS */

/*printf ("Scrw %d Scrh %d Scrd %d Scrc %d\n", scrw, scrh, scrd, scrc);*/

/*if ((scrw > 352) || (scrh > 235)) Panic ("Need a LO-RES picture");*/

  if (scrd > 4) Panic ("Ack! No more than 16 colors!");
  if (scrw < 64 || scrh < 64) Panic ("Picture too small");

  /* Create a bitmap, expand the picture, and get rid of the compressed pic.
  */  

  if (InitBM  (&picbm, scrh, scrw, scrd) == false) Panic ("No memory for picture");

  Expand  (&picbm, &(pic.bmhd), pic.rawsource);

  FreeMem (pic.rawsource, pic.rawsourcesize);
  pic.rawsource = NULL;

  FindColors (&(pic.colortable), 1 << scrd);

  if ((scr0 = OpenPictureScreen (&pic, bordercolor, normcolor)) == NULL)
    Panic ("No memory for screen");
  LoadRGB4 (&(scr0->ViewPort), &(pic.colortable), (LONG)scrc);

  /* For now, FORCE some values... */
  puzdepth = scrd;
  picx     = 8;
  picy     = 16;
  pich     = Min (scrh, scr0->Height-picy-180);
  picw     = Min (scrw, scr0->Width-picx*2);

/* A word on colors: Globally,
**  normcolor is used for text (different than background, but not much)
**  textcolor is used for bright stuff (highlights)
**  bordercolor is slightly different than background
*/

  if (InitPzMenu (scrd, normcolor, normcolor, bordercolor) == false) 
    Panic ("No memory for menu");

  GetAndHandleEvents (scr0->FirstWindow);

  CleanUp ();

}

