///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Contains error-related code.
 *	\file		IceError.h
 *	\author		Pierre Terdiman
 *	\date		April, 4, 2000
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef __ICEERROR_H__
#define __ICEERROR_H__

	//! Request handler
	typedef bool (*REQUEST_CALLBACK) (const char* request, const char* requestcode, udword userdata, udword& response);

	ICECORE_API	void		SetRequestCallback(REQUEST_CALLBACK callback);
	ICECORE_API	void		SetRequestUserData(udword userdata);
	ICECORE_API bool		Request(const char* request, const char* requestcode, udword& response);









	//! Error handler
	typedef void (*ERROR_CALLBACK) (const char* error, const char* errorcode, bool updatelog, udword userdata);

	ICECORE_API	void		SetErrorCallback(ERROR_CALLBACK callback);
	ICECORE_API	void		SetErrorUserData(udword userdata);

	// Error structure
	class ICECORE_API IceError
	{
		public:
		// Constructor/Destructor
									IceError();
									~IceError();

						String		mErrorText;			//!< A string describing the last error
						String		mErrorCode;			//!< A possible error code
						udword		mErrorTimeStamp;	//!< A timestamp for the last error
	};

	ICECORE_API void		SetIceError(const char* error, const char* errorcode=null, bool updatelog=true);
	ICECORE_API IceError*	GetLastIceError();

	ICECORE_API	bool		GetError(IceError& error);
	ICECORE_API	udword		FlushErrors(CustomArray* log=null);

	#define	LASTERRORTEXT	GetLastIceError()->mErrorText							//!< Laziness...
	#define	LASTERRORCODE	GetLastIceError()->mErrorCode							//!< Laziness...


	// Following macros mimic the exception mechanism, without needing exception support (useful on Dreamcast).
	// Standard usage:
	//
	//	ICE_TRY		Subroutine
	//	ICE_CATCH	MessageBox(null, LASTERRORTEXT, "Oops", MB_OK);
	//
	// That's what I call "ICEptions" ...!
	//
	#define	ICE_TRY			udword __RDTSEC = GetLastIceError()->mErrorTimeStamp;	//!< Read time stamp error counter
	#define ICE_CATCH		if(GetLastIceError()->mErrorTimeStamp!=__RDTSEC)		//!< Compare to previous counter

#endif // __ICEERROR_H__
