/****************************************************************************

				Print.c

	This file is used whenever a structure must be printed fully.
	Structures that can be printed are Windows, Gadgets, Menus and
	even full Screens!
	This file is supposed to be linked with Basic.o.

					Rick van Rein, October 30, 1990

****************************************************************************/



#include <functions.h>
#include <intuition/intuition.h>
#include <stdio.h>

void PrintDrawMode ();
void PrintPen ();
void PrintFlags ();
void PrintStr ();
void mprintf ();		/* Use it like you would use printf. Insert a '\t' for tab to X=49 */

extern struct Image *StdCheckMark;	/* Address of default CheckMark as is probably in ROM */

#define abs(x) (((x) >= 0)? (x): (-(x)))


#define INTUITEXT	0
#define BORDER		1
#define BORDERCOORDS	2
#define IMAGE		3
#define IMAGEDATA	4
#define GADGET		5
#define BOOLINFO	6
#define PROPINFO	7
#define STRINGINFO	8
#define STRINGBUF	9
#define STRINGUNDO	10
#define WINDOW		11
#define PROPBUF		12
#define MENU		13
#define MENUITEM	14
#define NEWSCREEN	15
#define COLORMAP	16
#define WINDOWARRAY	17
#define MENUARRAY	18


extern char *StructNames [];

extern int ctr [];



/***** Print a struct IntuiText: */

static int PrintIntuiText (itx)		/* Returns number N within label itxN */
   struct IntuiText *itx;
 {
   int me,child;

   if (itx->NextText)
      child=PrintIntuiText (itx->NextText);
   mprintf ("\nstruct IntuiText %s%d=\n {\n   ",StructNames [INTUITEXT],me=++ctr [INTUITEXT]);
   PrintPen (itx->FrontPen);
   mprintf (",");
   PrintPen (itx->BackPen);
   mprintf (",\t/* FrontPen, BackPen */\n   ");
   PrintDrawMode (itx->DrawMode);
   mprintf (",\t/* DrawMode */\n   ");
   mprintf ("%d,%d,\t/* LeftEdge, TopEdge */\n   ",itx->LeftEdge,itx->TopEdge);
   mprintf ("NULL,\t/* ITextFont */\n   (UBYTE *) ");
   PrintStr (itx->IText);
   mprintf (",\t/* IText */\n   ");
   if (itx->NextText)
      mprintf ("&%s%d\t/* NextText */\n };\n",StructNames [INTUITEXT],child);
   else
      mprintf ("NULL\t/* NextText */\n };\n");
   return me;
 }


/***** Print a struct Border: */

static int PrintBorder (bor)
   struct Border *bor;
 {
   int child,me,i;

   if (bor->NextBorder)
      child=PrintBorder (bor->NextBorder);
   mprintf ("\nSHORT %s%d []=\n",StructNames [BORDERCOORDS],me=++ctr [BORDERCOORDS]);
   for (i=0;i<bor->Count;i++)
      mprintf ("%s\n   %d,%d",i? ",": " {",bor->XY [i+i],bor->XY [i+i+1]);
   mprintf ("\n };\n\nstruct Border %s%d=\n {\n   ",StructNames [BORDER],me);
   mprintf ("%d,%d,\t/* LeftEdge,TopEdge */\n   ",bor->LeftEdge,bor->TopEdge);
   PrintPen (bor->FrontPen);
   mprintf (",");
   PrintPen (bor->BackPen);
   mprintf (",\t/* FrontPen, BackPen */\n   ");
   PrintDrawMode (bor->DrawMode);
   mprintf (",\t/* DrawMode */\n   ");
   mprintf ("%d,\t/* Count */\n   %s%d,\t/* XY */\n   ",bor->Count,StructNames [BORDERCOORDS],me);
   if (bor->NextBorder)
      mprintf ("&%s%d\t/* NextBorder */\n };\n",StructNames [BORDER],child);
   else
      mprintf ("NULL\t/* NextBorder */\n };\n");
   return me;
 }


/***** Print the data that is needed for an Image; Print anything from the { on: */

