/* include this file if you need standard command line parsing like unix */
#ifdef __cplusplus

#include <fstream.h>
#include <iostream.h>
extern filebuf cin_fb, cout_fb, cerr_fb;

extern "C" {
#endif

#define timeval _timeval
#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <dos/exall.h>
#include <dos/rdargs.h>
#include <clib/alib_protos.h>
#include <graphics/gfxbase.h>
#include <inline/stubs.h>
#ifdef __OPTIMIZE__
#include <inline/exec.h>
#include <inline/dos.h>
#else
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#endif
#undef timeval


void destroy_argc_argv(void);
BOOL build_argc_argv(int orig_d0, char *orig_a0, int *argc, char **argv[]);
int _X__main(int argc, char *argv[]);

struct Library *IconBase;
struct Library *CxBase;
struct Library *MathTransBase;
struct Library *MathBase;
struct Library *MathIeeeDoubBasBase;
struct Library *MathIeeeDoubTransBase;
struct Library *UtilityBase;

#ifdef stdin
#undef stdin
#endif
#ifdef stdout
#undef stdout
#endif
extern BPTR stdin;
extern BPTR stdout;

extern UBYTE *__default_wb_window;

#ifdef NEED_STDOUT
BOOL	start_from_wb=FALSE;
#endif

inline BOOL OpenLibs(void)
{
	if(IconBase = OpenLibrary((STRPTR)"icon.library",37))
	{
		if(CxBase = OpenLibrary((STRPTR)"commodities.library",37))
		{
			if(MathBase = OpenLibrary((STRPTR)"mathffp.library",0L))
			{
				if(MathTransBase = OpenLibrary((STRPTR)"mathtrans.library",0L))
				{
					if(MathIeeeDoubTransBase = OpenLibrary((STRPTR)"mathieeedoubtrans.library",0L))
					{
						if(MathIeeeDoubBasBase = OpenLibrary((STRPTR)"mathieeedoubbas.library",0L))
						{
							if(UtilityBase = OpenLibrary((STRPTR)"utility.library",0L))
							{
								return TRUE;
							}
						}
					}
				}
			}
		}
	}

	return FALSE;
}



inline void CloseLibs(void)
{
	struct Library *lib;

	if(MathBase) 				{ lib=(struct Library *)MathBase;				CloseLibrary(lib); }

	if(MathTransBase)			{ lib=(struct Library *)MathTransBase;	 		CloseLibrary(lib); }

	if(MathIeeeDoubBasBase) 	{ lib=(struct Library *)MathIeeeDoubBasBase;	CloseLibrary(lib); }

	if(MathIeeeDoubTransBase)	{ lib=(struct Library *)MathIeeeDoubTransBase;	CloseLibrary(lib); }

	if(UtilityBase)	            { lib=(struct Library *)UtilityBase;	        CloseLibrary(lib); }

	if(CxBase)					{ lib=(struct Library *)CxBase;			        CloseLibrary(lib); }

	if(IconBase)				{ lib=(struct Library *)IconBase;		        CloseLibrary(lib); }
}

int main(int alen, char *aptr)
{
	int return_status;
	int argc;
	char **argv;

	if(OpenLibs())
	{
		if(build_argc_argv(alen,aptr,&argc,&argv))
		{
#ifdef		NEED_STDOUT
			if(stdout==0L)
			{
				start_from_wb=TRUE;
				if(__default_wb_window)
					stdin=Open(__default_wb_window, MODE_NEWFILE);

				if(!stdin)
					stdin=(BPTR)Open((STRPTR)ArgString((UBYTE **)argv,(STRPTR)"WINDOW", (STRPTR) "CON:0/0/640/200/Default Window/AUTO/CLOSE/WAIT"),MODE_NEWFILE);
				stdout=stdin;
				SelectInput(stdin);
				SelectOutput(stdout);

#ifdef __cplusplus
				cin_fb.close();
				cin_fb.attach((int)stdin);
				cout_fb.close();
				cout_fb.attach((int)stdout);
				cerr_fb.close();
				cerr_fb.attach((int)stdout);

			   	cin_fb._flags2 |=_DO_NOT_CALL_SYSCLOSE;
			   	cout_fb._flags2 |=_DO_NOT_CALL_SYSCLOSE;
			   	cerr_fb._flags2 |=_DO_NOT_CALL_SYSCLOSE;
#endif
			}
#endif

			return_status=_X__main(argc,argv);

#ifdef		NEED_STDOUT
			if(start_from_wb==TRUE)
			{
				Close(stdin);

				stdin=0;
				stdout=0;
				SelectInput(0);
				SelectOutput(0);

#ifdef __cplusplus
				cin_fb.close();
				cout_fb.close();
				cerr_fb.close();
#endif
			}
#endif

			destroy_argc_argv();
		}
		else
			return_status=RETURN_FAIL;

		CloseLibs();
	}
	else return(20);

	return return_status;
}

#define main _X__main

#ifdef __cplusplus
}
#endif
