/*  Icon2C.c  --- Write out an Icon as C data structures
 *  Link with AStartup.obj ... LIBRARY Amiga.lib
 */

#include <exec/types.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>


/* For stdio under WB */
extern LONG stdin, stdout, stderr;  /* in Astartup.obj */
#define INBUFSZ 40
#define SBUFSZ  80
char sbuf[SBUFSZ];
char iname[INBUFSZ];
char fname[INBUFSZ];
char conSpec[] = "CON:0/40/640/140/ Icon2C ";
BOOL fromWB, newStdio;

/* Other stuff */
struct DiskObject *diskobj = NULL;
LONG   IconBase = NULL;
LONG   fh = NULL;
int    wLen; 

char   line1[] =
          "\nIcon2C - Writes Icon to file as C source structures\n\n";
char   line2[] =
          "   Notes: User should convert flag values to OR'd labels\n";
char   line3[] =
          "          Fields commented in [brackets] are not traced\n";
char   line4[] =
          "          User must supply these if value is non-zero\n\n";


main(argc,argv)
int  argc;
char **argv;
   {

   fromWB = (argc==0) ? TRUE : FALSE;
   newStdio = FALSE;
   if((fromWB) && (!(newStdio = openStdio(&conSpec[0]))))
      {
      return(0);
      }

   if((IconBase = OpenLibrary("icon.library",0))==NULL)
      {
      cleanexit("Can't open icon.library\n");
      }

   printf(line1);
   printf(line2);
   printf(line3);
   printf(line4);
   printf("Enter icon name without \".info\": ");
   if(!(gets(&iname[0])))
      cleanexit("\nNo icon name given, data not saved\n");

   if((diskobj = (struct DiskObject *)GetDiskObject(iname))==NULL)
      {
      cleanexit("\nCan't get icon - check path and spelling\n");
      }

   printf("Enter filename for output: ");
   if(!(gets(&fname[0])))
      cleanexit("\nNo file name given, data not saved\n");


   if(!(fh = Open(&fname[0],MODE_NEWFILE)))
      cleanexit("\nCan't open output file\n");

   wLen = 1;   /* Init to non-error value */
   writeData(fh,diskobj);
   Close(fh);
   cleanexit("\nDone\n");
   }


writeData(fh,obj)
LONG fh;
struct DiskObject *obj;
   {
   struct Image *img;
   struct IntuiText *itext;

   if (img=(struct Image *)(obj->do_Gadget.GadgetRender))
      {
      writeImageData(fh,img,1);
      writeImage(fh,img,1);
      }
   if (img=(struct Image *)(obj->do_Gadget.SelectRender))
      {
      writeImageData(fh,img,2);
      writeImage(fh,img,2);
      }
   if (itext = (struct IntuiText *)(obj->do_Gadget.GadgetText))
      {
      writeItext(fh,itext);
      }
   writeDiskObj(fh,obj);
   }


writeImage(fh,img,n)
LONG fh;
struct Image *img;
int n;
   {
   sprintf(&sbuf[0],"USHORT  image%ld[] = {\n",n);
   myWrite(fh,&sbuf[0]);

   myDVarWrite(fh,(LONG)img->LeftEdge,"LeftEdge");
   myDVarWrite(fh,(LONG)img->TopEdge,"TopEdge");
   myDVarWrite(fh,(LONG)img->Width,"Width");
   myDVarWrite(fh,(LONG)img->Height,"Height");
   myDVarWrite(fh,(LONG)img->Depth,"Depth");
   sprintf(&sbuf[0],
              " (USHORT *)&imageData%ld,  /* ImageData */\n",n);
   myWrite(fh,&sbuf[0]);
   myXVarWrite(fh,(LONG)img->PlanePick,"PlanePick");
   myXVarWrite(fh,(LONG)img->PlaneOnOff,"PlaneOnOff");
   myDVarWrite(fh,(LONG)img->NextImage,"[NextImage]");
   myWrite(fh," };\n\n");
   }


