/****************************************************************************
*
* $RCSfile: ArgParser.c $
* $Revision: 1.1 $
* $Date: 1997/09/13 11:25:02 $
* $Author: ssolie $
*
*****************************************************************************
*
* Copyright (c) 1997 Software Evolution.  All Rights Reserved.
*
*****************************************************************************
*
* ArgParser.c -- ArgParser class source file
*
* This file contains the source code for ArgParser objects.
*/

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

#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/icon.h>

#include "ArgParser.h"
#include "Debug.h"


/*** Global variables ***/
IMPORT struct ExecBase		*SysBase;
IMPORT struct DosLibrary	*DOSBase;
IMPORT struct Library		*IconBase;


/*** Local constants ***/
const STRPTR YES_STR	= "YES";	/* tooltype true values */
const STRPTR NO_STR		= "NO";		/* tooltype false values */


/*** Local data types ***/
typedef enum { SHELL=1, WORKBENCH } INTERFACE;

struct ArgParserClass {
	INTERFACE interface;			/* which interface to parse */

	struct RDArgs *rdargs;			/* read args handle */
	STRPTR template;				/* shell argument template */
	LONG results[MAX_TEMPLATE_ITEMS];	/* argument results */

	struct WBStartup *wbstartup;	/* workbench startup message */
	BPTR old_lock;					/* original directory lock */
	struct DiskObject *disk_obj;	/* disk object pointer */
	STRPTR *tooltypes;				/* icon tool types array */
};


/*
 * newArgParser -- Create ArgParser object
 *
 * This function creates a new ArgParser and sets up the parsing mechanism
 * based on which interface is to be parsed.  Returns a reference to an
 * ArgParser object if successful or NULL on error.
 *
 * NOTE:
 *	This function should probably be split into two functions.
 *	One function for each interface (Shell or Workbench).
 */
ArgParser newArgParser(STRPTR template, struct WBStartup *wbstartup)
{
	ArgParser this;

	D(bug("newArgParser(%s, %08lx)\n", template, wbstartup));

	if ( template == NULL && wbstartup == NULL )
		return(NULL);

	this = AllocVec(sizeof(struct ArgParserClass), MEMF_CLEAR);
	if ( this == NULL )
		return(NULL);

	if ( wbstartup == NULL )  {
		this->interface = SHELL;
		this->template = template;

		this->rdargs = ReadArgs(template, this->results, NULL);
		if ( this->rdargs == NULL )  {
			deleteArgParser(this);
			return(NULL);
		}
	}
	else  {
		this->interface = WORKBENCH;
		this->wbstartup = wbstartup;

		this->old_lock = CurrentDir(wbstartup->sm_ArgList[0].wa_Lock);

		this->disk_obj = GetDiskObjectNew(wbstartup->sm_ArgList[0].wa_Name);
		if ( this->disk_obj == NULL )  {
			deleteArgParser(this);
			return(NULL);
		}

		this->tooltypes = this->disk_obj->do_ToolTypes;
	}

	return(this);
}


/*
 * deleteArgParser -- Delete ArgParser object
 *
 * Deletes an ArgParser object and frees all its resources.
 */
VOID deleteArgParser(ArgParser this)
{
	D(bug("deleteArgParser(%08lx)\n", this));

	if ( this == NULL )
		return;

	FreeArgs(this->rdargs);

	if ( this->disk_obj != NULL )
		FreeDiskObject(this->disk_obj);

	if ( this->interface == WORKBENCH )
		CurrentDir(this->old_lock);

	FreeVec(this);
}


/*
 * getArgParserStr -- Get string argument value
 *
 * Gets the string value associated with the given argument.  If any error
 * occurs or the argument is not found, the default is returned.  Otherwise,
 * the actual string pointer will be returned.
 */
STRPTR getArgParserStr(ArgParser this, STRPTR arg, STRPTR def)
{
	STRPTR value;
	STRPTR string;
	LONG i;

	D(bug("getArgParserStr(%08lx, %s, %s)\n", this, arg, def));

	if ( this == NULL || arg == NULL )
		return(def);

	value = def;

	if ( this->interface == SHELL )  {
		i = FindArg(this->template, arg);
		if ( i >= 0 && this->results[i] != NULL )
			value = (STRPTR)this->results[i];
	}
	else  {
		string = FindToolType(this->tooltypes, arg);
		if ( string != NULL )
			value = string;
	}

	return(value);
}


/*
 * getArgParserInt -- Get integer argument value
 *
 * Gets the integer value associated with the given argument.  If any error
 * occurs or the argument is not found, the default is returned.  Otherwise,
 * the actual integer will be returned.
 */
LONG getArgParserInt(ArgParser this, STRPTR arg, LONG def)
{
	STRPTR string;
	LONG i, integer;
	LONG value;

	D(bug("getArgParserInt(%08lx, %s, %ld)\n", this, arg, def));

	if ( this == NULL || arg == NULL )
		return(def);

	value = def;

	if ( this->interface == SHELL )  {
		i = FindArg(this->template, arg);
		if ( i >= 0 && this->results[i] != NULL )
			value = *((LONG*)this->results[i]);
	}
	else  {
		string = FindToolType(this->tooltypes, arg);
		if ( string != NULL && StrToLong(string, &integer) > 0 )
			value = integer;
	}

	return(value);
}


/*
 * getArgParserBool -- Get boolean argument value
 *
 * Gets the boolean value associated with the given argument.  A true value
 * can either be "TRUE" or "YES".  A false value is either "FALSE" or "NO".
 * If any error occurs or the argument is not found, the default is returned.
 * Otherwise the actual boolean value will be returned.
 */
BOOL getArgParserBool(ArgParser this, STRPTR arg, BOOL def)
{
	STRPTR string;
	LONG i;
	BOOL value;

	D(bug("getArgParserBool(%08lx, %s, %ld)\n", this, arg, def));

	if ( this == NULL || arg == NULL )
		return(def);

	value = def;

	if ( this->interface == SHELL )  {
		i = FindArg(this->template, arg);
		if ( i >= 0 && this->results[i] != NULL )
			value = TRUE;
	}
	else  {
		string = FindToolType(this->tooltypes, arg);
		if ( string != NULL )  {
			if ( MatchToolValue(string, YES_STR) == TRUE )
				value = TRUE;
			else if ( MatchToolValue(string, NO_STR) == TRUE )
				value = FALSE;
		}
	}

	return(value);
}
