#if !defined (EXCEPTIONS_H)
#define EXCEPTIONS_H

#include <stdio.h>

#ifdef _VXWORKS_
//#include "tasklib.h"
#include "osutils.h"
#else
#include <string.h>
#include <malloc.h>
#endif

typedef enum
{
	NULL_ARG,
	SPAWN_FAILURE,
	MEM_ALLOC_FAILURE
}exceptionIds;

/*---------------------------------------------------------------
CLASS Exception
    
AUTHOR
  D.Cline. Copyright MBARI 1998.  
-----------------------------------------------------------------*/
class Exception
{
public:
	// Initializes exception type. This is generally just an
	// enumerated or #defined integer id
	Exception(int type, const char *msg = 0):
	_type(type),
	_msg(0)
	{ 
		if(msg != 0)
		_msg = (char *)strdup(msg);
	};		
	virtual ~Exception(){
		if(_msg != 0)
		free((void *)_msg);
	};
	virtual const char *msg(){return _msg;};
	int type(){return _type;};

private:	
    int _type;
	const char *_msg;
};

class SingletonException
{
private:
	SingletonException();

public:
	static SingletonException* instance();
	~SingletonException();
	// Sets exception type
	static void set(Exception *e);
	// Returns exception type
	static int isa(Exception &e);
	static Exception* get();

private:
	
	static SingletonException *_pInstance;
	static Exception *_exception;
};

/*---------------------------------------------------------------
CLASS 
	NullArg

DESCRIPTION
	Null argument exception. Run-time exception thrown when a 
	function had a null argument passed in.
-----------------------------------------------------------------*/
class NullArg : public Exception {
public:		
	NullArg(int argIndex = 0)
		: Exception (NULL_ARG)
	{
		sprintf(_msg, "Null argument no. %d", argIndex);
	};
	virtual ~NullArg(){};
	virtual const char *msg(){return _msg;};
private:
	char _msg[80];
};
/*---------------------------------------------------------------
CLASS 
	MemAllocFailure

DESCRIPTION
	Memory allocation error. Run-time exception thrown when a 
	new or malloc fails
-----------------------------------------------------------------*/
class MemAllocFailure : public Exception {
public:		
	MemAllocFailure(const char *message = "Memory alloc failure")
		: Exception (MEM_ALLOC_FAILURE){_msg = (char *)strdup(message);};
	virtual ~MemAllocFailure(){free((void *)_msg);};
	const char *msg(){return _msg;};
private:
	const char *_msg;
};

/*---------------------------------------------------------------
CLASS 
	SpawnFailure

DESCRIPTION
	Task spawn failure exception. Run-time exception thrown when a 
	task failed to spawn.
-----------------------------------------------------------------*/
class SpawnFailure : public Exception {
public:
	SpawnFailure(const char *spawnedTaskName = "TaskFailure")
		: Exception (SPAWN_FAILURE)
	{_taskName = (char *)strdup(spawnedTaskName);};
	virtual ~SpawnFailure(){free((void *)_taskName);}
	virtual const char *msg(){return _taskName;};
private:
	const char *_taskName;
};
#ifdef HAS_NO_EXCEPTIONS

# define _THROW(EXCEPTION) \
    do \
      { \
	SingletonException::set(new EXCEPTION); \
        return; \
      } while (0) 

# define _TRY \
	do { \
	     do {

# define _ENDTRY \
	  } while (0); \
		} while (0) 

# define _CATCH(EXCEPTION,E) \
	} while (0); \
    do \
	if (SingletonException::get () && SingletonException::isa(E) ) \
	{ \
		Exception &E = *SingletonException::get();

# else /* Has exceptions */
# define _TRY_ try
# define _THROW_(EXCEPTION) throw (EXCEPTION)
# define _CATCH_(EXCEPTION,VAR) catch (EXCEPTION & VAR) 
# define _ENDTRY_
#endif

#endif /* EXCEPTIONS_H */
