
/*
  File: include/mia/Interface_ErrorSys.h
  Description: MIA error system.
  Part of the Mantis project
  (c) 2002 Lycos Inc.

  This file is distributed for the sole purpose of allowing you to write
  software to interface with Sonique 2 and other Mantis programs. It is
  not to be modified or used for any other purpose without written
  authorization.

  If you redistribute this file, it must be in the original package
  complete with all other files provided, including the usage agreement.

  Do not remove this notice.
*/

#ifndef _INTERFACE_ERROR_SYS_H__
#define _INTERFACE_ERROR_SYS_H__

#ifdef DEBUG_INCLUDE_ORDER
#pragma message("Including " __FILE__ "\n" )
#endif

#if _MSC_VER > 1000
#pragma once
#endif


#include "typesport.h"
#include "Array.h"
#include "mgeneric.h"


#ifndef COMPILE_WITHOUT_MIA
// {cd523c80-ce41-11d3-9bf3-0090272ddf8e}
extern "C" const MID MID_ERROR_SYSTEM;		//	= { 0xcd523c80, 0xce41, 0x11d3, { 0x9b, 0xf3, 0x00, 0x90, 0x27, 0x2d, 0xdf, 0x8e } };
#endif



class MError
{
public:
	const char* Name;
	int32 Code, OrigCode;
	void* UserData;
	const char* ModuleName;
};

class MErrorModule
{
public:
	const char* Name;
	int32 Base;
	
	Array<MError*> Errors;
};

__forceinline int32 FindError(const MError* Errors, int32 Num)
{
	ASSERT(Errors[Num].Code != 0);
	return Errors[Num].Code;
}

inline int32 GetBasicError(int32 num)
{
	return -num-1;
}
inline bool IsBasicError(int32 errorcode)
{
	return (errorcode < 0 && errorcode > -0x100);
}

__forceinline int32 GetError(MError* Errors, int32 Num)
{
	return FindError(Errors, Num);
}

enum {
	ERR_BASIC_UNKNOWNERROR,
	ERR_BASIC_UNIMPLEMENTED,
	ERR_BASIC_OUTOFMEMORY,
	ERR_BASIC_NORESOURCES,
	ERR_BASIC_NOTFOUND,
	ERR_BASIC_ALREADYEXISTS,
	ERR_BASIC_OPENFORREADFAILED,
	ERR_BASIC_OPENFORWRITEFAILED,
	ERR_BASIC_INVALIDPARAMETER,
	ERR_BASIC_DISKWRITEFAILED,
	ERR_BASIC_IOERROR,
	ERR_BASIC_ALREADYINITIALIZED,
	ERR_BASIC_NOTINITIALIZED,
	ERR_BASIC_UNKNOWNVERSION,
	ERR_BASIC_UNKNOWNOBJECT,
	ERR_BASIC_INVALIDFILETYPE,
	ERR_BASIC_INVALIDRESOURCE,
	ERR_BASIC_NOTIMPLEMENTED,
	ERR_BASIC_MISSINGLIBRARY,
	ERR_BASIC_TIMEDOUT,
	ERR_BASIC_OUTOFRANGE,
	ERR_BASIC_NOTOPEN,
	ERR_BASIC_ALREADYOPEN,
	ERR_BASIC_CRASHED,
	ERR_BASIC_ACCESSDENIED,
	ERR_BASIC_INACTIVE,
	ERR_BASIC__NUM
};

#define ERR_BASIC__MODULE "Basic Errors"


