/*
 *  WICONCUTTER     A companion utility to wIconSetter and wIconify.
 *                  wIconCutter lets you select a section of any screen
 *                  and creates a wIconSetter icon file using the selected
 *                  bitmap as the icon's image.
 *
 *  Copyright 1990 by Davide P. Cervone, all rights reserved.
 *  You may use this code, provided this copyright notice is kept intact.
 */

#include <exec/types.h>
#include <graphics/rastport.h>
#include "Frame.h"


char *program    = "wIconCutter";
char *version    = "v1.1";
char *copyright  = "Copyright (c) 1990 by Davide P. Cervone";
char *usage =
   "wIconCutter [IMAGE | SELECT] [MASK] [APPEND] [PLANES n] file";

#ifdef MANX
   #define ERROR errno
#else
   #define ERROR _OSERR
#endif

extern long fopen();
extern long ERROR;

static char *FileName;      /* the output file name */
static long OutFile;        /* the output file handle */

static char *Hex = "0123456789abcdef)!@#$%^&*(ABCDEF";
#define MAXHEX      32
#define MAXLINE     132

static int AppendIt;        /* TRUE if appending to the output file */
static int ImageType;       /* which type of image is being created */
#define CUT_IMAGE   1
#define CUT_SELECT  2
#define CUT_MASK    4


#define ARGMATCH(s)     (stricmp(argv[0],s) == 0)


/*
 *  ParseArguments()
 *
 *  Set the function to framing
 *  While there are more arguements to consider
 *    Get the next one
 *    If it is an image type, add it to the type to be produced
 *    Otherwise if it is APPEND, set the append flag
 *    Otherwise if it is PLANES,
 *      Get a bit-plane mask
 *    Otherwise, if no filename has been given use it as a file name
 *    Otherwise, give an error and show usage
 *  If no file was specified, give an error and show usage
 *  return the function to be performed
 */

int ParseArguments(argc,argv)
int argc;
char **argv;
{
   int function = FRAME_IT;
   long mask;
   
   while (--argc > 0)
   {
      argv++;
      if (ARGMATCH("IMAGE"))  ImageType |= CUT_IMAGE; else
      if (ARGMATCH("SELECT")) ImageType |= CUT_SELECT; else
      if (ARGMATCH("MASK"))   ImageType |= CUT_MASK; else
      if (ARGMATCH("APPEND")) AppendIt = TRUE; else
      if (ARGMATCH("PLANES"))
      {
         if (argc >= 2 &&  (sscanf(argv[1],"%lx",&mask) == 1))
         {
            PlaneMask = mask;
         } else {
            printf("PLANES requires a hex value\n");
            function = JUST_EXIT;
         }
         argc--; argv++;
      } else
      if (FileName == NULL) FileName = argv[0]; else
      {
         printf("Unrecognized parameter '%s'\n",argv[0]);
         function = SHOW_USAGE;
      }
   }
   if (FileName == NULL)
   {
      printf("Missing file specification\n");
      function = SHOW_USAGE;
   }
   return(function);
}


/*
 *  WriteHeading()
 *
 *  Write the comments at the top of the file that identify the file and
 *  the creating program.
 */

static void WriteHeading()
{
   fprintf(OutFile,"/*\n *  %s\n *\n",FileName);
   fprintf(OutFile," *  An Icon Created by %s %s\n */\n",program,version);
}


/*
 *  WriteBitMap()
 *
 *  For each row of the bitmap
 *    And each column of each row
 *      Get the pen color of the pixel at that position
 *      Save the pixel value as a HEX digit in the output line
 *    End the line and print it to the output file
 */

static void WriteBitMap(theRPort)
struct RastPort *theRPort;
{
   short h,w;
   short Width = (theWidth < MAXLINE)? theWidth: MAXLINE;
   int pen;
   char Line[MAXLINE];

   for (h=0; h<theHeight; h++)
   {
      for (w=0; w<Width; w++)
      {
         pen = ReadPixel(theRPort,w,h) % MAXHEX;
         Line[w] = Hex[pen];
      }
      Line[w] = 0;
      fprintf(OutFile,"\n   ");
      fprintf(OutFile,Line);
   }
   fprintf(OutFile,"\n");
}


/*
 *  WriteMask()
 *
 *  Write the MASK command to the file
 *  For each row of the bitmap
 *    And each column of each row
 *      Get the pen color of the pixel at that position
 *      If it is non-zero, put a '1' in the line, otherwise a '0'
 *    End the line and print it to the file
 */

static void WriteMask(theRPort)
struct RastPort *theRPort;
{
   short h,w;
   short Width = (theWidth < MAXLINE)? theWidth: MAXLINE;
   int pen;
   char Line[MAXLINE];

   fprintf(OutFile,"\nMASK:\n");
   for (h=0; h<theHeight; h++)
   {
      for (w=0; w<Width; w++)
      {
         pen = ReadPixel(theRPort,w,h);
         if (pen) Line[w] = Hex[1]; else Line[w] = Hex[0];
      }
      Line[w] = 0;
      fprintf(OutFile,"\n   ");
      fprintf(OutFile,Line);
   }
   fprintf(OutFile,"\n");
}



/*
 *  WriteImage()
 *
 *  Write the IMAGE command to the file, then print the image data
 */

static void WriteImage(theRPort)
struct RastPort *theRPort;
{
   fprintf(OutFile,"\nIMAGE:\n");
   WriteBitMap(theRPort);
}


/*
 *  WriteSelect()
 *
 *  WRite the SELECT command to the file, then write the image data
 */

static void WriteSelect(theRPort)
struct RastPort *theRPort;
{
   fprintf(OutFile,"\nSELECT:\n");
   WriteBitMap(theRPort);
}


/*
 *  WriteIcon()
 *
 *  If we are appending to the file,
 *    Open the file for appending (error if we can't)
 *  Otherwise
 *    Open the file for writing (error if we can't)
 *    And write the heading
 *  Initialize a RastPort to use the copied BitMap.
 *  Write the IMAGE, SELECT, and MASK data that have been requested.
 *  Close the file
 */

static void WriteIcon()
{
   struct RastPort theRPort;

   if (AppendIt)
   {
      OutFile = fopen(FileName,"a");
      if (OutFile == NULL)
         DoExit("Can't Append '%s' - Error: %ld",FileName,ERROR);
   } else {
      OutFile = fopen(FileName,"w");
      if (OutFile == NULL)
         DoExit("Can't Create '%s' - Error: %ld",FileName,ERROR);
      WriteHeading();
   }

   InitRastPort(&theRPort);
   theRPort.BitMap = &theBitMap;
   if (ImageType & CUT_IMAGE)  WriteImage(&theRPort);
   if (ImageType & CUT_SELECT) WriteSelect(&theRPort);
   if (ImageType & CUT_MASK)   WriteMask(&theRPort);

   fclose(OutFile); OutFile = NULL;
}


/*
 *  UseFrame()
 *
 *  If no image type was specified, assume IMAGE
 *  Write the icon to the file
 */

void UseFrame(function)
int function;
{
   if (ImageType == 0) ImageType = CUT_IMAGE;
   WriteIcon();
}


/*
 *  DoUseExit()
 *
 *  The only cleanup needed here is closing the file if it is open.
 *  The rest of the cleanup is done by Frame itself.
 */

void DoUseExit()
{
   if (OutFile) fclose(OutFile);
}