static void PrintImageData (img)
   struct Image *img;
 {
   int pl,plc,hg,hgc,wd,wdc;
   USHORT *dataptr=img->ImageData;
   UBYTE pick,onoff;

   pl=img->Depth;
   wd=(img->Width + 15) >> 4;	/* Make the width a word-counter */
   hg=img->Height;
   onoff=img->PlaneOnOff;
   plc=0;

   mprintf (" {\n");
   		/* Start printing the planes needed: */
   for (pick=img->PlanePick;pick;pick>>=1)
    {
      if (!(pick & 0x01))
       {
         if (onoff & 0x01)
	    mprintf ("                /* Plane %d consists of a filled rectangle */\n",plc);
	 else
	    mprintf ("                /* Plane %d is not filled anyhow */\n",plc);
       }
      else
       {
         mprintf ("                /* Plane %d contains a picture: */\n",plc);

	 	/* Start printing the lines needed: */
         for (hgc=0;hgc<hg;hgc++)
	  {

            mprintf ("   ");
	    	/* Start printing each word in the line: */
	    for (wdc=0;wdc<wd;wdc++)
	       mprintf ("0x%04x%s",*(dataptr++),((wdc+1<wd) || (hgc+1<hg) || ((pick & 0xfe)!=0))? ",": "");
	    mprintf ("\n");
	  }
       }
      onoff>>=1;
      plc++;
    }
   mprintf (" };\n");
 }


/***** Print a struct Image: */

static int PrintImage (img)
   struct Image *img;
 {
   int child,me;

   if (img->NextImage)
      child=PrintImage (img->NextImage);
   me=++ctr [IMAGE];

   if (img->ImageData)
    {
      mprintf ("\nUSHORT %s%d []=\n",StructNames [IMAGEDATA],me);
      PrintImageData (img);
    }

   mprintf ("\nstruct Image %s%d=\n {\n   ",StructNames [IMAGE],me);
   mprintf ("%d,%d,\t/* LeftEdge,TopEdge */\n   ",img->LeftEdge,img->TopEdge);
   mprintf ("%d,%d,%d,\t/* Width,Height,Depth */\n   ",img->Width,img->Height,img->Depth);
   
   if (img->ImageData)
      mprintf ("%s%d,\t/* ImageData */\n   ",StructNames [IMAGEDATA],me);
   else
      mprintf ("NULL,\t/* ImageData */\n   ");

   mprintf ("0x%02x,0x%02x,\t/* PlanePick,PlaneOnOff */\n   ",img->PlanePick,img->PlaneOnOff);

   if (img->NextImage)
      mprintf ("&%s%d\t/* NextImage */\n };\n",StructNames [IMAGE],child);
   else
      mprintf ("NULL\t/* NextImage */\n };\n");

   return me;
 }



/***** Print a struct BoolInfo (Yes, it DOES seem to exists!): */

static void PrintBoolInfo (bin,me,wd,hg)
   struct BoolInfo *bin;
   int me;
   int wd,hg;
 {
   struct Image img;

   if (bin->Flags)
    {
      img.Width=wd;
      img.Height=hg;
      img.Depth=1;
      img.PlaneOnOff=0x01;
      img.PlanePick=0x00;
      img.ImageData=bin->Mask;
      mprintf ("\nUWORD %s%d=\n",StructNames [IMAGEDATA],me);
      PrintImageData (&img);
    }
   mprintf ("\nstruct BoolInfo %s%d=\n {\n   ",StructNames [BOOLINFO],me);
   if (bin->Flags)
      mprintf ("BOOLMASK,\t/* Flags */\n   %s%d,\t/* Mask */\n   ",StructNames [IMAGEDATA],me);
   else
      mprintf ("0,\t/* Flags */\n   NULL,\t/* Mask */\n   ");
   mprintf ("0x%08lx\t/* Reserved */\n };\n",bin->Reserved);
 }


/***** Print a struct StringInfo: */

static void PrintStringInfo (sin,me)
   struct StringInfo *sin;
   int me;
 {
   mprintf ("\nchar %s%d [%d]=",StructNames [STRINGBUF],me,sin->MaxChars);
   PrintStr (sin->Buffer);	/* It should be initialized, shouldn't it? */
   mprintf (";\n\nchar %s%d [%d];\n",StructNames [STRINGUNDO],me,sin->MaxChars);
   mprintf ("\nstruct StringInfo %s%d=\n {\n   ",StructNames [STRINGINFO],me);
   mprintf ("(UBYTE *) %s%d,(UBYTE *) %s%d,\t/* Buffer,UndoBuffer */\n   ",StructNames [STRINGBUF],me,StructNames [STRINGUNDO],me);
   mprintf ("%d,\t/* BufferPos */\n   ",sin->BufferPos);
   mprintf ("%d,\t/* MaxChars */\n   ",sin->MaxChars);
   mprintf ("%d\t/* DispPos */\n",sin->DispPos);
   mprintf ("\t/* Intuition initializes and maintains all other variables for you */\n };\n");
 }