writeImageData(fh,img,n)
LONG fh;
struct Image *img;
int n;
   {
   int w, h, d, wi, hi, di, sPerLine, k;
   USHORT *data;

   w = (int)img->Width;
   h = (int)img->Height;
   d = (int)img->Depth;
   data = (USHORT *)img->ImageData;

   /* Write out Image data array */
   sprintf(&sbuf[0],"USHORT  imageData%ld[] = {\n",n);
   myWrite(fh,&sbuf[0]);

   sPerLine = ((w - 1) >> 4) + 1;
   for (di = 0; (di < d)&&(wLen>0); di++)
      {
      for (hi = 0; (hi < h)&&(wLen>0); hi ++)
         {
         for (wi = 0; (wi < sPerLine)&&(wLen>0); wi++, data++)
            {
            sprintf(&sbuf[0]," 0x%4lx,",(USHORT)(*data));
            for (k=3; k<7; k++)
               {
               if (sbuf[k] == ' ')  sbuf[k] = '0';
               }
            myWrite(fh,&sbuf[0]);
            }
         myWrite(fh,"\n");
         }
      myWrite(fh,"/**/\n");
      }
   myWrite(fh," };\n\n");
   }


writeItext(fh,it)
LONG fh;
struct IntuiText *it;
   {
   /* Write out IntuiText structure */
   myDVarWrite(fh,(LONG)it->FrontPen,"FrontPen");
   myDVarWrite(fh,(LONG)it->BackPen,"BackPen");
   myXVarWrite(fh,(LONG)it->DrawMode,"DrawMode");
   myDVarWrite(fh,(LONG)it->LeftEdge,"LeftEdge");
   myDVarWrite(fh,(LONG)it->TopEdge,"TopEdge");

   myXVarWrite(fh,(LONG)it->ITextFont,"[ITextFont]");
   if(it->IText)
      {
      sprintf(&sbuf[0]," \"%s\",  /* IText */\n",it->IText);
      myWrite(fh,&sbuf[0]);
      }
   else
      {
      myWrite(fh," NULL,  /*IText */\n");
      }
   myXVarWrite(fh,(LONG)it->NextText,"[NextText]");
   }


writeDiskObj(fh,obj)
LONG fh;
struct DiskObject *obj;
   {
   /* Write out DiskObject/Gadget structure */
   myWrite(fh,"struct DiskObject diskObject = {\n");
   myWrite(fh," WB_DISKMAGIC,   /* do_Magic */\n");
   myWrite(fh," WB_DISKVERSION, /* do_Version */\n\n");
   myWrite(fh,"/* Embedded Gadget Structure */\n");
   myDVarWrite(fh,(LONG)obj->do_Gadget.NextGadget,"[NextGadget]");
   myDVarWrite(fh,(LONG)obj->do_Gadget.LeftEdge,"LeftEdge");
   myDVarWrite(fh,(LONG)obj->do_Gadget.TopEdge,"TopEdge");
   myDVarWrite(fh,(LONG)obj->do_Gadget.Width,"Width");
   myDVarWrite(fh,(LONG)obj->do_Gadget.Height,"Height");
   myXVarWrite(fh,(LONG)obj->do_Gadget.Flags,"Flags");
   myXVarWrite(fh,(LONG)obj->do_Gadget.Activation,"Activation");
   myXVarWrite(fh,(LONG)obj->do_Gadget.GadgetType,"GadgetType");

   if(obj->do_Gadget.GadgetRender)
      myWrite(fh," (APTR)&image1, /* GadgetRender */\n");
   else
      myWrite(fh," NULL,     /* GadgetRender */\n");

   if(obj->do_Gadget.SelectRender)
      myWrite(fh," (APTR)&image2, /* SelectRender */\n");
   else
      myWrite(fh," NULL,     /* SelectRender */\n");

   if(obj->do_Gadget.GadgetText)
      myWrite(fh," &gadgetText, /* GadgetText */\n");
   else
      myWrite(fh," NULL,     /* GadgetText */\n");

   myXVarWrite(fh,(LONG)obj->do_Gadget.MutualExclude,"MutualExclude");
   myXVarWrite(fh,(LONG)obj->do_Gadget.SpecialInfo,"[SpecialInfo]");
   myDVarWrite(fh,(LONG)obj->do_Gadget.GadgetID,"GadgetID");
   myXVarWrite(fh,(LONG)obj->do_Gadget.UserData,"[UserData]");

   myWrite(fh,"\n/* Rest of DiskObject structure */\n");
   myXVarWrite(fh,(LONG)obj->do_Type,"do_Type");
   if(obj->do_DefaultTool)
      {
      sprintf(&sbuf[0]," \"%s\",   /* do_Default Tool */\n",
                 obj->do_DefaultTool);
      myWrite(fh,&sbuf[0]);
      }
   else
      {
      myWrite(fh," NULL,   /* do_DefaultTool */\n");
      }
   myXVarWrite(fh,(LONG)obj->do_ToolTypes,"[do_ToolTypes]");
   myXVarWrite(fh,(LONG)obj->do_CurrentX,"do_CurrentX");
   myXVarWrite(fh,(LONG)obj->do_CurrentY,"do_CurrentY");
   myXVarWrite(fh,(LONG)obj->do_DrawerData,"[do_DrawerData]");
   myXVarWrite(fh,(LONG)obj->do_ToolWindow,"[do_ToolWindow]");
   myXVarWrite(fh,(LONG)obj->do_StackSize,"do_StackSize");
   myWrite(fh," };\n\n");
   }


