/* Source File FL_Panel.c */

/* Includes */
 
#include <ctype.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <dos/dos.h>
#include <string.h>
#include <stdlib.h>
#include <libraries/asl.h>
#include <stdio.h>

#include "SimpleRexx_tm.h" /* SimpleRexx header file */
#include "FL_Panel.h"      /* User header file       */
#include "FL_Panel_rev.h"  /* Bumprev header file    */

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/utility_protos.h>
#include <clib/asl_protos.h>
#include <clib/dos_protos.h>

/* Pragma includes for register parameters */
 
#include <pragmas/exec_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/gadtools_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <pragmas/asl_pragmas.h>
#include <pragmas/dos_pragmas.h>

/* Global variables */
 
char vers[] = VERSTAG;          /* Bumprev version string */
struct Library *IntuitionBase;  /* intuition.library pointer */
struct Library *GadToolsBase;   /* gadtools.library pointer */
struct Library *UtilityBase;    /* utility.library pointer */
struct Library *AslBase;        /* asl.library pointer */
struct IntuiText BodyText = {0,1,JAM2,20,8,NULL,(UBYTE *)TEXT_NORELEASE2,NULL};
struct IntuiText NegText  = {0,1,JAM2, 6,4,NULL,(UBYTE *)TEXT_OK,NULL};

static BOOL ARexxInvocation = FALSE;

#include "FL_Panel_Glob.h"

BOOL FL_Panel_Init ( int argc, char *argv[] );

/* Protos for Event Functions */
BOOL EventFunc_SAVE     ( struct TMData *, struct IntuiMessage *, TMOBJECTDATA * );
BOOL EventFunc_ABOUT    ( struct TMData *, struct IntuiMessage *, TMOBJECTDATA * );
BOOL EventFunc_QUIT     ( struct TMData *, struct IntuiMessage *, TMOBJECTDATA * );
BOOL EventFunc_FLPSeed  ( struct TMData *, struct IntuiMessage *, TMOBJECTDATA * );
BOOL EventFunc_FLPRaniz ( struct TMData *, struct IntuiMessage *, TMOBJECTDATA * );
BOOL EventFunc_FILENAME ( struct TMData *, struct IntuiMessage *, TMOBJECTDATA * );
BOOL EventFunc_MAKEFRAC ( struct TMData *, struct IntuiMessage *, TMOBJECTDATA * );
BOOL EventFunc_SAVEAS   ( struct TMData *, struct IntuiMessage *, TMOBJECTDATA * );
void RandomizeSeed      ( void                                                   );
BOOL Call_FL            ( struct TMData *                                        );
void DisableAllGadgets  ( struct TMData *                                        );
void EnableAllGadgets   ( struct TMData *                                        );
void SetSeedGadget      ( struct TMData *, char  *NewSeed                        );
void SetXLevelGadget    ( struct TMData *                                        );
void SetYLevelGadget    ( struct TMData *                                        );
void SetNameGadget      ( struct TMData *                                        );

/* Entry functions */
 