long PropFlagsFld []=
 { AUTOKNOB, FREEHORIZ, FREEVERT, PROPBORDERLESS, KNOBHIT, 0L };

#define PropFlags PropFlagsFld

char *PropFlagsNms []=
 { "AUTOKNOB", "FREEHORIZ", "FREEVERT", "PROPBORDERLESS", "KNOBHIT" };


/***** Print a struct PropInfo: */

static void PrintPropInfo (pin,me)
   struct PropInfo *pin;
   int me;
 {
   mprintf ("\nstruct PropInfo %s%d=\n {\n   ",StructNames [PROPINFO],me);
   PrintFlags ((long) pin->Flags,PropFlagsFld,PropFlags,PropFlagsNms);
   mprintf (",\t/* Flags */\n   ");
   mprintf ("%d,%d,\t/* HorizPot,VertPot (%d,%d%%) */\n   ",pin->HorizPot,pin->VertPot,(int) ((100L*pin->HorizPot)>>16),(int) ((100L*pin->VertPot)>>16));
   mprintf ("%d,%d\t/* Horizbody,VertBody */\n",pin->HorizBody,pin->VertBody);
   mprintf ("\t/* The rest are the variables that Intuition sets and maintains */\n };\n");
 }


long GadgFlagsFld []=
 { GADGHIGHBITS, GADGHIGHBITS, GADGHIGHBITS, GADGHIGHBITS, GADGIMAGE, GRELBOTTOM, GRELRIGHT, GRELWIDTH, GRELHEIGHT, SELECTED, GADGDISABLED, 0L };

long GadgFlags []=
 { GADGHCOMP, GADGHBOX, GADGHIMAGE, GADGHNONE, GADGIMAGE, GRELBOTTOM, GRELRIGHT, GRELWIDTH, GRELHEIGHT, SELECTED, GADGDISABLED };

char *GadgFlagsNms []=
 { "GADGHCOMP", "GADGHBOX", "GADGHIMAGE", "GADGHNONE", "GADGIMAGE", "GRELBOTTOM", "GRELRIGHT", "GRELWIDTH", "GRELHEIGHT", "SELECTED", "GADGDISABLED" };


long GadgActivationFld []=
 { RELVERIFY, GADGIMMEDIATE, ENDGADGET, FOLLOWMOUSE, RIGHTBORDER, LEFTBORDER, TOPBORDER, BOTTOMBORDER, TOGGLESELECT, STRINGCENTER, STRINGRIGHT, LONGINT, ALTKEYMAP, BOOLEXTEND, 0L };

#define GadgActivation GadgActivationFld

char *GadgActivationNms []=
 { "RELVERIFY", "GADGIMMEDIATE", "ENDGADGET", "FOLLOWMOUSE", "RIGHTBORDER", "LEFTBORDER", "TOPBORDER", "BOTTOMBORDER", "TOGGLESELECT", "STRINGCENTER", "STRINGRIGHT", "LONGINT", "ALTKEYMAP", "BOOLEXTEND" };


long GadgTypesFld []=
 { SYSGADGET, SCRGADGET, GZZGADGET, REQGADGET, 0x00f0, 0x00f0, 0x00f0, 0x00f0, 0x00f0, 0x00f0, 0x00f0, 0x00f0, 0x0007, 0x0007, 0x0007, 0x0007, 0L };

long GadgTypes []=
 { SYSGADGET, SCRGADGET, GZZGADGET, REQGADGET, SIZING, WDRAGGING, SDRAGGING, WUPFRONT, SUPFRONT, WDOWNBACK, SDOWNBACK, CLOSE, BOOLGADGET, GADGET0002, PROPGADGET, STRGADGET };

char *GadgTypesNms []=
 { "SYSGADGET", "SCRGADGET", "GZZGADGET", "REQGADGET", "SIZING", "WDRAGGING", "SDRAGGING", "WUPFRONT", "SUPFRONT", "WDOWNBACK", "SDOWNBACK", "CLOSE", "BOOLGADGET", "GADGET0002", "PROPGADGET", "STRGADGET" };


/***** Print a struct Gadget, where "list" is a boolean, telling if we should steal a whole list;
       A returned value of 0 indicates no Gadget has been printed at all: */

