#include <classes/DOS/Arguments.h>

#include <exec/memory.h>

#pragma -
#include <pragma/exec_lib.h>
#include <pragma/dos_lib.h>
#pragma +

ArgsC::ArgsC(STRPTR argTemplate, struct RDArgs *rdargs)
{
	args = NULL;
	argarray = NULL;
	templ = NULL;
	read(argTemplate, rdargs);
}

ArgsC::ArgsC(STRPTR argTemplate, RDArgsC &rdargs)
{
	args = NULL;
	argarray = NULL;
	templ = NULL;
	read(argTemplate, rdargs.object());
}

ArgsC::ArgsC(const ArgsC &s)
{
	args = NULL;
	argarray = NULL;
	templ = NULL;
	read(s.templ, s.args);
}

ArgsC::~ArgsC()
{
	free();
}

ArgsC &ArgsC::operator= (const ArgsC &s)
{
	if (this != &s)
	{
		free();
		args = NULL;
		argarray = NULL;
		templ = NULL;
		read(s.templ, s.args);
	};
	return *this;
}

VOID ArgsC::read(STRPTR argTemplate, struct RDArgs *rdargs)
{
	free();
	templ = argTemplate;
	if (argTemplate)
	{
		STRPTR t = argTemplate;
		argcount = 1;
		while (*t != '\0')
		{
			if (*t == ',')
				argcount++;
			t++;
		};
		if (argarray = (ULONG *) AllocMem(argcount*4,MEMF_CLEAR))
		{
			args = ReadArgs(argTemplate,(LONG *) argarray,rdargs);
			if (!args)
				throw RDArgsX();
		}
		else
			throw MemoryX(argcount*4);
	};
}

VOID ArgsC::free()
{
	if (args)
	{
		FreeArgs(args);
		args = NULL;
	};
	if (argarray)
	{
		FreeMem(argarray,argcount*4);
		argarray = NULL;
	};
}

STRPTR ArgsC::getStr(LONG i, STRPTR dfault) const
{
	if (((ULONG) i) < argcount && argarray)
	{
		if ((STRPTR) argarray[i])
			return (STRPTR) argarray[i];
	};
	return dfault;
}

STRPTR ArgsC::getStr(STRPTR keyword, STRPTR dfault) const
{
	if (keyword && templ && argarray)
	{
		LONG i = FindArg(templ,keyword);
		if (i >= 0 && (STRPTR) argarray[i])
			return (STRPTR) argarray[i];
	};
	return dfault;
}

LONG ArgsC::getNumber(LONG i, LONG dfault) const
{
	if (((ULONG) i) < argcount && argarray)
	{
		if ((LONG *) argarray[i])
			return *((LONG *) argarray[i]);
	};
	return dfault;
}

LONG ArgsC::getNumber(STRPTR keyword, LONG dfault) const
{
	if (keyword && templ && argarray)
	{
		LONG i = FindArg(templ,keyword);
		if (i >= 0 && (LONG *) argarray[i])
			return *((LONG *) argarray[i]);
	};
	return dfault;
}

BOOL ArgsC::getSwitch(LONG i) const
{
	if (((ULONG) i) < argcount && argarray)
	{
		return (BOOL) argarray[i];
	};
	return FALSE;
}

BOOL ArgsC::getSwitch(STRPTR keyword) const
{
	if (keyword && templ && argarray)
	{
		LONG i = FindArg(templ,keyword);
		if (i >= 0)
			return (BOOL) argarray[i];
	};
	return FALSE;
}

// *************************************************************

ArgsMCursorC::ArgsMCursorC(ArgsC &args, LONG i)
{
	marg = NULL;
	if (((ULONG) i) < args.argcount && args.argarray)
	{
		marg = (ULONG *) args.argarray[i];
	};
	first();
}

ArgsMCursorC::ArgsMCursorC(ArgsC &args, STRPTR keyword)
{
	marg = NULL;
	if (keyword && args.templ && args.argarray)
	{
		LONG i = FindArg(args.templ,keyword);
		if (i >= 0)
		{
			marg = (ULONG *) args.argarray[i];
		};
	};
	first();
}

ArgsMCursorC::ArgsMCursorC(const ArgsMCursorC &s)
{
	marg = s.marg;
	first();
}

ArgsMCursorC &ArgsMCursorC::operator= (const ArgsMCursorC &s)
{
	if (this != &s)
	{
		marg = s.marg;
		first();
	};
	return *this;
}

ULONG ArgsMCursorC::count() const
{
	ULONG *a = marg;
	ULONG c = 0;
	if (!a)
		return 0;
	while (*a) {
		a++;
		c++;
	};
	return c;
}

VOID ArgsMCursorC::first()
{
	arg = marg;
};

BOOL ArgsMCursorC::isDone() const
{
	return arg ? *arg == 0 : TRUE;
}

VOID ArgsMCursorC::next()
{
	if (!isDone())
		arg++;
}

STRPTR ArgsMCursorC::itemStr() const
{
	return isDone() ? NULL : (STRPTR) *arg;
}

LONG ArgsMCursorC::itemNumber() const
{
	return isDone() ? 0 : *((LONG *) *arg);
}

