/* ICON v1.0 by AMIGA Plus
   © 1989 Aki Rimpilainen & Arnie Cachelin
   Works with Lattice using Aztec include files!
   Use option -Z5000 (to increase string space) with Aztec. */


#include <exec/exec.h>                   /* include files */
#include <intuition/intuition.h>
#include <workbench/workbench.h>
#include <libraries/dos.h>
#include <functions.h>
#include <stdio.h>

struct  IntuitionBase *IntuitionBase;     /* global structures... */
struct  IconBase      *IconBase;
struct  DiskObject    *dob;
struct  Gadget        gdg;
struct  Image         *image,*image2;

UWORD   arno;                             /* ...and vars */
char    *ttypes[255];
UWORD   *data,*data2;


main(argc,argv)                          /* and now the program */
 int argc;
 char *argv[];
{
  char     name[40],opt[10];   /* local vars */
  short    i,j;


  puts("\n[33mICON v1.0 - © 1989 AMIGA [3mPlus[0m");
  if (argc<2) Usage();                /* Check for arguments,  */
                                      /* if none, display help */
  strcpy(name,argv[1]);  /* get icon filename */

/* Open Some libraries...    */
  IntuitionBase = (struct IntuitionBase *)
    OpenLibrary("intuition.library",LIBRARY_VERSION);
  if (IntuitionBase==0) { Closing("Can't open intuition."); exit(0L); }

  IconBase=(struct IconBase *)
    OpenLibrary("icon.library",LIBRARY_VERSION);
  if (IconBase==0) { Closing("Can't open icon.library."); exit(0L); }

/* get the requested DiskObject... */
  dob=GetDiskObject(name);
  if (dob==0) { printf("Can't find file %s.info\n",name);
                Closing("Can't open file!"); exit(0L); }
/* initialize some general structures/variables for future */
  gdg=dob->do_Gadget;
  image =(struct Image *)dob->do_Gadget.GadgetRender;
  image2=(struct Image *)dob->do_Gadget.SelectRender;
  data =(UWORD *)image->ImageData;
  data2=(UWORD *)image2->ImageData;    /* note how we also get a pointer */
                                       /* to a possible alternate image! */
  j=(gdg.Width+15)/16;
  j=j*gdg.Height*2;    /* calculating the length of the data section */

  if (argc==2) InfoScreen(name);   /* two arguments gives information */
/*  else if (argc==3) Usage();        three args does nothing, exit   */
  else
   {
    arno=3;                     /* this is our argument 'bookmark', which */
    do {                        /* points to the user arg being processed */
      strcpy(opt,argv[arno-1]);      /* get the option  */
      if ((strlen(opt))>1)           /* if opt longer than byte, exit */
       {
        strcpy(name,"Unknown option : ");
        strcat(name,opt);            /* display what went wrong */
        Closing(name);
        exit(0L);
       }
      if      ((*opt=='c') || (*opt=='C')) CDump(argv[arno]);
                                  /* Then we're saving a C statement...*/
      else if ((*opt=='d') || (*opt=='D')) NewDefTool(argv[arno]);
                                  /* changing DefaultTool...*/
      else if ((*opt=='s') || (*opt=='S')) NewStack(argv[arno]);
                                  /* changing stack size */
      else if ((*opt=='t') || (*opt=='T')) NewType(argv[arno]);
                                  /* changing type */
      else if ((*opt=='r') || (*opt=='R'))
       {                          /* redefining tool types */
        i=0;
        while ((strcmp("end",argv[arno])!=0) && (strcmp("END",argv[arno])!=0))
         {
          if (strlen(argv[arno])>127) /* bail out if string too long */
           {
            Closing("ToolType string too long (or missing END)!");
            exit(0L);
           }
          ttypes[i++]=argv[arno];
          printf("  New ToolType    : %s\n",argv[arno++]);
         }
        arno+=2;
        dob->do_ToolTypes=ttypes;
       }
      else if ((*opt=='a') || (*opt=='A'))
       {                            /* adding tool types */
        for (i=0;(ttypes[i]=dob->do_ToolTypes[i])!=0;i++);
                                    /* find the last tooltype entry */
        while ((strcmp("end",argv[arno])!=0) && (strcmp("END",argv[arno])!=0))
         {
          if (strlen(argv[arno])>127) /* bail out if string too long */
           {
            Closing("ToolType string too long (or missing END)!");
            exit(0L);
           }
          ttypes[i++]=argv[arno];
          printf("  Added ToolType  : %s\n",argv[arno++]);
         }
        arno+=2;
        dob->do_ToolTypes=ttypes;
       }
      else                           /* unknown option, exit */
       {
        strcpy(name,"Unknown option : ");
        strcat(name,opt);            /* display what went wrong */
        Closing(name);
        exit(0L);
       }
    } while (arno<(argc+1));   /* repeat the loop while args remain */
   }

  PutDiskObject(name,dob); /* save modified diskobject */
  Closing(NULL);
  exit(0L);
}