int PrintGadget (gad,list)
   struct Gadget *gad;
   int list;
 {
   int child,me,itx,gr,sr;

   child=0;	/* To cover the case of SYSTEM-gadgets only */

   if (gad->NextGadget && list)
      child=PrintGadget (gad->NextGadget,1);

   if (list && (gad->GadgetType & SYSGADGET))
      return child;		/* Do not print SystemGadgets in case of listing Gadgets */

   me=++ctr [GADGET];
   if (gad->GadgetRender)
      if ((gad->Flags & GADGIMAGE) || (gad->GadgetType & 0x0007)==PROPGADGET)
         if ((gad->GadgetType & 0x0007)==PROPGADGET && ((struct PropInfo *) gad->SpecialInfo)->Flags & AUTOKNOB)
	    mprintf ("\nSHORT %s%d [4];\n",StructNames [PROPBUF],me);
	 else
            gr=PrintImage ((struct Image *) gad->GadgetRender);
      else
         gr=PrintBorder ((struct Border *) gad->GadgetRender);
   if (gad->SelectRender && (gad->Flags & GADGHIGHBITS)==GADGHBOX)
      sr=PrintBorder ((struct Border *) gad->SelectRender);
   if (gad->SelectRender && (gad->Flags & GADGHIGHBITS)==GADGHIMAGE)
      sr=PrintImage ((struct Image *) gad->SelectRender);
   if (gad->GadgetText)
      itx=PrintIntuiText (gad->GadgetText);
   switch (gad->GadgetType & 0x0007)
    {
      case BOOLGADGET:
         if (gad->SpecialInfo)
	    PrintBoolInfo (gad->SpecialInfo,me,gad->Width,gad->Height);
	 break;
      case PROPGADGET:
         PrintPropInfo (gad->SpecialInfo,me);
	 break;
      case STRGADGET:
         PrintStringInfo (gad->SpecialInfo,me);
    }

   mprintf ("\nstruct Gadget %s%d=\n {\n   ",StructNames [GADGET],me);
   if (child)
      mprintf ("&%s%d,\t/* NextGadget */\n   ",StructNames [GADGET],child);
   else
      mprintf ("NULL,\t/* NextGadget */\n   ");
   mprintf ("%d,%d,\t/* LeftEdge,TopEdge */\n   ",gad->LeftEdge,gad->TopEdge);
   mprintf ("%d,%d,\t/* Width,Height */\n   ",gad->Width,gad->Height);
   PrintFlags ((long) gad->Flags,GadgFlagsFld,GadgFlags,GadgFlagsNms);
   mprintf (",\t/* Flags */\n   ");
   PrintFlags ((long) gad->Activation,GadgActivationFld,GadgActivation,GadgActivationNms);
   mprintf (",\t/* Activation */\n   ");
   PrintFlags ((long) gad->GadgetType,GadgTypesFld,GadgTypes,GadgTypesNms);
   mprintf (",\t/* GadgetType */\n   ");
   if (gad->GadgetRender)
      if ((gad->Flags & GADGIMAGE) || (gad->GadgetType & 0x0007)==PROPGADGET)
         if ((gad->GadgetType & 0x0007)==PROPGADGET && ((struct PropInfo *) gad->SpecialInfo)->Flags & AUTOKNOB)
	    mprintf ("(APTR) %s%d,\t/* GadgetRender (SHORT [4]) */\n   ",StructNames [PROPBUF],me);
	 else
            mprintf ("(APTR) &%s%d,\t/* GadgetRender (Image) */\n   ",StructNames [IMAGE],gr);
      else
         mprintf ("(APTR) &%s%d,\t/* GadgetRender (Border) */\n   ",StructNames [BORDER],gr);
   else
      mprintf ("NULL,\t/* GadgetRender */\n   ");
   if (gad->SelectRender && (gad->Flags & GADGHIGHBITS)==GADGHBOX && gad->GadgetType!=PROPGADGET)
      mprintf ("(APTR) &%s%d,\t/* SelectRender (Border) */\n   ",StructNames [BORDER],sr);
      else if (gad->SelectRender && (gad->Flags & GADGHIGHBITS)==GADGHIMAGE && gad->GadgetType!=PROPGADGET)
         mprintf ("(APTR) &%s%d,\t/* SelectRender (Image) */\n   ",StructNames [IMAGE],sr);
      else
         mprintf ("NULL,\t/* SelectRender */\n   ");
   if (gad->GadgetText)
      mprintf ("&%s%d,\t/* GadgetText */\n   ",StructNames [INTUITEXT],itx);
   else
      mprintf ("NULL,\t/* GadgetText */\n   ");
   mprintf ("0x%08lx,\t/* MutualExclude */\n   ",gad->MutualExclude);
   switch (gad->GadgetType & 0x0007)
    {
      case BOOLGADGET:
	 if (gad->SpecialInfo)
            mprintf ("(APTR) &%s%d,\t/* SpecialInfo (Boolinfo) */\n   ",StructNames [BOOLINFO],me);
	 else
	    mprintf ("NULL,\t/* SpecialInfo (BoolInfo) */\n   ");
         break;
      case PROPGADGET:
         mprintf ("(APTR) &%s%d,\t/* SpecialInfo (PropInfo) */\n   ",StructNames [PROPINFO],me);
         break;
      case STRGADGET:
         mprintf ("(APTR) &%s%d,\t/* SpecialInfo (StringInfo) */\n   ",StructNames [STRINGINFO],me);
         break;
      default:			/* GADGET0002 */
         mprintf ("NULL,\t/* SpecialInfo */\n   ");
    }
   mprintf ("%d,\t/* GadgetID */\n   ",gad->GadgetID);
   mprintf ("0x%08lx\t/* UserData */\n };\n",gad->UserData);

   return me;
 }