VOID main(int argc, char **argv)
{
  struct TMData *TMData;	/* data structure pointer */
  ULONG error;
  char NewSeed [ 25 ] = { "                        " };

  if(!(IntuitionBase = OpenLibrary((UBYTE *)"intuition.library", 37L)))	/* Open intuition.library V37 */
    {
    if(IntuitionBase = OpenLibrary((UBYTE *)"intuition.library", 0L))
      {
      AutoRequest(NULL, &BodyText, NULL, &NegText, 0, 0, 320, 80);
      CloseLibrary(IntuitionBase);
      }
    cleanexit(NULL, RETURN_FAIL);
    }

  if(!(GadToolsBase = OpenLibrary((UBYTE *)"gadtools.library", 37L)))	/* Open gadtools.library V37 */
    {
    TM_Request(NULL, (UBYTE *)TEXT_ERROR, (UBYTE *)TEXT_NOLIBRARY, (UBYTE *)TEXT_ABORT, NULL, "gadtools.library V37");
    cleanexit(NULL, RETURN_FAIL);
    }

  if(!(UtilityBase = OpenLibrary((UBYTE *)"utility.library", 37L)))	/* Open utility.library V37 */
    {
    TM_Request(NULL, (UBYTE *)TEXT_ERROR, (UBYTE *)TEXT_NOLIBRARY, (UBYTE *)TEXT_ABORT, NULL, "utility.library V37");
    cleanexit(NULL, RETURN_FAIL);
    }

  if(!(AslBase = OpenLibrary((UBYTE *)"asl.library", 37L)))	/* Open asl.library V37 */
    {
    TM_Request(NULL, (UBYTE *)TEXT_ERROR, (UBYTE *)TEXT_NOLIBRARY, (UBYTE *)TEXT_ABORT, NULL, "asl.library V37");
    cleanexit(NULL, RETURN_FAIL);
    }

  FL_Panel_Init ( argc, argv );
  
  if(!(TMData = TM_Open(&error)))	/* Open Toolmaker data */
    {
    switch(error)
      {
      case TMERR_MEMORY:
        TM_Request(NULL, (UBYTE *)TEXT_ERROR, (UBYTE *)TEXT_NOMEMORY, (UBYTE *)TEXT_ABORT, NULL, NULL);
        break;
      case TMERR_MSGPORT:
        TM_Request(NULL, (UBYTE *)TEXT_ERROR, (UBYTE *)TEXT_NOMSGPORT, (UBYTE *)TEXT_ABORT, NULL, NULL);
        break;
      }
    cleanexit(NULL, RETURN_FAIL);
    }

  if(!(TMData->FileRequester = AllocAslRequestTags(ASL_FileRequest, TAG_DONE)))
    {
    TM_Request(NULL, (UBYTE *)TEXT_ERROR, (UBYTE *)TEXT_NOFILEREQ, (UBYTE *)TEXT_ABORT, NULL, NULL);
    cleanexit(TMData, RETURN_FAIL);
    }

  if(!(OpenScreen_Workbench(TMData)))	/* Open default public screen */
    {
    TM_Request(NULL, (UBYTE *)TEXT_ERROR, (UBYTE *)TEXT_NOSCREEN, (UBYTE *)TEXT_ABORT, NULL, NULL);
    cleanexit(TMData, RETURN_FAIL);
    }

  if(!(OpenWindow_AMIGAFLP(TMData)))	/* Open the window */
    {
    TM_Request(NULL, (UBYTE *)TEXT_ERROR, (UBYTE *)TEXT_NOWINDOW, (UBYTE *)TEXT_ABORT, NULL, NULL);
    cleanexit(TMData, RETURN_FAIL);
    }

  /* Set up the tool types or the defaults now that the window is open. */
  stcu_d ( NewSeed, Seed );
  SetSeedGadget ( TMData, NewSeed );

  GT_SetGadgetAttrs ( gadget_FLPNUMX, window_AMIGAFLP, NULL, GTSL_Level, XPointCardinality, TAG_END );
  GT_SetGadgetAttrs ( gadget_FLPNUMY, window_AMIGAFLP, NULL, GTSL_Level, YPointCardinality, TAG_END );
  GT_SetGadgetAttrs ( gadget_FILENAME,
                      window_AMIGAFLP, NULL, GTST_String, UsersFileName, TAG_END );
  GT_RefreshWindow  ( window_AMIGAFLP, NULL );  

  TM_EventLoop(TMData);	/* Process events */

  cleanexit(TMData, RETURN_OK);
}

/* cleanexit function */
 
VOID cleanexit(struct TMData *TMData, int returnvalue)
{
  if(TMData)
    {
    CloseWindow_AMIGAFLP(TMData);
    CloseScreen_Workbench(TMData);
    if(TMData->FileRequester) FreeAslRequest(TMData->FileRequester);
    TM_Close(TMData);
    }

  if(AslBase)       CloseLibrary(AslBase);       /* Close asl.library       */
  if(UtilityBase)   CloseLibrary(UtilityBase);   /* Close utility.library   */
  if(GadToolsBase)  CloseLibrary(GadToolsBase);  /* Close gadtools.library  */
  if(IntuitionBase) CloseLibrary(IntuitionBase); /* Close intuition.library */

  exit ( returnvalue );
}

/* ASL file requester function */
 
UBYTE *getfilename(struct TMData *TMData, UBYTE *title, UBYTE *buffer, ULONG bufsize, struct Window *window, BOOL saveflag)
{
  ULONG funcflags;

  if(saveflag)
    funcflags = FILF_SAVE;
  else
    funcflags = 0;

  if(buffer && TMData)
    {
    if(AslRequestTags((APTR) TMData->FileRequester,
                      ASL_Hail, title,
                      ASL_Window, window,
                      ASL_FuncFlags, funcflags,
                      TAG_DONE))
      {
      strcpy(buffer, TMData->FileRequester->rf_Dir);
      if(AddPart(buffer, TMData->FileRequester->rf_File, bufsize))
        {
        return(buffer);
        }
      }
    }

  return(NULL);
}

/* Window event functions */
 
BOOL Window_AMIGAFLP_CLOSEWINDOW(struct TMData *TMData, struct IntuiMessage *imsg)
  {
  return(TRUE);
  }