NewType(arg)       /* change tooltype */
char *arg;
{
  char bailout[50];

  if      ((strcmp("PROJECT",arg)==0) || (strcmp("project",arg)==0))
    dob->do_Type=WBPROJECT;
  else if ((strcmp("TOOL",arg)==0) || (strcmp("tool",arg)==0))
    dob->do_Type=WBTOOL;
  else
   {
    strcpy(bailout,"Tool Type not supported : ");
    strcat(bailout,arg);
    Closing(bailout);
    exit(0);
   }
  printf("  New ToolType    : %s\n",arg);
  arno+=2;
  return(0);
}


NewStack(arg)      /* change stack size */
char *arg;
{
  dob->do_StackSize=atol(arg);
  printf("  New StackSize   : %ld\n",dob->do_StackSize);
  arno+=2;
  return(0);
}


NewDefTool(arg)    /* change default tool */
char *arg;
{
  strcpy(dob->do_DefaultTool,arg);     /* second filename */
  printf("  New DefaultTool : %s\n",dob->do_DefaultTool);
  arno+=2;
  return(0);
}


InfoScreen(arg)              /* give info about an icon... */
char *arg;
{
  short i;

  puts("");
  printf("  [33mObject name  :[31m %s.info\n",arg);
  printf("  [33mObject type  :[31m ");
  switch (dob->do_Type) {                  /* icon type */
    case WBDISK    :
      puts("WBDISK");
      break;
    case WBDRAWER  :
      puts("WBDRAWER");
      break;
    case WBTOOL    :
      puts("WBTOOL");
      break;
    case WBPROJECT :
      puts("WBPROJECT");
      break;
    case WBGARBAGE :
      puts("WBGARBAGE");
      break;
    case WBDEVICE  :
      puts("WBDEVICE");
      break;
    case WBKICK    :
      puts("WBKICK");
      break;
    default        :
      puts("UNKNOWN");
      break;
  }
  printf("  [33mDefault Tool :[31m ");   /* default tool */
  if (strlen(dob->do_DefaultTool)!=0)
    printf("%s\n",dob->do_DefaultTool);
  else puts("No tool specified");

  printf("  [33mToolTypes    :[31m ");
  if (strlen(dob->do_ToolTypes[0])!=0)   /* tooltypes array */
   {
    for (i=0; strlen(dob->do_ToolTypes[i])!=0; i++)
     {
      if (i!=0) printf("                 ");
      printf("%s\n",dob->do_ToolTypes[i]);
     }
   } else puts("No tooltypes specified");

  printf("  [33mImage Mode   :[31m ");  /* image highlighting */
  switch (gdg.Flags) {
    case GADGIMAGE | GADGHCOMP  :
      puts("COMPLEMENT");
      break;
    case GADGIMAGE | GADGHBOX   :
      puts("BOX");
      break;
    case GADGIMAGE | GADGHIMAGE :
      puts("IMAGE");
      break;
    default :
      puts("UNKNOWN");
      break;
   }                                     /* and other useful data */
  printf("  [33mX-position   :[31m ");
  if (dob->do_CurrentX==NO_ICON_POSITION) puts("NO_ICON_POSITION");
  else printf("%ld\n",dob->do_CurrentX);
  printf("  [33mY-position   :[31m ");
  if (dob->do_CurrentY==NO_ICON_POSITION) puts("NO_ICON_POSITION");
  else printf("%ld\n",dob->do_CurrentY);
  printf("  [33mStack size   :[31m %ld\n",dob->do_StackSize);
  return(0);
}