long WindowFlagsFld []=
 { WINDOWSIZING, WINDOWDRAG, WINDOWDEPTH, WINDOWCLOSE, SIZEBRIGHT, SIZEBBOTTOM, REFRESHBITS, REFRESHBITS, REFRESHBITS, REFRESHBITS, BACKDROP, REPORTMOUSE, GIMMEZEROZERO, BORDERLESS, ACTIVATE, WINDOWACTIVE,
   INREQUEST, MENUSTATE, RMBTRAP, NOCAREREFRESH, WINDOWREFRESH, WBENCHWINDOW, WINDOWTICKED, 0L };

long WindowFlags []=
 { WINDOWSIZING, WINDOWDRAG, WINDOWDEPTH, WINDOWCLOSE, SIZEBRIGHT, SIZEBBOTTOM, SMART_REFRESH, SIMPLE_REFRESH, SUPER_BITMAP, OTHER_REFRESH, BACKDROP, REPORTMOUSE, GIMMEZEROZERO, BORDERLESS, ACTIVATE,
   WINDOWACTIVE, INREQUEST, MENUSTATE, RMBTRAP, NOCAREREFRESH, WINDOWREFRESH, WBENCHWINDOW, WINDOWTICKED };

char *WindowFlagsNms []=
 { "WINDOWSIZING", "WINDOWDRAG", "WINDOWDEPTH", "WINDOWCLOSE", "SIZEBRIGHT", "SIZEBBOTTOM", "SMART_REFRESH", "SIMPLE_REFRESH", "SUPER_BITMAP", "OTHER_REFRESH", "BACKDROP", "REPORTMOUSE", "GIMMEZEROZERO",
   "BORDERLESS", "ACTIVATE", "WINDOWACTIVE", "INREQUEST", "MENUSTATE", "RMBTRAP", "NOCAREREFRESH", "WINDOWREFRESH", "WBENCHWINDOW", "WINDOWTICKED" };


long WindowIDCMPFld []=
 { SIZEVERIFY, NEWSIZE, REFRESHWINDOW, MOUSEBUTTONS, MOUSEMOVE, GADGETDOWN, GADGETUP, REQSET, MENUPICK, CLOSEWINDOW, RAWKEY, REQVERIFY, REQCLEAR, MENUVERIFY, NEWPREFS, DISKINSERTED, DISKREMOVED,
   WBENCHMESSAGE, ACTIVEWINDOW, INACTIVEWINDOW, DELTAMOVE, VANILLAKEY, INTUITICKS, LONELYMESSAGE, 0L };

#define WindowIDCMP WindowIDCMPFld

char *WindowIDCMPNms []=
 { "SIZEVERIFY", "NEWSIZE", "REFRESHWINDOW", "MOUSEBUTTONS", "MOUSEMOVE", "GADGETDOWN", "GADGETUP", "REQSET", "MENUPICK", "CLOSEWINDOW", "RAWKEY", "REQVERIFY", "REQCLEAR", "MENUVERIFY", "NEWPREFS",
   "DISKINSERTED", "DISKREMOVED", "WBENCHMESSAGE", "ACTIVEWINDOW", "INACTIVEWINDOW", "DELTAMOVE", "VANILLAKEY", "INTUITICKS", "LONELYMESSAGE" };


/***** Print a Window structure in a special way: Derive a struct NewWindow from it! */