BOOL Window_AMIGAFLP_MENUPICK(struct TMData *TMData, struct IntuiMessage *imsg)
  {
  UWORD menucode;
  struct MenuItem *menuitem;
  TMOBJECTDATA *tmobjectdata;
  BOOL (*eventfunc)(struct TMData *, struct IntuiMessage *, TMOBJECTDATA *);

  menucode = imsg->Code;
  while(menucode != MENUNULL)
    {
    menuitem = ItemAddress(WindowInfo_AMIGAFLP.Menu, menucode);
    tmobjectdata = (TMOBJECTDATA *)(GTMENUITEM_USERDATA(menuitem));
    eventfunc = tmobjectdata->EventFunc;

    if(eventfunc)
      {
      if((*eventfunc)(TMData, imsg, tmobjectdata)) return(TRUE);
      }

    menucode = menuitem->NextSelect;
    }
  return ( FALSE );
  }

BOOL Window_AMIGAFLP_GADGETUP(struct TMData *TMData, struct IntuiMessage *imsg)
{
  struct Gadget *gadget;
  TMOBJECTDATA *tmobjectdata;
  BOOL (*eventfunc)(struct TMData *, struct IntuiMessage *, TMOBJECTDATA *);

  gadget = (struct Gadget *)imsg->IAddress;
  tmobjectdata = (TMOBJECTDATA *)(gadget->UserData);
  eventfunc = tmobjectdata->EventFunc;

  if(eventfunc)
    {
    return((*eventfunc)(TMData, imsg, tmobjectdata));
    }
  return ( FALSE );
}

BOOL Window_AMIGAFLP_VANILLAKEY(struct TMData *TMData, struct IntuiMessage *imsg)
{
  struct Gadget *gadget;
  TMOBJECTDATA *tmobjectdata;

  gadget = (struct Gadget *)imsg->IAddress;
  tmobjectdata = (TMOBJECTDATA *)(gadget->UserData);
  switch(imsg->Code)
  {
    case 'A': return ( EventFunc_SAVEAS   ( TMData, imsg, tmobjectdata ) );
    case 'F': return ( EventFunc_SAVEAS   ( TMData, imsg, tmobjectdata ) );
    case 'M': return ( EventFunc_MAKEFRAC ( TMData, imsg, tmobjectdata ) );
    case 'Q': return ( EventFunc_QUIT     ( TMData, imsg, tmobjectdata ) );
    case 'R': return ( EventFunc_FLPSeed  ( TMData, imsg, tmobjectdata ) );
    case 'S': return ( EventFunc_SAVE     ( TMData, imsg, tmobjectdata ) );
    case 'T': return ( EventFunc_ABOUT    ( TMData, imsg, tmobjectdata ) );
    case 'z': return ( EventFunc_FLPRaniz ( TMData, imsg, tmobjectdata ) );
    default : /* do nothing */;
  }
  return ( FALSE );
}

BOOL Window_AMIGAFLP_RAWKEY(struct TMData *TMData, struct IntuiMessage *imsg)
  {
  switch(imsg->Code)
    {
    case 0:
      break;
    }
  return ( FALSE );
  }

BOOL Window_AMIGAFLP_REQVERIFY(struct TMData *TMData, struct IntuiMessage *imsg)
  {
  return ( FALSE );
  }

BOOL Window_AMIGAFLP_MENUVERIFY(struct TMData *TMData, struct IntuiMessage *imsg)
  {
  return ( FALSE );
  }

BOOL Window_AMIGAFLP_MENUHELP(struct TMData *TMData, struct IntuiMessage *imsg)
  {
  return ( FALSE );
  }

BOOL SetSeed ( unsigned int SeedValue )
{
  Seed = SeedValue;
  return ( FALSE );
}

