#include "wipecount.h"

struct NewWindow NewWindow = {
250,160,145,10,
1,2,
NULL,   /* IDCMP flags ... later CLOSEWINDOW */
WINDOWCLOSE|WINDOWDRAG|SMART_REFRESH|NOCAREREFRESH|WINDOWDEPTH|ACTIVATE,
NULL,
NULL,
(STRPTR) "Demo",
NULL,
NULL,
0,0,0,0,
WBENCHSCREEN
};

struct NewScreen NewScreen = {
0,0,384,240,5,
0,1,
NULL,
CUSTOMSCREEN,
NULL,
(STRPTR) "Please wait...",
NULL,
NULL
};

struct Screen *Picture;
struct Window *Control;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *IconBase;
struct narrator_rb *TalkCB = 0;
struct timerequest *WaitCB;
FILE *script;
long numplanes;
extern struct WBStartup *WBenchMsg;

main(argc,argv)
int argc;
char **argv;
{
char *get1,*get2,*GetLin(),*scrfln;
static UBYTE chmasks[4] = {3,5,10,12};
static UWORD ptr[6] = {0,0,0,0,0,0};
struct narrator_rb *CreateExtIO();
long time(),nzx,nzy;
int wipesel = -1,cycsel = 0,arg = 1,t0;
BOOL hires = FALSE,lace = FALSE;
static BOOL exclmap[WIPECOUNT];
struct DiskObject *diskobj;
char *value;

   scrfln = "wipedemo.s";
   if (!argc)
      {
      IconBase = OpenLibrary("icon.library",0L);
      if (WBenchMsg->sm_NumArgs == 2)
         {
         scrfln = WBenchMsg->sm_ArgList[1].wa_Name;
         diskobj = GetDiskObject(scrfln);
         }
      else
         diskobj = GetDiskObject(WBenchMsg->sm_ArgList[0].wa_Name);
      if (value = FindToolType(diskobj->do_ToolTypes,"FLAGS"))
         {
         lace = MatchToolValue(value,"LACE");
         hires = MatchToolValue(value,"HIRES");
         }
      FreeDiskObject(diskobj);
      CloseLibrary(IconBase);
      }
   else
      {
      if (!ustrcmp("?",argv[1]))
         {
         printf("Usage: %s [LACE] [HIRES] [FILENAME]\n",argv[0]);
         exit(0L);
         }
      if (arg < argc)
         if (!ustrcmp("lace",argv[arg]))
            {
            lace = TRUE;
            arg++;
            }
      if (arg < argc)
         if (!ustrcmp("hires",argv[arg]))
            {
            hires = TRUE;
            arg++;
            }
      if (arg < argc)
         if (!ustrcmp("lace",argv[arg]))
            {
            lace = TRUE;
            arg++;
            }
      if (arg < argc)
         scrfln = argv[arg];
      }
   nzx = 32;
   nzy = 20;
   if (lace)
      {
      NewScreen.Height = 480;
      NewScreen.ViewModes |= INTERLACE;
      nzy = 40;
      }
   if (hires)
      {
      NewScreen.Width = 768;
      NewScreen.ViewModes |= HIRES;
      nzx = 64;
      }
   Check0(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0L));
   Check0(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L));
   numplanes = (hires) ? 4 : 6;
   NewScreen.Depth = numplanes;
   Check0(script = fopen(scrfln,"r"));
   Check0(Picture = OpenScreen(&NewScreen));
   Picture->ViewPort.DxOffset = -nzx;
   Picture->ViewPort.DyOffset = -nzy;
   Check0(Control = OpenWindow(&NewWindow));
   SetPointer(Control,ptr,1L,1L,0L,0L);
   srand((unsigned int) time(0L));
   Check0(WaitCB = (struct timerequest *) CreateExtIO(CreatePort(0L,0L),(long)
                  sizeof(struct timerequest)));
   OpenDevice(TIMERNAME,UNIT_VBLANK,WaitCB,0L);
   WaitCB->tr_node.io_Command = TR_ADDREQUEST;
   WaitCB->tr_time.tv_micro = 0;

   FOREVER
      {
      get1 = GetLin(script);
      if (!get1)
         break;
      if (*get1 == '#')
         continue;
      for (get2 = get1; *get2 != ' '; get2++)
         if (!(*get2))
            break;
      if (*get2)
         *(get2++) = NULL;
      if (!ustrcmp(get1,"show"))
         {
         LoadPict(get2,Picture,wipesel,cycsel,1,exclmap,hires,lace);
         continue;
         }
      if (!ustrcmp(get1,"say"))
         {
         if (!TalkCB)
            {
            Check0(TalkCB = CreateExtIO(CreatePort(0L,0L),
               (long) sizeof(struct narrator_rb)));
            TalkCB->ch_masks = chmasks;
            TalkCB->nm_masks = 4;
            TalkCB->message.io_Command = CMD_WRITE;
            TalkCB->mouths = 0;
            if (OpenDevice("narrator.device",0L,TalkCB,0L))
               TheEnd();
            }
         Say(get2);
         continue;
         }
      if (!ustrcmp(get1,"wait"))
         {
         Sit(get2);
         continue;
         }
      if (!ustrcmp(get1,"loop"))
         {
         fseek(script,0L,0);
         continue;
         }
      if (!ustrcmp(get1,"random"))
         {
         wipesel = -1;
         continue;
         }
      if (!ustrcmp(get1,"select"))
         {
         wipesel = atoi(get2);
         continue;
         }
      if (!ustrcmp(get1,"exclude"))
         {
         if (!ustrcmp(get2,"all"))
            {
            for (t0 = 0; t0 != WIPECOUNT; t0++)
               exclmap[t0] = TRUE;
            continue;
            }
         if (!exclmap[t0 = atoi(get2)])
            exclmap[t0] = TRUE;
         continue;
         }
      if (!ustrcmp(get1,"include"))
         {
         if (!ustrcmp(get2,"all"))
            for (t0 = 0; t0 != WIPECOUNT; t0++)
               exclmap[t0] = FALSE;
         if (exclmap[t0 = atoi(get2)])
            exclmap[t0] = FALSE;
         continue;
         }
      if (!ustrcmp(get1,"fades"))
         continue;
      if (!ustrcmp(get1,"cycle"))
         {
         if (!ustrcmp(get2,"off"))
            cycsel = 0;
         else
            cycsel = 1;
         continue;
         }
      break;
      }
   TheEnd();
}

