/*-------------------------------------------------------
*
*     c_source.c
*
*     Prints c source from DisplayMenu
*
*     For Lattice/SAS Version 5.10a:
*     Compile: 
*        lc -cfist -v -y -b1 c_source.c
*     Link:
*        Blink FROM
*              c.o
*              main.o
*              a_source.o
*              b_source.o
*              c_source.o
*              TO ms
*              LIB lc.lib
*
*  MenuScript c_source.c
*  Copyright (c) 1991 David T. Ossorio
*  All Rights Reserved.
*
*
*
*--------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <exec/types.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>

#ifdef LATTICE
#include <proto/all.h>
#endif

extern VOID pcl(char type);
extern VOID print_header(char type);
extern BOOL own_font;
extern UBYTE *mname;
extern struct TextAttr *textAttr;
extern struct Image *CheckMarkImage;
extern VOID CleanExit(LONG Error_Number,
                      BOOL Display_Line,ULONG ReturnValue);


#define STACKSIZE 64 
#define ITEXT struct IntuiText *

#define ER_STACK_OVERFLOW 21     /* From main.c */

/*-------------------------------------------------------
*  functions
*--------------------------------------------------------*/

VOID print_c_source(struct Menu *fm);
VOID MenuPush(struct Menu *menu);
struct Menu *MenuPop(VOID);
VOID SetItemflags(struct MenuItem *item);
VOID SetMenuflags(struct Menu *menu);
VOID SetModeString(struct IntuiText *itext);
VOID PrintTextBlock(UBYTE *comment,UBYTE *str,ULONG id,
                    struct MenuItem *fi,UBYTE *header);
VOID PrintItemBlock(UBYTE *comment,UBYTE *str,ULONG id,
                    struct MenuItem *fi,UBYTE *header);
VOID WriteTx(struct IntuiText *itext);

/*----------------------------------------------------------*/


/*--------------------------------------------------------
*     We use a stack so we can start from the last menu and
*     work backwards
*     Since the stack allows 64 menus,
*     it should NEVER overflow.
*---------------------------------------------------------*/

static struct Menu *MenuStack[STACKSIZE];
static UBYTE menuflags[32];
static UBYTE itemflags[128];
static UBYTE *fontstring;
static UBYTE *modestring;

ULONG MenuPtr;

static UBYTE *FontString[] = {
   "&MenuAttr",
   "NULL"
};

static UBYTE *ModeString[] = {
   "JAM1",
   "JAM2",
   "COMPLEMENT",
   "JAM1|INVERSVID",
   "JAM2|INVERSVID",
   "COMPLEMENT|INVERSVID"
};

/*-----------------------------------------------------------------*/

VOID MenuPush(struct Menu *menu)
{
   /* push Menu * onto MenuStack */
   
   if (MenuPtr == 0) CleanExit(ER_STACK_OVERFLOW,FALSE,RETURN_WARN);
   
   MenuStack[--MenuPtr] = menu;
   return;
}
struct Menu *MenuPop(VOID)
{
   if (MenuPtr == STACKSIZE) return NULL;
   return (MenuStack[MenuPtr++]);
}

/*----------------------------------------------------------------
*  WriteTx()
*-----------------------------------------------------------------*/
VOID WriteTx(struct IntuiText *itext)
{
   
   SetModeString(itext);
   printf("\n\t\t{%d,%d,%s,%d,%d,%s, \"%s\" , NULL}",
      itext->FrontPen,itext->BackPen,modestring,itext->LeftEdge,
      itext->TopEdge,fontstring,itext->IText);
   return;
}


