#include <intuition/intuisup.h>
#include <libraries/dos.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>

#ifndef DEBUG
#include <proto/all.h>
#endif

#define  HUNK_UNIT     0xe7
#define  HUNK_HEADER   0xf3

#define  KNOWN_FILE_TYPES  6

#define  INVALID_FILE     -2
#define  UNKNOWN_FILE     -1
#define  EXECUTABLE_FILE   0
#define  OBJECT_FILE       1
#define  ASCII_FILE        2
#define  IFF_ILBM_FILE     3
#define  IFF_8SVX_FILE     4
#define  IFF_ANIM_FILE     5

BOOL     use_quotes = TRUE, use_prompt = TRUE;
UBYTE    Type[KNOWN_FILE_TYPES][25] =
   {
   "executable",
   "object module",
   "ascii text",
   "IFF picture (ILBM)",
   "IFF sound (8SVX)",
   "IFF animation (ANIM)",
   };
UBYTE    Viewer[KNOWN_FILE_TYPES][21] =
   {
   /*--- Max len 20 ---*/
   "",
   "DISABLED",
   "etc:less",
   "etc:show",
   "etc:play",
   "etc:movie"
   };
UBYTE    ToolType[KNOWN_FILE_TYPES][8] =
   {
   "",
   "OBJECT",
   "TEXT",
   "PICTURE",
   "SOUND",
   "ANIM"
   };

VOID Help()
{
   printf("Usage: smallbench [?] [ [-h|p|q] [-r|o|t|i|s|a <file>|DISABLED] ... ]\n");
   printf("       -h : printf this reminder\n");
   printf("       -p : disable file type verification, default on\n");
   printf("       -q : disable quotes around filename, default on\n");
   printf("       -t <file>: text file viewer, default etc:less\n");
   printf("       -o <file>: object file application, default DISABLED\n");
   printf("       -i <file>: IFF ILBM viewer, default etc:show\n");
   printf("       -s <file>: IFF 8SVX player, default etc:play\n");
   printf("       -a <file>: IFF ANIM player, default etc:movie\n");
   printf("       Using DISABLED instead of <file> disables action.\n");
   printf("Version 1.1, written by Gauthier Groult, 89.1020\n");
}

BYTE ParseCLIArgs(argc, argv)
UBYTE argc, **argv;
{
   UBYTE arg = 1, viewer;

   while (arg<argc)
         {
         switch(argv[arg][0])
               {
               case '?':
                  Help();
                  return(1);
               break;

               case '-':
                  viewer = 0;
                  switch(argv[arg][1])
                        {
                        case 'h': Help(); return(1); break;
                        case 'p': use_prompt = FALSE; break;
                        case 'q': use_quotes = FALSE; break;
                        case 'o': viewer = 1; break;
                        case 't': viewer = 2; break;
                        case 'i': viewer = 3; break;
                        case 's': viewer = 4; break;
                        case 'a': viewer = 5; break;
                        default: return(2);
                        }
                  if (viewer && argv[arg+1][0])
                     {
                     StrCpy(Viewer[viewer], argv[arg+1]);
                     arg+=2;
                     }
                  else arg++;
               break;

               default: return(2);
               }
         }
   return(0);
}

VOID ParseWBArgs(wbMsg)
struct WBStartup *wbMsg;
{
   UBYTE  i, *s, **toolarray;
   struct WBArg      *wbArg;
   struct DiskObject *diskobj;

   /* Get ToolTypes from SmartIcon.info */
   wbArg = wbMsg->sm_ArgList;
   diskobj=(struct DiskObject *)GetDiskObject(wbArg->wa_Name);
   if(diskobj)
      {
      toolarray = (char **)diskobj->do_ToolTypes;

      for(i=1; i<KNOWN_FILE_TYPES; i++)
         if (s=(UBYTE *)FindToolType(toolarray, ToolType[i])) StrCpy(Viewer[i], s);

      if ((s=(UBYTE *)FindToolType(toolarray, "PROMPT")) && !StrCmp(s, "OFF")) use_prompt = FALSE;
      if ((s=(UBYTE *)FindToolType(toolarray, "QUOTES")) && !StrCmp(s, "OFF")) use_quotes = FALSE;

      FreeDiskObject(diskobj);
      }
}

BYTE FileType(window, filename)
struct Window *window;
UBYTE *filename;
{
   BYTE  rc = 0;
   SHORT i = 0, flag = 1;
   UBYTE buffer[400];
   struct FileHandle *filep;

   if (!(filep = (struct FileHandle *)Open(filename, MODE_OLDFILE))) return(INVALID_FILE);

   SetPointerNum(window, WAIT_POINTER);
   for(i=0; i<400; i++) buffer[i]=0;
   Read(filep, buffer, 4);
   if  (buffer[3]==HUNK_UNIT) rc = OBJECT_FILE;
   else
     if  (buffer[3]==HUNK_HEADER) rc = EXECUTABLE_FILE;
     else
        if (!StrCmp(buffer,"FORM",4))
           {
           Read(filep, buffer, 4);
           Read(filep, buffer, 4);
           if (!StrCmp(buffer, "ILBM")) rc = IFF_ILBM_FILE;
           if (!StrCmp(buffer, "8SVX")) rc = IFF_8SVX_FILE;
           if (!StrCmp(buffer, "ANIM")) rc = IFF_ANIM_FILE;
           }
        else
           {
           Read(filep, buffer, 400);
           while (flag && (i++<400) ) if (buffer[i]>0x7E && buffer[i]<0xA0) flag = 0;
           if (flag) rc = ASCII_FILE;
           else      rc = UNKNOWN_FILE;
           }

   Close(filep);
   SetPointerNum(window, WBENCH_POINTER);
   return(rc);
}

BOOL
TypePrompt(window, filename, type)
struct Window *window;
UBYTE *filename, type;
{
   if (AutoSmartRequest(window, 3, BaseName(filename),
                       "supposed type is:", Type[type],
                        0, "Ok", "Cancel", NULL, NULL) ) return(TRUE);
   return(FALSE);
}

VOID DisplayFile(window, filename, type)
struct Window *window;
UBYTE *filename, type;
{
   UBYTE command[80];
   struct FileHandle *nil = (struct FileHandle *)Open("NIL:", MODE_NEWFILE); /* always succesfull */

   if (use_prompt && !(TypePrompt(window, filename, type))) return;

   if (StrCmp(Viewer[type], "DISABLED"))
      {
      StrCpy(command, "c:run >NIL: <NIL: " );
      if (type)
         {
         StrCat(command, Viewer[type]);
         StrCat(command, " >NIL: <NIL: ");
         }

      if (use_quotes) StrCat(command, "\"");
      StrCat(command, filename);
      if (use_quotes) StrCat(command, "\"");

      SetPointerNum(window, WAIT_POINTER);
#ifdef DEBUG
      printf("Execute %s\n", command);
#endif
      if (!Execute(command, nil, nil)) DisplayBeep(NULL);
      SetPointerNum(window, WBENCH_POINTER);
      }
   Close(nil);
}


