#include<dos/rdargs.h>
#include<exec/libraries.h>
#include<workbench/startup.h>

#include<stdio.h>

#include<clib/dos_protos.h>
#include<clib/exec_protos.h>

#include "gui.h"
#include "idcmp.h"
#include "loadsave.h"
#include "arexx.h"

/* The library base global variables */
/* (The different style of opening libraries requires these to be initialised to NULL) */
struct Library* GfxBase = NULL;
struct Library* IntuitionBase = NULL;
struct Library* GadToolsBase = NULL;
struct Library* AslBase = NULL;
struct Library* DosBase = NULL;
struct Library* IFFBase = NULL;
struct Library* RexxSysBase = NULL;

/* Need to give prototypes for our functions */
static int  createAll(void);
static void freeAll(void);
static int  openLibs(void);
static void closeLibs(void);

/* The alternative "main()" for Workbench startup */
void wbmain(struct WBStartup*);

/* The shared starting point of our program */
static void realmain(void);

#define ARGS_TEMPLATE "DEPTH/N,PORTNAME"

enum ARGS { ARG_DEPTH, ARG_PORTNAME, NUM_ARGS };

#define DEFAULT_PORTNAME "HELLOPAINTER"
#define DEFAULT_DEPTH    (4)

/* The CLI starting point for StormC, but the general start for SAS/C */
void main(int argc, char** argv)
{
	/* argc should never be zero: SAS/C uses this to indicate WB start */
  if(argc == 0)
		wbmain((struct WBStartup*)argv);
	else
		realmain();
}

/* The WB starting point for StormC */
void wbmain(struct WBStartup* wbmsg)
{
	/* WB-specific startup could go here */
	realmain();
}

/* The start of the program */
static void realmain()
{
	if(createAll())
		handleIDCMP();
	freeAll();
}

static struct RDArgs* rdargs = NULL;

static int createAll()
{
  LONG args[NUM_ARGS];
  int i;
  /* Initialise our args to NULL */
  /* (This way we will know if an argument was specified) */
  for(i=0; i<NUM_ARGS; i++)
  	args[i] = NULL;
  if(openLibs())
	{
	  if(rdargs = ReadArgs(ARGS_TEMPLATE, args, NULL))
		{
			char* portname = (char*)(args[ARG_PORTNAME]);
	    LONG* depthptr = (LONG*)(args[ARG_DEPTH]);
  	  UBYTE depth;
			/* Use the default if an argument was not specified */
    	if(portname == NULL)
	    	portname = DEFAULT_PORTNAME;
  	  if(depthptr == NULL)
    		depth = DEFAULT_DEPTH;
	    else
  	  	depth = (UBYTE)(*depthptr);
			return createARexxPort(portname) && createArgs() && openGUI(depth,0,0,0);
		}
		else
			printf("Error: could not read arguments\n");
	}
	return FALSE;
}

static void freeAll()
{
	freeReqs();
	closeGUI();
	freeArgs();
	freeARexxPort();
	if(rdargs)
		FreeArgs(rdargs);
	closeLibs();
}

/* Try to open all the libraries -- return TRUE on success */
static int openLibs()
{
	if((GfxBase = OpenLibrary("graphics.library",37)) == NULL)
	{
		printf("Error: could not open graphics.library\n");
		return FALSE;
	}
	if((IntuitionBase = OpenLibrary("intuition.library",37)) == NULL)
	{
		printf("Error: could not open intuition.library\n");
		return FALSE;
	}
	if((GadToolsBase = OpenLibrary("gadtools.library",37)) == NULL)
	{
		printf("Error: could not open gadtools.library\n");
		return FALSE;
	}
	if((AslBase = OpenLibrary("asl.library",37)) == NULL)
	{
		printf("Error: could not open asl.library\n");
		return FALSE;
	}
	if((DosBase = OpenLibrary("dos.library",37)) == NULL)
	{
		printf("Error: could not open dos.library\n");
		return FALSE;
	}
	if((IFFBase = OpenLibrary("iff.library",23)) == NULL)
	{
		printf("Error: could not open iff.library\n");
		return FALSE;
	}
	if((RexxSysBase = OpenLibrary("rexxsyslib.library",35)) == NULL)
	{
		printf("Error: could not open rexxsyslib.library\n");
		return FALSE;
	}
  return TRUE;
}

/* Close any open library */
static void closeLibs()
{
	if(RexxSysBase)
		CloseLibrary(RexxSysBase);
	if(IFFBase)
		CloseLibrary(IFFBase);
	if(DosBase)
		CloseLibrary(DosBase);
	if(AslBase)
		CloseLibrary(AslBase);
	if(GadToolsBase)
		CloseLibrary(GadToolsBase);
	if(IntuitionBase)
		CloseLibrary(IntuitionBase);
	if(GfxBase)
		CloseLibrary(GfxBase);
}