TheEnd()
{
   StopCringe();
   if (WaitCB && WaitCB->tr_node.io_Device)
      CloseDevice(WaitCB);
   if (TalkCB && TalkCB->message.io_Device)
      CloseDevice(TalkCB);
   if (TalkCB)
      {
      DeletePort(TalkCB->message.io_Message.mn_ReplyPort);
      DeleteExtIO(TalkCB,(long) sizeof(struct narrator_rb));
      }
   if (WaitCB)
      {
      DeletePort(WaitCB->tr_node.io_Message.mn_ReplyPort);
      DeleteExtIO(WaitCB,(long) sizeof(struct timerequest));
      }
   if (Control)
      CloseWindow(Control);
   if (Picture)
      CloseScreen(Picture);
   if (script)
      fclose(script);
   if (GfxBase)
      CloseLibrary(GfxBase);
   if (IntuitionBase)
      CloseLibrary(IntuitionBase);
   exit(0L);
}

Say(whattosay)
char *whattosay;
{
   TalkCB->message.io_Data = (APTR) whattosay;
   TalkCB->message.io_Length = strlen(whattosay);
   DoIO(TalkCB);
}

Sit(howstr)
char *howstr;
{
int secs;
struct Message *Mess;

   ModifyIDCMP(Control,CLOSEWINDOW);
   secs = atoi(howstr);
   WaitCB->tr_time.tv_secs = secs;
   SendIO(WaitCB);
   Wait((1L << WaitCB->tr_node.io_Message.mn_ReplyPort->mp_SigBit) |
        (1L << Control->UserPort->mp_SigBit));
   if (Mess = GetMsg(Control->UserPort))
      {
      AbortIO(WaitCB);
      ReplyMsg(Mess);
      TheEnd();
      }
   GetMsg(WaitCB->tr_node.io_Message.mn_ReplyPort);
   ModifyIDCMP(Control,0L);
}

char *GetLin(handle)
FILE *handle;
{
static char buf[90];

if (fgets(buf,90,handle) == NULL)
   return(NULL);

buf[strlen(buf)-1] = NULL;

return(buf);
}

ustrcmp(x,y)
char *x,*y;
{
   while (*x)
      if (toupper(*(x++)) != toupper(*(y++)))
         return(1);
   return(0);
}