CDump(arg)        /* save C-language DiskObject-related structures */
char *arg;
{
  FILE  *fp;
  short i=0,j=0;

  arno+=2;
  if ( (dob->do_Type!=WBPROJECT) && (dob->do_Type!=WBTOOL) ) {
    Closing("Sorry, your tool type is not supported with this option.");
    exit(0);
   }

  fp=fopen(arg,"w");       /* open file for saving */
  if (fp==0) { Closing("Can't open save file"); exit(0); }

  fputs("/* The following code created with AMIGA Plus' ICON program */\n\n",fp);
  fputs("USHORT DOBdata[]=\n",fp);              /* data section out */
  fputs("{\n",fp);
  for (i=0;i<j;i++)
     {
      fprintf(fp,"  0x%04x",data[i]);
      if (i<(j-1)) fprintf(fp,",");          /* comma every four columns */
      if ((i+1)%4==0) fprintf(fp,"\n");
     }
  fputs("};\t\t/* ImageData           */\n\n",fp);

  fputs("struct Image DOBimage =\n",fp);       /* image structure out */
  fputs  ("{\n",fp);
  fputs  ("  0,\t\t/* LeftEdge            */\n",fp);
  fputs  ("  0,\t\t/* TopEdge             */\n",fp);
  fprintf(fp,"  %d,\t\t/* Width               */\n",image->Width);
  fprintf(fp,"  %d,\t\t/* Height              */\n",image->Height);
  fprintf(fp,"  %d,\t\t/* Depth               */\n",image->Depth);
  fputs  ("  &DOBdata[0],\n",fp);
  fputs  ("\t\t/* ImageData           */\n",fp);
  fprintf(fp,"  %d,\t\t/* PlanePick           */\n",image->PlanePick);
  fprintf(fp,"  %d,\t\t/* PlaneOnOff          */\n",image->PlaneOnOff);
  fputs  ("  NULL\t\t/* NextImage           */\n",fp);
  fputs  ("};\n\n",fp);

  if (image2!=0)     /* we have an alternative image */
   {
    fputs("USHORT DOBdata2[]=\n",fp);              /* data section out */
    fputs("{\n",fp);
    for (i=0;i<j;i++)
     {
      fprintf(fp,"  0x%04x",data2[i]);
      if (i<(j-1)) fprintf(fp,",");          /* comma every four columns */
      if ((i+1)%4==0) fprintf(fp,"\n");
     }
    fputs("};\t\t/* ImageData           */\n\n",fp);

    fputs("struct Image DOBimage2 =\n",fp);       /* image structure out */
    fputs  ("{\n",fp);
    fputs  ("  0,\t\t/* LeftEdge            */\n",fp);
    fputs  ("  0,\t\t/* TopEdge             */\n",fp);
    fprintf(fp,"  %d,\t\t/* Width               */\n",image2->Width);
    fprintf(fp,"  %d,\t\t/* Height              */\n",image2->Height);
    fprintf(fp,"  %d,\t\t/* Depth               */\n",image2->Depth);
    fputs  ("  &DOBdata2[0],\n",fp);
    fputs  ("\t\t/* ImageData           */\n",fp);
    fprintf(fp,"  %d,\t\t/* PlanePick           */\n",image2->PlanePick);
    fprintf(fp,"  %d,\t\t/* PlaneOnOff          */\n",image2->PlaneOnOff);
    fputs  ("  NULL\t\t/* NextImage           */\n",fp);
    fputs  ("};\n\n",fp);
   }

  if (strlen(dob->do_ToolTypes[0])!=0)    /* possible tooltypes array */
   {
    fputs("static char *DOBtools[] =\n",fp);
    fprintf(fp,"{\n");
    for (i=0; strlen(dob->do_ToolTypes[i])!=0; i++)
     {
      fprintf(fp,"\n  \"%s\"",dob->do_ToolTypes[i]);
      if (dob->do_ToolTypes[i+1]!=0) fprintf(fp,",");    /* no comma aft. last */
     }
    fprintf(fp,"\n};\t\t/* do_ToolTypes       */\n\n");
   }

  fputs("struct DiskObject DOB =\n",fp);
  fputs  ("{\n",fp);
  fputs  ("  WB_DISKMAGIC,  \t/* do_Magic            */\n",fp);
  fputs  ("  WB_DISKVERSION,\t/* do_Version          */\n",fp);
  fputs  ("  NULL,\t\t\t/* NextGadget          */\n",fp);
  fprintf(fp,"  %d,\t\t\t/* LeftEdge            */\n",gdg.LeftEdge);
  fprintf(fp,"  %d,\t\t\t/* TopEdge             */\n",gdg.TopEdge);
  fprintf(fp,"  %d,\t\t\t/* Width               */\n",gdg.Width);
  fprintf(fp,"  %d,\t\t\t/* Height              */\n",gdg.Height);
  switch (gdg.Flags) {
    case GADGIMAGE | GADGHCOMP  :
      fputs("  GADGIMAGE | GADGHCOMP,\n",fp);
      break;
    case GADGIMAGE | GADGHBOX   :
      fputs("  GADGIMAGE | GADGHBOX,\n",fp);
      break;
    case GADGIMAGE | GADGHIMAGE :
      fputs("  GADGIMAGE | GADGHIMAGE,\n",fp);
      break;
    default :
      fprintf(fp,"  %d,\n",gdg.Flags);
      break;
   }
  fputs("\t\t\t/* Flags               */\n",fp);
  fputs  ("  RELVERIFY | GADGIMMEDIATE,\n",fp);
  fputs  ("\t\t\t/* Activation          */\n",fp);
  fputs  ("  BOOLGADGET,\t\t/* GadgetType          */\n",fp);
  fputs  ("  (APTR)&DOBimage,\n",fp);
  fputs  ("\t\t\t/* GadgetRender        */\n",fp);
  if (image2!=0)    /* alternate image */
   {
    fputs  ("  (APTR)&DOBimage2,\n",fp);
    fputs  ("\t\t\t/* SelectRender        */\n",fp);
   }
  else fputs ("  NULL,\t\t\t/* SelectRender        */\n",fp);
  fputs  ("  NULL,\t\t\t/* GadgetText          */\n",fp);
  fprintf(fp,"  %ld,\t\t\t/* MutualExclude       */\n",gdg.MutualExclude);
  fputs  ("  NULL,\t\t\t/* SpecialInfo         */\n",fp);
  fprintf(fp,"  %d,\t\t\t/* GadgetID            */\n",gdg.GadgetID);
  fputs  ("  NULL,\t\t\t/* UserData            */\n",fp);
  switch (dob->do_Type) {
    case WBDISK    :
      fprintf(fp,"  WBDISK");
      break;
    case WBDRAWER  :
      fprintf(fp,"  WBDRAWER");
      break;
    case WBTOOL    :
      fprintf(fp,"  WBTOOL");
      break;
    case WBPROJECT :
      fprintf(fp,"  WBPROJECT");
      break;
    case WBGARBAGE :
      fprintf(fp,"  WBGARBAGE");
      break;
    case WBDEVICE  :
      fprintf(fp,"  WBDEVICE");
      break;
    case WBKICK    :
      fprintf(fp,"  WBKICK");
      break;
    default        :
      fprintf(fp,"  %u",dob->do_Type);
      break;
  }
  fputs(",\t\t/* do_Type             */\n",fp);

  if (strlen(dob->do_DefaultTool)!=0)
    fprintf(fp,"  \"%s\",\n",dob->do_DefaultTool);
  else fputs("  NULL,\n",fp);
  fputs("\t\t\t/* do_DefaultTool      */\n",fp);
  if (strlen(dob->do_ToolTypes[0])==0)
   fputs("  NULL,\t\t\t/* do_ToolTypes        */\n",fp);   /* no tooltypes */
  else
    fputs("  (char **)&DOBtools,\t/* do_ToolTypes        */\n",fp);
  fputs  ("  NO_ICON_POSITION,\t/* do_CurrentX         */\n",fp);
  fputs  ("  NO_ICON_POSITION,\t/* do_CurrentY         */\n",fp);
  fputs  ("  NULL,\t\t\t/* DrawerData          */\n",fp);
  fputs  ("  NULL,\t\t\t/* do_Toolwindow       */\n",fp);
  fprintf(fp,"  %ld\t\t\t/* do_StackSize        */\n",dob->do_StackSize);
  fputs("};\n\n",fp);
  fclose(fp);

  puts("  C-language header file created");
  return(0);
}


Usage()
{
  puts("Usage: ICON (filename) [C savefilename] [D DefaultTool]");
  puts("  [S stacksize] [T type]");
  puts("  [R Tool_1 Tool_2 ... Tool_N END]");
  puts("  [A Tool_1 Tool_2 ... Tool_N END]");
  puts("");
  puts("Options:\n\tC\tSave as C-structure.");
  puts("\tD\tChange DefaultTool");
  puts("\tS\tChange stack size");
  puts("\tT\tChange icon type (PROJECT or TOOL)");
  puts("\tR\tRedefine ToolTypes");
  puts("\tA\tAdd ToolTypes");
  Closing(NULL);
  exit(0L);
}


Closing(mes)
char *mes;
{
  if (mes)
   {
    printf("ERROR - %s\n",mes);
    puts("None of the changes will be saved");
   }
  puts("");
  if (dob) FreeDiskObject(dob);
  if (IconBase) CloseLibrary(IconBase);
  if (IntuitionBase) CloseLibrary(IntuitionBase);
}