int PrintWindow (win,list)
   struct Window *win;
   int list;
 {
   int child,me,gad,chk;

   if (win->NextWindow && list)
      child=PrintWindow (win->NextWindow,1);

   if (win->FirstGadget)
      gad=PrintGadget (win->FirstGadget,1);		/* Print all Gadgets used by the Window */
   else
      gad=0;						/* Indicating no gadgets were entered */

   if (win->CheckMark!=StdCheckMark)
      chk=PrintImage (win->CheckMark);

   mprintf ("\nstruct NewWindow %s%d=\n {\n   ",StructNames [WINDOW],me=++ctr [WINDOW]);
   mprintf ("%d,%d,\t/* LeftEdge,TopEdge */\n   ",win->LeftEdge,win->TopEdge);
   mprintf ("%d,%d,\t/* Width,Height */\n   ",win->Width,win->Height);
   PrintPen (win->DetailPen);
   mprintf (",");
   PrintPen (win->BlockPen);
   mprintf (",\t/* DetailPen,BlockPen */\n   ");

   PrintFlags (win->IDCMPFlags,WindowIDCMPFld,WindowIDCMP,WindowIDCMPNms);
   mprintf (",\t/* IDCMPFlags */\n   ");

   PrintFlags (win->Flags,WindowFlagsFld,WindowFlags,WindowFlagsNms);
   mprintf (",\t/* Flags */\n   ");

   if (gad)
      mprintf ("&%s%d,\t/* FirstGadget */\n   ",StructNames [GADGET],gad);
   else
      mprintf ("NULL,\t/* FirstGadget */\n   ");
   if (win->CheckMark!=StdCheckMark)
      mprintf ("&%s%d,\t/* CheckMark */\n   (UBYTE *) ",StructNames [IMAGE],chk);
   else
      mprintf ("NULL,\t/* CheckMark */\n   (UBYTE *) ");
   PrintStr (win->Title);
   mprintf (",\t/* Title */\n   ");
   mprintf ("NULL,\t/* Screen */\n   ");

   							/* BitMaps! ##### */
   mprintf ("NULL,\t/* BitMap */\n   ");

   mprintf ("%d,%d,\t/* MinWidth,MinHeight */\n   ",win->MinWidth,win->MinHeight);
   mprintf ("%d,%d,\t/* MaxWidth,MaxHeight */\n   ",win->MaxWidth,win->MaxHeight);

   mprintf ("WBENCHSCREEN\t/* Type */\n };\n");

   return me;
 }



long MenuItemFlagsFld []=
 { CHECKIT, ITEMTEXT, COMMSEQ, MENUTOGGLE, ITEMENABLED, HIGHFLAGS, HIGHFLAGS, HIGHFLAGS, HIGHFLAGS, CHECKED, ISDRAWN, HIGHITEM, MENUTOGGLED, 0L };

long MenuItemFlags []=
 { CHECKIT, ITEMTEXT, COMMSEQ, MENUTOGGLE, ITEMENABLED, HIGHIMAGE, HIGHCOMP, HIGHBOX, HIGHNONE, CHECKED, ISDRAWN, HIGHITEM, MENUTOGGLED };

char *MenuItemFlagsNms []=
 { "CHECKIT", "ITEMTEXT", "COMMSEQ", "MENUTOGGLE", "ITEMENABLED", "HIGHIMAGE", "HIGHCOMP", "HIGHBOX", "HIGHNONE", "CHECKED", "ISDRAWN", "HIGHITEM", "MENUTOGGLED" };


/***** Print a struct MenuItem: */