/*------------------------------------------------------------------
*  PrintTextBlock()
*-------------------------------------------------------------------*/
VOID PrintTextBlock(comment,str,id,fi,header)
UBYTE *comment;
UBYTE *str;
ULONG id;
struct MenuItem *fi;
UBYTE *header;
{
   REGISTER struct MenuItem *item = fi;
   
   printf(comment,str);
   printf("struct IntuiText %s%x[]\t=\n\t{",header,id);
   
   while (item) {
      WriteTx((ITEXT)item->ItemFill);
      item = item->NextItem;
      if(item) printf(",");
      else printf("\n\t};\n\n");
   }
  
   item = fi;
   while (item) {
      if(item->SelectFill) {
         printf("struct IntuiText Select_%s%x\t=",header,item);
         WriteTx((ITEXT)item->SelectFill);
         printf(";\n\n");
      }
      item = item->NextItem;
   }
   
   return;
}       
/*--------------------------------------------------------
*  PrintItemBlock()
*---------------------------------------------------------*/      
VOID PrintItemBlock(comment,str,id,fi,header)
UBYTE *comment;
UBYTE *str;
ULONG id;
struct MenuItem *fi;
UBYTE *header;
{
   REGISTER struct MenuItem *item = fi;
   REGISTER ULONG ItemNum = 0;
   REGISTER ULONG TextNum = 0;
   
   if(!item) return;
   
   printf(comment,str);
   printf("struct MenuItem %s%x[]\t=\n\t{",header,id);
   
   while (item) {
      SetItemflags(item);
      printf("\n\t\t/*\t\"%s\"\t*/\n",((ITEXT)item->ItemFill)->IText);
      if(item->NextItem)
         printf("\t\t{&%s%x[%d],",header,id,++ItemNum);
      else printf("\t\t{ NULL,");
         
      printf("%4d,%4d,%4d,%4d,\n",
         item->LeftEdge,item->TopEdge,item->Width,item->Height);
      
      printf("\t\t%s,%4d,\n",itemflags,item->MutualExclude);
      printf("\t\t(APTR)&IntuiText_%x[%d],",id,TextNum++);
      if(item->SelectFill) printf("(APTR)&Select_IntuiText_%x,",item);
      else printf("NULL,");
      if(item->Command) printf("'%c',",item->Command);
      else printf("NULL,");
      if(item->SubItem) printf("&Subi_%x[0],",item);
      else printf("NULL,");
      
      printf("MENUNULL\n\t\t}");
      item = item->NextItem;
      if(item) printf(",");
      else printf("\n\t};\n\n");
   }               

   
   return;
}      



/*-------------------------------------------------------------------------
*  SetModeString()
*-----------------------------------------------------------------------*/
VOID SetModeString(struct IntuiText *itext)
{

   /* Boolean AND (&) dosen't seem to work here; since
      there aren't too many permutations, we calcualte the
      string representing the DrawMode with a table */  
  
   switch(itext->DrawMode) {
      case JAM1: modestring = ModeString[0];
      break;
      case JAM2: modestring = ModeString[1];
      break;
      case COMPLEMENT: modestring = ModeString[2];
      break;
      case JAM1+INVERSVID: modestring = ModeString[3];
      break;
      case JAM2+INVERSVID: modestring = ModeString[4];
      break;
      case COMPLEMENT+INVERSVID: modestring = ModeString[5];
      break;
   }
   
   
      
   /* set the font, if needed */
   
   if(own_font) fontstring = FontString[0];
   else fontstring = FontString[1];
   
   return;
}
   
/*----------------------------------------------------------------------*
*  SetMenuflags()
*-----------------------------------------------------------------------*/
VOID SetMenuflags(struct Menu *menu)
{
   strcpy(menuflags,"NULL");
   if((menu->Flags & MENUENABLED) == MENUENABLED)
      strcat(menuflags,"|MENUENABLED");
   return;
}
/*--------------------------------------------------------------------
*  SetItemflags()
*---------------------------------------------------------------------*/
VOID SetItemflags(struct MenuItem *item)
{
   REGISTER USHORT flags = item->Flags;
   
   strcpy(itemflags,"NULL");
   
   if((flags & CHECKIT)==CHECKIT) strcat(itemflags,"|CHECKIT");
   if((flags & CHECKED)==CHECKED) strcat(itemflags,"|CHECKED");
   if((flags & ITEMTEXT)==ITEMTEXT) strcat(itemflags,"|ITEMTEXT");
   if((flags & COMMSEQ)==COMMSEQ) strcat(itemflags,"|COMMSEQ");
   if((flags & MENUTOGGLE)==MENUTOGGLE) strcat(itemflags,"|MENUTOGGLE");
   if((flags & ITEMENABLED)==ITEMENABLED) strcat(itemflags,"|ITEMENABLED");
   
   if((flags & HIGHNONE)==HIGHNONE) strcat(itemflags,"|HIGHNONE");
   else if((flags & HIGHCOMP)==HIGHCOMP) strcat(itemflags,"|HIGHCOMP");
   else if((flags & HIGHBOX)==HIGHBOX) strcat(itemflags,"|HIGHBOX");
   else strcat(itemflags,"|HIGHIMAGE");

   return;
}
/*-------------------------------------------------------------
* print_c_source()
*--------------------------------------------------------------*/

   

