//***************************************************************************
//
//								ABL.H
//
//***************************************************************************

#ifndef ABL_H
#define	ABL_H
#include<Stuff\Stuff.hpp>

#pragma warning (disable:4284)
#pragma warning (push)
#include <stlport\string>
#pragma warning (pop)

extern bool gShowScriptErrors;

#define ablREPORT(exp,Message) {if (gShowScriptErrors && !(exp)) {PAUSE((Message));}}

namespace ABL
{
	char *ablERROR(char *str);
	const int MAX_ABL_ERROR_STR = 255;
	const int ABL_DETAIL_ERROR_STRING_SIZE = 2048;

	class ABLError
	{
	protected:
		char m_ErrorString[MAX_ABL_ERROR_STR];
		char m_ErrorFile[MAX_ABL_ERROR_STR];
		static char m_DetailErrorString[ABL_DETAIL_ERROR_STRING_SIZE];
		int m_Line;
		int m_Code;

	public:
		ABLError (char *str,char *file,int line,int code)
		{
			Str_Copy (m_ErrorString,str,MAX_ABL_ERROR_STR);
			Str_Copy (m_ErrorFile,file,MAX_ABL_ERROR_STR);
			m_Line = line;
			m_Code = code;
		}
		ABLError ()
		{
			m_ErrorString[0] = 0;
			m_ErrorFile[0] = 0;
			m_Line = 0;
			m_Code = 0;
		}
		~ABLError ()
		{
		}
		const char *String (void) const
		{
			return m_ErrorString;
		}
		const char *File (void) const
		{
			return m_ErrorFile;
		}
		int Line (void) const
		{
			return m_Line;
		}
		int Code (void) const
		{
			return m_Code;
		}
		char *Details (void)
		{
			char line[25];

			Str_Copy (m_DetailErrorString," ",ABL_DETAIL_ERROR_STRING_SIZE);
			Str_Copy (m_DetailErrorString,m_ErrorFile,ABL_DETAIL_ERROR_STRING_SIZE);

			Str_Cat (m_DetailErrorString,"(",ABL_DETAIL_ERROR_STRING_SIZE);
			itoa (m_Line,line,10);
			Str_Cat (m_DetailErrorString,line,ABL_DETAIL_ERROR_STRING_SIZE);
			Str_Cat (m_DetailErrorString,")",ABL_DETAIL_ERROR_STRING_SIZE);

			Str_Cat (m_DetailErrorString,": ",ABL_DETAIL_ERROR_STRING_SIZE);
			Str_Cat (m_DetailErrorString,m_ErrorString,ABL_DETAIL_ERROR_STRING_SIZE);
			return m_DetailErrorString;
		}

		void String (const char *str)
		{
			Str_Copy (m_ErrorString,str,MAX_ABL_ERROR_STR);
		}
		void File (const char *file)
		{
			Str_Copy (m_ErrorFile,file,MAX_ABL_ERROR_STR);
		}
		void Line (const int line)
		{
			m_Line = line;
		}
		void Code (const int code)
		{
			m_Code = code;
		}

	};
}

#include "ablgen.h"
#include "ablexec.h"
#include "ablsymt.h"
#include "ablenv.h"

#ifndef ABLDBUG_H
	#include "abldbug.h"
#endif

#ifndef GAMEOS_HPP
	#include <gameos\gameos.hpp>
#endif

#ifndef STUFF_HPP
	#include <stuff\stuff.hpp>
#endif

#include "mw4headers.hpp"
#include "ai.hpp"
#include "mwobject.hpp"

namespace ABL
{
//***************************************************************************
	extern MechWarrior4::AI             *CurWarrior;


//#define	DEBUGGING

	void ABLi_init (unsigned long symTableHeapSize = 102400,
									unsigned long stackHeapSize = 40960,
									unsigned long codeHeapSize = 102400,
									unsigned long runtimeStackSize = 20480,
									unsigned long maxCodeBufferSize = 10240,
									unsigned long maxRegisteredModules = 200,
									unsigned long maxStaticVariables = 100,
									void (*callback)(char* s) = NULL,
									bool debugInfo = false,
									bool debug = false,
									bool profile = false);

	inline void SetABLExecFunction (ABLExecFunctionType func)
	{
		Check_Pointer (func);
		routineExecFunction = func;
	}

	ABLParamPtr ABLi_createParamList (long numParameters);

	void ABLi_setIntegerParam (ABLParamPtr paramList, long index, long value);

	void ABLi_setRealParam (ABLParamPtr paramList, long index, float value);

	void ABLi_deleteParamList (ABLParamPtr paramList);

	long ABLi_preProcess (char* sourceFileName,
						  ABLError *error,
						  long* numErrors = NULL,
						  long* numLinesProcessed = NULL,
						  long* numFilesProcessed = NULL,
						  bool printLines = false);

//	long ABLi_preProcessFromParams(const std::string& params, const std::string& script_suffix);

	long ABLi_loadLibrary (char* sourceFileName,
												 ABLError *error,
												 long* numErrors = NULL,
												 long* numLinesProcessed = NULL,
												 long* numFilesProcessed = NULL,
												 bool printLines = false);

	long ABLi_execute (SymTableNodePtr moduleIdPtr,
										 SymTableNodePtr functionIdPtr = NULL,
										 ABLParamPtr paramList = NULL,
										 StackItemPtr returnVal = NULL);

	long ABLi_deleteModule (SymTableNodePtr moduleIdPtr);

	ABLModulePtr ABLi_getModule (long id);

	DebuggerPtr ABLi_getDebugger (void);

void ABLi_saveEnvironment (FilePtr ablFile);

void ABLi_loadEnvironment (FilePtr ablFile, bool malloc);

	void ABLi_close (void);

	bool ABLi_enabled (void);

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

}
#endif