inline MError* GetBasicErrors(MError* Errors)
{
	Errors[ERR_BASIC_UNKNOWNERROR].Name =		"unknown error";
	Errors[ERR_BASIC_UNIMPLEMENTED].Name =		"this functionality is unimplemented";
	Errors[ERR_BASIC_OUTOFMEMORY].Name =		"out of memory";
	Errors[ERR_BASIC_NORESOURCES].Name =		"out of system resources";
	Errors[ERR_BASIC_NOTFOUND].Name =			"not found";
	Errors[ERR_BASIC_ALREADYEXISTS].Name =		"already exists";
	Errors[ERR_BASIC_OPENFORREADFAILED].Name =	"could not read file";
	Errors[ERR_BASIC_OPENFORWRITEFAILED].Name =	"could not write to file";
	Errors[ERR_BASIC_INVALIDPARAMETER].Name =	"invalid parameter to call";
	Errors[ERR_BASIC_IOERROR].Name =			"file I.O error";
	Errors[ERR_BASIC_DISKWRITEFAILED].Name =	"disk write failed (disk full?)";
	Errors[ERR_BASIC_ALREADYINITIALIZED].Name =	"already.Name =ialized";
	Errors[ERR_BASIC_NOTINITIALIZED].Name =		"not.Name =ialized";
	Errors[ERR_BASIC_UNKNOWNVERSION].Name =		"unknown version of object requested";
	Errors[ERR_BASIC_UNKNOWNOBJECT].Name =		"unknown type of object requested";
	Errors[ERR_BASIC_INVALIDFILETYPE].Name =	"type of file specified is not correct";
	Errors[ERR_BASIC_INVALIDRESOURCE].Name =	"resource not available/found";
	Errors[ERR_BASIC_NOTIMPLEMENTED].Name =		"this function has not been implemented";
	Errors[ERR_BASIC_MISSINGLIBRARY].Name =		"a required library file can not be found";
	Errors[ERR_BASIC_TIMEDOUT].Name =			"the action took to long so it was terminated";
	Errors[ERR_BASIC_OUTOFRANGE].Name =			"a value provided was not within the allowed range";
	Errors[ERR_BASIC_NOTOPEN].Name =			"you must open first";
	Errors[ERR_BASIC_ALREADYOPEN].Name =		"you must close first";
	Errors[ERR_BASIC_CRASHED].Name =			"the component crashed";
	Errors[ERR_BASIC_ACCESSDENIED].Name =		"you do not have permission from the operating system to perform this operation";
	return Errors;
}


class LogEventCallback
{
public:
	virtual void LogEvent(int Priority, const char* Message)		= 0;
};

class MErrorSystem : public MGeneric
{
public:
	virtual const MErrorModule*		__stdcall FindModule(int32 Code) const																	= 0;
	virtual const MErrorModule*		__stdcall FindModule(const char* Name) const															= 0;
	virtual const MError*			__stdcall FindError(int32 Code, const MErrorModule* Module = (const MErrorModule*)NULL) const			= 0;
	virtual const MError*			__stdcall FindError(const char* Name, const MErrorModule* Module = (const MErrorModule*)NULL) const		= 0;
	inline  const char*				__stdcall GetErrorName(int32 Code) { const MError* Error = FindError(Code); if( Error ) return Error->Name; else return "unknown error"; }
	inline bool						__stdcall ErrorIs(int32 Error, int32 Code, const char* Module) { const MErrorModule* pModule = FindModule(Module); if( !pModule ) return false; const MError* pError = FindError(Error, pModule); return (pError && pError->OrigCode == Code); }
	virtual int32					__stdcall GetError(const MError* Errors, int32 Index) const												= 0;

	virtual int32					__stdcall RegisterErrors(MError* Errors, int32 NumErrors, const char* ModuleName = (const char*)NULL)	= 0;
	virtual int32					__stdcall UnregisterErrors(const char* ModuleName)	= 0;
/*
	virtual int32					__stdcall RegisterLogEvent(LogEventCallback* Callback) = 0;
	virtual int32					__stdcall DeregisterLogEvent(LogEventCallback* Callback) = 0;
*/
};

/*
inline int32 Log(int Priority //1-9//, const char* ModuleName, const char* Format, ...)
{
	char* Buf;
	va_list args;
	int result;

	Buf = new char[strlen(Format)+64];
	sprintf(Buf, "<%d> [%s] %s\r\n\r\n", Priority, ModuleName, Format);
	va_start(args, ModuleName);
	FILE* temp = fdopen(2, "wb");
	result = vfprintf(stdout, Buf, args);
	puts(Buf);
	fclose(temp);
	va_end(args);

	return result;
}
*/

#ifdef DEBUG_INCLUDE_ORDER
#pragma message("Done including " __FILE__ "\n" )
#endif

#endif // _INTERFACE_ERROR_SYS_H__