static int PrintMenuItem (mit)
   struct MenuItem *mit;
 {
   int child,sub,me,itf,sf;

   if (mit->NextItem)
      child=PrintMenuItem (mit->NextItem);
   if (mit->SubItem)
      sub=PrintMenuItem (mit->SubItem);

   if (mit->ItemFill)
      if (mit->Flags & ITEMTEXT)
         itf=PrintIntuiText ((struct IntuiText *) mit->ItemFill);
      else
         itf=PrintImage ((struct Image *) mit->ItemFill);

   if (mit->SelectFill && (mit->Flags & HIGHFLAGS)==HIGHIMAGE)
         sf=PrintImage ((struct Image *) mit->ItemFill);

   mprintf ("\nstruct MenuItem %s%d=\n {\n   ",StructNames [MENUITEM],me=++ctr [MENUITEM]);
   if (mit->NextItem)
      mprintf ("&%s%d,\t/* NextItem */\n   ",StructNames [MENUITEM],child);
   else
      mprintf ("NULL,\t/* NextItem */\n   ");
   mprintf ("%d,%d,\t/* LeftEdge,TopEdge */\n   ",mit->LeftEdge,mit->TopEdge);
   mprintf ("%d,%d,\t/* Width,Height */\n   ",mit->Width,mit->Height);

   PrintFlags ((long) mit->Flags,MenuItemFlagsFld,MenuItemFlags,MenuItemFlagsNms);
   mprintf (",\t/* Flags */\n   ");
   mprintf ("0x%08lx,\t/* MutualExclude */\n   ",mit->MutualExclude);

   if (mit->ItemFill)
      if (mit->Flags & ITEMTEXT)
         mprintf ("(APTR) &%s%d,\t/* MenuItem (IntuiText) */\n   ",StructNames [INTUITEXT],itf);
      else
         mprintf ("(APTR) &%s%d,\t/* MenuItem (Image) */\n   ",StructNames [IMAGE],itf);
   else
      mprintf ("NULL,\t/* ItemFill */\n   ");

   if (mit->SelectFill && (mit->Flags & HIGHFLAGS)==HIGHIMAGE)
      mprintf ("(APTR) &%s%d,\t/* SelectFill (Image) */\n   ");
   else
      mprintf ("NULL,\t/* SelectFill */\n   ");

   if (mit->Flags & COMMSEQ)
      if (mit->Command >= ' ' && mit->Command <= 0x7f)
         mprintf ("(BYTE) '%c',\t/* Command (In use) */\n   ",mit->Command);
      else
         mprintf ("0x%02x,\t/* Command (In use) */\n   ");
   else
      mprintf ("0,\t/* Command (Unused) */\n   ");

   if (mit->SubItem)
      mprintf ("&%s%d\t/* SubItem */\n   ",StructNames [MENUITEM],sub);
   else
      mprintf ("NULL\t/* SubItem */\n   ");

   mprintf ("\t/* NextSelect will be filled in by Intuition */\n };\n");

   return me;
 }


long MenuFlagsFld []=
 { MENUENABLED, MIDRAWN, 0L };

#define MenuFlags MenuFlagsFld

char *MenuFlagsNms []=
 { "MENUENABLED", "MIDRAWN" };


/***** Print a struct Menu: */

int PrintMenu (men)
   struct Menu *men;
 {
   int child,me,mit;

   if (men->NextMenu)
      child=PrintMenu (men->NextMenu);

   if (men->FirstItem)
      mit=PrintMenuItem (men->FirstItem);

   mprintf ("\nstruct Menu %s%d=\n {\n   ",StructNames [MENU],me=++ctr [MENU]);

   if (men->NextMenu)
      mprintf ("&%s%d,\t/* NextMenu */\n   ",StructNames [MENU],child);
   else
      mprintf ("NULL,\t/* NextMenu */\n   ");

   mprintf ("%d,%d,\t/* LeftEdge, TopEdge */\n   ",men->LeftEdge,men->TopEdge);
   mprintf ("%d,%d,\t/* Width,Height */\n   ",men->Width,men->Height);
   PrintFlags ((long) men->Flags,MenuFlagsFld,MenuFlags,MenuFlagsNms);
   mprintf (",\t/* Flags */\n   (BYTE *) ");
   PrintStr (men->MenuName);
   mprintf (",\t/* MenuName */\n   ");

   if (men->FirstItem)
      mprintf ("&%s%d\t/* FirstItem */\n",StructNames [MENUITEM],mit);
   else
      mprintf ("NULL\t/* FirstItem */\n");

   mprintf ("\t/* The other variables are for internal use only */\n };\n");

   return me;
 }



/***** Print the ColorMap that goes with each Screen: */

static void PrintColorMap (scr,id)
   struct Screen *scr;
   int id;
 {
   int i,cols;
   char *cont;
   UWORD *colmap;

   mprintf ("\nUWORD %s%d []=\t/* In the format xRGB (HEX) */\n    { ",StructNames [COLORMAP],id);

   colmap=(UWORD *) scr->ViewPort.ColorMap->ColorTable;
   cols=1 << scr->BitMap.Depth;
   cont="";
   for (i=0;i<cols;i++)
    {
      mprintf ("%s0x%04x",cont,*(colmap++));
      cont=", ";
    }
   mprintf (" };\n");
 }



/***** Print an array containing all struct Windows allocated in the Screen handed;
       This array contains some struct NewWindow *'s, terminated with a NULL: */

