#ifndef CLIB_H
#define CLIB_H

#include <stdarg.h>

#define REG(x) register __## x

struct EnvArgs {
	char **ea_Argv;
	struct RDArgs *ea_EnvRDArgs;
	struct RDArgs *ea_RDArgs;
};


/* protos for tiny c.lib */

/* Private: HANDS OFF!!! */
extern long _Std_Main(void);					/* internal code */
extern long _Cli_Main(void);					/* internal code (default startup code) */
extern long _WB_Main(void);						/* internal code */
extern BOOL _ReadCliArgs(struct EnvArgs *);		/* internal code */
extern BOOL _ParseToolTypes(struct WBStartup *, struct EnvArgs *);	/* internal code */

/* Internal variables: HANDS OFF!!! */
extern BOOL (*__ReadCliArgs)(struct EnvArgs *);
extern BOOL (*__ReadEnvArgs)(char *, char *, struct EnvArgs *);
extern BOOL (*__ParseToolTypes)(struct WBStartup *, struct EnvArgs *);


/* Public */
long main(long argc, char *argv[]);						/* standard entry point   */
long Main(char *Argv[], struct WBStartup *WBenchMsg);	/* powerfull! entry point */
long _Main(void);										/* redesign by yourself!  */

BOOL AllocEnvArgs(struct EnvArgs *EnvArgs);
void FreeEnvArgs(struct EnvArgs *EnvArgs);
BOOL ReadEnvVar(char *VarName, char *Template, struct EnvArgs *ea);

long EasyReq(char *GadFmt, char *TextFmt, APTR Args);
void __stdargs SimpleReq(char *fmt, ...);

LONG VSPrintf(UBYTE *buf, UBYTE *fmt, va_list arg_ptr);
LONG __stdargs SPrintf(UBYTE *buf, UBYTE *fmt,...);

void __stdargs KPrintF(char *,...);
#define KPrintf KPrintF

// Missing pragma in pragmas/utility.h
#pragma tagcall UtilityBase CallHook 66 9A803

#define CoerceMethodA(class, object, msg)		CallHookPkt(&(class)->cl_Dispatcher, object, msg)
#define DoSuperMethodA(class, object, msg)		CoerceMethodA((class)->cl_Super, object, msg)
#define DoMethodA(object, msg)					CoerceMethodA(OCLASS(object), object, msg)


/********************************/
/* Startup Modules Declarations */
/********************************/

/*
 *	To get a standard startup code calling main(argc, argv),
 *	just put:
 *
 * StandardStartup
 *
 *	at the beginning of your program. (outside main()!)
 *	Note: the dummy 'extern' declaration is to allow a trailing ';'
 *	      after the keyword "StandardStartup".
 */

#define StandardStartup		long _Main(void) { return _Std_Main(); } extern char yMmUd

/*
 *	To get a workbench startup as well, when using Main(ArgV, WBenchMsg),
 *	just put:
 *
 * WorkbenchStartup
 *
 *	at the beginning of your program. (outside main()!)
 *	This is useless with StandardStartup.
 *	Note: the dummy 'extern' declaration is to allow a trailing ';'
 *	      after the keyword "WorkbenchStartup".
 */

#define WorkbenchStartup	long _Main(void) { return _WB_Main(); } extern char yMmUd

/*
 *	If you need cli args (Template) you MUST put
 *
 * CliArgs
 *
 *	at the beginning of your program. (outside main()!)
 *	as well as defining a Template, and an optionnal CliHelp.
 */

#define CliArgs				BOOL (*__ReadCliArgs)() = _ReadCliArgs

/*
 *	If you want your cli args to be read for an environnement
 *	variable, just put:
 *
 * ReadEnvArgs("VarName")
 *
 *	at the beginning of your program. (outside main()!)
 *	You can then store default args value in it.
 */

#define ReadEnvArgs(VarName)	char *__EnvVarName = VarName;BOOL (*__ReadEnvArgs)() = ReadEnvVar

/*
 *	Read tooltypes by examining the template and then find matching tooltypes.
 */

#define ParseToolTypes			BOOL (*__ParseToolTypes)() = _ParseToolTypes


#endif