myDVarWrite(f,var,s)
LONG f,var;
char *s;
   {
   sprintf(&sbuf[0]," %ld,  /* %s */\n",var,s);
   myWrite(f,&sbuf[0]);
   }

myXVarWrite(f,var,s)
LONG f,var;
char *s;
   {
   sprintf(&sbuf[0]," 0x%lx,  /* %s */\n",var,s);
   myWrite(f,&sbuf[0]);
   }


myWrite(f,s)
LONG f;
char *s;
   {
   if (wLen > 0)
      {
      wLen = Write(f,s,strlen(s));
      return(wLen);
      }
   else cleanexit("\nError writing output file\n");
   }


cleanexit(s)
char *s;
   {
   if (diskobj)  FreeDiskObject(diskobj);
   if (IconBase) CloseLibrary(IconBase);

   if (*s) printf(s);
   if ((*s)&&(fromWB))
      {
      printf("\nPRESS RETURN TO EXIT\n");
      while(getchar() != '\n');
      }

   if (newStdio) closeStdio();
   exit(0);
   }



openStdio(conspec)
char *conspec;
   {
   LONG wfile;
   struct Process *proc;
   struct FileHandle *handle;

   if (!(wfile = Open(conspec,MODE_NEWFILE)))  return(0);
   stdin  = wfile;
   stdout = wfile;
   stderr = wfile;
   handle = (struct FileHandle *)(wfile << 2);
   proc = (struct Process *)FindTask(NULL);
   proc->pr_ConsoleTask = (APTR)(handle->fh_Type);
   proc->pr_CIS = (BPTR)stdin;
   proc->pr_COS = (BPTR)stdout;
   return(1);
   }

closeStdio()
   {
   struct Process *proc;
   struct FileHandle *handle;

   if (stdin > 0)  Close(stdin);
   stdin  = -1;
   stdout = -1;
   stderr = -1;
   handle = (struct FileHandle *)(stdin << 2);
   proc = (struct Process *)FindTask(NULL);
   proc->pr_ConsoleTask = NULL;
   proc->pr_CIS = NULL;
   proc->pr_COS = NULL;
   }


gets(s)
char *s;
   {
   int l = 0, max = INBUFSZ - 1;

   while (((*s = getchar()) !='\n' )&&(l < max)) s++, l++;
   *s = NULL;
   return(l);
   }




/* String Functions */

strlen(s)
char *s;
   {
   int i = 0;
   while(*s++) i++;
   return(i);
   }

strcpy(to,from)
char *to, *from;
   {
   do
      {
      *to++ = *from;
      }
   while(*from++);
   }

strcat(to,from)
char *to, *from;
   {
   while(*to) to++;
   strcpy(to,from);
   }