static void PrintWindowArray (scr,id)
   struct Screen *scr;
   int id;
 {
   int oldwin,newwin,winctr;

   oldwin=ctr [WINDOW]+1;

   if (scr->FirstWindow)
      newwin=PrintWindow (scr->FirstWindow,1);		/* Print a LIST of windows */
   else
      newwin=0;

   mprintf ("\nstruct NewWindow *%s%d []=\n { ",StructNames [WINDOWARRAY],id);
   for (winctr=newwin;winctr>=oldwin;winctr--)
      mprintf ("&%s%d, ",StructNames [WINDOW],winctr);
   mprintf ("NULL };\n");
 }



/***** Do exactly the same as in the last function, but now do not print NewWindow-pointers but
       mention their Menu-bases in exactly the same order; NULL now means an empty Menu too: */

static void PrintMenuArray (win,id)
   struct Window *win;
   int id;
 {
   			/* This function will call itself recursively.
			   when building up the calls, any Menu's are printed.
			   Then, the stop-condition is encountered, which means initialization
			   of the list to be printed. At last, the stack will be emptied, and
			   while this is done, the list is extended more and more. */
   if (win)
    {
      int men;

      if (win->MenuStrip)
         PrintMenu (win->MenuStrip);
      men=ctr [MENU];

      PrintMenuArray (win->NextWindow,-abs (id));		/* Call recursively */

      if (win->MenuStrip)
         mprintf ("&%s%d, ",StructNames [MENU],men);
      else
         mprintf ("NULL, ");
    }
   else						/* End-condition encountered! */
      mprintf ("\nstruct Menu *%s%d []=\n { ",StructNames [MENUARRAY],abs (id));
   if (id>=0)					/* Last return? */
      mprintf ("NULL };\n");
 }



long FlagsViewModesFld []=
 { HIRES, LACE, SPRITES, DUALPF, EXTRA_HALFBRITE, HAM, PFBA, GENLOCK_VIDEO, VP_HIDE, 0L };

#define FlagsViewModes FlagsViewModesFld

char *FlagsViewModesNms []=
 { "HIRES", "LACE", "SPRITES", "DUALPF", "EXTRA_HALFBRITE", "HAM", "PFBA", "GENLOCK_VIDEO", "VP_HIDE", 0L };


long FlagsScrTypesFld []=
 { SCREENTYPE, SCREENTYPE, CUSTOMBITMAP, SCREENBEHIND, SCREENQUIET, 0L };

long FlagsScrTypes []=
 { WBENCHSCREEN, CUSTOMSCREEN, CUSTOMBITMAP, SCREENBEHIND, SCREENQUIET };

char *FlagsScrTypesNms []=
 { "WBENCHSCREEN", "CUSTOMSCREEN", "CUSTOMBITMAP", "SCREENBEHIND", "SCREENQUIET" };



/***** Print a struct Screen by creating the corresponding struct NewScreen: */

int PrintScreen (scr)
   struct Screen *scr;
 {
   int child,me;

   PrintColorMap (scr,me=++ctr [NEWSCREEN]);
   PrintWindowArray (scr,me);
   PrintMenuArray (scr->FirstWindow,me);

   mprintf ("\nstruct NewScreen %s%d=\n {\n   ",StructNames [NEWSCREEN],me);
   mprintf ("%d,%d,\t/* LeftEdge,TopEdge */\n   ",scr->LeftEdge,scr->TopEdge);
   mprintf ("%d,%d,%d,\t/* Width,Height,Depth */\n   ",scr->Width,scr->Height,scr->BitMap.Depth);
   mprintf ("%d,%d,\t/* DetailPen,BlockPen */\n   ",scr->DetailPen,scr->BlockPen);
   PrintFlags ((long) scr->ViewPort.Modes,FlagsViewModesFld,FlagsViewModes,FlagsViewModesNms);
   mprintf (",\t/* ViewModes */\n   ");
   PrintFlags ((long) scr->Flags,FlagsScrTypesFld,FlagsScrTypes,FlagsScrTypesNms);
   mprintf (",\t/* Type */\n   ");
   mprintf ("NULL,\t/* Font */\n   ");
   mprintf ("(UBYTE *) ");
   PrintStr (scr->DefaultTitle);
   mprintf (",\t/* DefaultTitle */\n   ");
   mprintf ("NULL,\t/* Gadgets */\n   ");
   mprintf ("NULL\t/* CustomBitMap */\n };\n");

   return me;
 }