VOID print_c_source(struct Menu *fm)
{
   
   REGISTER struct Menu *menu = fm;
   REGISTER struct MenuItem *item;
   ULONG MenuNum = 0;
            
   fprintf(stderr,"\nWriting C Source Code...\n");

 
   print_header('c');
   printf("\n\n#include <exec/types.h>\n#include <intuition/intuition.h>\n\n");
   
   if (CheckMarkImage) {
      
      ULONG i;    /* for our loop */
      pcl('c');
      printf("/* Your Image structure for your custom checkmark is here,\n"
             "* but you must be sure that the data is in CHIP ram\n"
             "* youself!!! (for Lattice, the keyword 'chip' should\n"
             "* do, so if you're using Lattice Version 5.10a or higher,\n"
             "* you don't have to worry about this). */\n");
             
      pcl('c');
    
      printf("\nUSHORT\tchip\tCheckImageData[]\t=\n\t{\n\t");
      for(i=0;i < CheckMarkImage->Width/16 * CheckMarkImage->Height;i++)
         printf("0x%x,\n\t",CheckMarkImage->ImageData[i]);
      printf("};\n\n");   
      
      printf("struct Image CheckMImage =\n");
      printf("\t{%3d,%3d,%3d,%3d,%3d,&CheckImageData[0],%3d,%3d,NULL};\n\n",
         CheckMarkImage->LeftEdge,CheckMarkImage->TopEdge,
         CheckMarkImage->Width,CheckMarkImage->Height,
         CheckMarkImage->Depth,CheckMarkImage->PlanePick,
         CheckMarkImage->PlaneOnOff);
   
   }     /* end if */      
                 
   if (own_font) {
      pcl('c');
      printf("/* Your font is here, but if it is disk-based, you\n"
             "* still must open it yourself.\n"
             "* [ use OpenFont(MAttr) to make this painless... ] */\n\n");
             
      pcl('c');
      printf("struct TextAttr MenuAttr\t=\n",mname);
      printf("\t{ (STRPTR)\"%s\",%d,%d,%d };\n\n",
         textAttr->ta_Name,textAttr->ta_YSize,textAttr->ta_Style,
         textAttr->ta_Flags);
            
   }
   
    
  
   MenuPtr = STACKSIZE; /* initialize stack */
   
   /* push all the menus   */
   
   while(menu) {
      MenuPush(menu);
      menu = menu->NextMenu;
   }
   
   /*    walk backwards through the menus    */
   
   while (menu = MenuPop()) {
      item = menu->FirstItem;
      while (item) {
         if(item->SubItem) {
         
            PrintTextBlock("/* IntuiText for \"%s\" SubItems */\n",
                           ((ITEXT)item->ItemFill)->IText,
                           (ULONG)item,item->SubItem,"IntuiText_");
            
            PrintItemBlock("/* MenuItem structures for \"%s\" SubItems */\n",
                           ((ITEXT)item->ItemFill)->IText,
                           (ULONG)item,item->SubItem,"Subi_");
         }

         item = item->NextItem;
      
      }  /* next item */
      
      item = menu->FirstItem;
         
      PrintTextBlock("/* IntuiText for \"%s\" items */\n",
           menu->MenuName,(ULONG)menu,item,"IntuiText_");
      PrintItemBlock("/* MenuItem structures for \"%s\" items */\n",
            menu->MenuName,(ULONG)menu,item,"Item_");
         
   }      /* next menu */          
         
   menu = fm;
   printf("\n\n/*\tMenu Titles\t*/\nstruct Menu Menus[]\t=\n\t{");
   
   while (menu) {
      
      SetMenuflags(menu);
      if(menu->NextMenu)
         printf("\n\t\t{&Menus[%d],",++MenuNum);
      else 
         printf("\n\t\t{NULL ,");
         
      printf("%4d,%4d,%4d,%4d, %s, \"%s\",\t&Item_%x[0]}",
      menu->LeftEdge,menu->TopEdge,menu->Width,menu->Height,menuflags,
      menu->MenuName,menu);
      
      menu = menu->NextMenu;
      if(menu) printf(",");                  
      else printf("\n\t};\n\n");
   }
   
   if(CheckMarkImage) 
   printf("/* A pointer to the checkmark image structure for easy reference */\n"
          "struct Image *CheckMarkImage = &CheckMImage;\n\n");
   
   printf("/* A pointer to the first menu for easy reference */\n"
          "struct Menu *%s\t=\t&Menus[0];\n\n",mname);
   
   if(own_font)
      printf("/* A pointer to the menu font TextAttr for easy reference */\n"
         "struct TextAttr *MAttr\t=\t&MenuAttr;\n\n");
         
  
   printf("/*\tEnd of File\t*/\n\n");       
  
     
}  /* end */