BOOL Call_FL ( struct TMData *TMData )
{
  char Command [ 256 ];
  int  i;
  LONG GadReturn = 0L;
  UBYTE FL_Error [ 256 ];
  char TheUsersName [ 150 ];

  DisableAllGadgets ( TMData );

  for ( i = 0; i < 150; ++i ) { TheUsersName [ i ] = '\0'; }
  TheUsersName [ 0 ] = '"';
  strcat ( TheUsersName, UsersFileName );
  strcat ( TheUsersName, "\"\0" );

  for ( i = 0; i < 256; ++i ) { Command [ i ] = '\0'; FL_Error [ i ] = '\0'; }

  /* Build the command for FL */

  sprintf ( Command, "FL:fl %s %d %d %ld FL_PANEL\n", TheUsersName,
                                                      XPointCardinality,
                                                      YPointCardinality, Seed );
  i = system ( Command );
  if ( i < 0 )
     {
       sprintf ( FL_Error, "FL FAILED TO RUN!!\n\nError returned was: %ld", i );
     }
    else if ( i > 0 )
     {
       sprintf ( FL_Error, "FL EXECUTION ERROR!\n\nError returned was: %ld", i );
     }
  if ( !ARexxInvocation )
     {
       if ( i != 0 )
          {
            GadReturn = TM_Request ( NULL, "Amiga Fractal Landscape Panel ERROR", FL_Error, "Okay|Okay", NULL, NULL );
          }
         else
            GadReturn = TM_Request ( NULL, "Amiga Fractal Landscape Panel", "FL is done.", "Okay|Okay", NULL, NULL );
     }
  EnableAllGadgets ( TMData );
  return ( (BOOL) i );
}

BOOL ARexxMessage(struct TMData *TMData, struct RexxMsg *RexxMsg)
{
  char         SeedValue [ 16 ] = "713\0\0\0\0\0\0\0\0\0\0\0\0";
  int          count;
  BOOL         done      = FALSE;
  UBYTE        command [ 24 ];
  UBYTE      * msgchar;
  UBYTE      * comchar;
  char         SwitchCommand;

  msgchar = ARG0 ( RexxMsg );
  comchar = command;
  count   = 0;

  while ( ( *msgchar != ' ' ) && ( *msgchar != '\0' ) && ( count < 23 ) )
  {
    *comchar++ = *msgchar++;
    count++;
  }
  *comchar = '\0';

  TMData->ARexxError [ 0 ] = '\0'; /* Null out error return string */
  TMData->ARexxErrorLevel  = 0;    /* Assume good return value.    */

  /* Stricmp() is a locale aware case-insensitive string compare in utility.library */
  if ( !Stricmp ( "QUIT", command ) )
     { /* Emergency QUIT request (no leading 'FL-PANEL.1') */
       done = TRUE;
     }
     else
     {
       /* Skip white space to next value. */
       count = 0;
       while ( ( *msgchar == ' ' ) && ( *msgchar != '\0' ) && ( count < 23 ) ) { msgchar++; count ++; }

       /* Now we have the command */
       SwitchCommand = toupper ( *msgchar );
       msgchar++; /* avoids macro problems */

       if ( SwitchCommand != 'M' )
          { /* Not doing the Make command, so skip the rest of the value. */
            count = 0;
            while ( ( *msgchar != ' ' ) && ( *msgchar != '\0' ) && ( count < 23 ) ) { msgchar++; count++; }
            /* Skip the white space */
            count = 0;
            while ( ( *msgchar == ' ' ) && ( *msgchar != '\0' ) && ( count < 23 ) ) { msgchar++; count++; }
          }

       switch ( SwitchCommand )
       {            /* Process Arexx commands                 */
         case 'Q' : /* Process QUIT request                   */
                    done = TRUE;
                    break;
         case 'A' :
         case 'F' : /* Process File Name                      */
                    strncpy ( UsersFileName, msgchar, 150 );
                    SetNameGadget ( TMData );
                    break;
         case 'R' :
         case 'Z' : /* Randomize (make new seed               */
                    RandomizeSeed();
                    stcu_d ( SeedValue, Seed );
                    SetSeedGadget ( TMData, SeedValue );
                    break;
         case 'S' : /* Set Seed Value                         */
                    Seed = atoi ( msgchar );
                    SetSeedGadget ( TMData, msgchar );
                    break;
         case 'M' : /* Make Fractal Landscape                 */
                    ARexxInvocation = TRUE;
                    done = Call_FL ( TMData );
                    stcu_d ( TMData->ARexxResult, done );
                    ARexxInvocation = FALSE;
                    break;
         case 'X' : /* Set X Point Cardinality                */
                    XPointCardinality = atoi ( msgchar );
                    SetXLevelGadget ( TMData );
                    break;
         case 'Y' : /* Set Y Point Cardinality                */
                    YPointCardinality = atoi ( msgchar );
                    SetYLevelGadget ( TMData );
                    break;
         case 'V' : /* Return Version Number to Calling Prog. */
                    TMData->ARexxResult     = VSTRING;
                    TMData->ARexxErrorLevel = 0;
                    break;
         default  : /* unknown command                        */
                    TMData->ARexxError      = "Unknown command";
                    TMData->ARexxErrorLevel = 20;
                    break; /* Safety */
       } /* end switch */
     } /* endif */

  return ( done );
}

BOOL UserSignal(struct TMData *TMData, ULONG signal)
{
  return ( FALSE );
}
