/************************************************************************/
/*! \class RtError
\brief Exception handling class for RtAudio & RtMidi.

The RtError class is quite simple but it does allow errors to be
"caught" by RtError::Type. See the RtAudio and RtMidi
documentation to know which methods can throw an RtError.

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

#ifndef RTERROR_H
#define RTERROR_H

#include <exception>
#include <iostream>
#include <string>

class RtError : public std::exception
{
public:
	//! Defined RtError types.
	enum Type
	{
		WARNING,           /*!< A non-critical error. */
		DEBUG_WARNING,     /*!< A non-critical error which might be useful for debugging. */
		UNSPECIFIED,       /*!< The default, unspecified error type. */
		NO_DEVICES_FOUND,  /*!< No devices found on system. */
		INVALID_DEVICE,    /*!< An invalid device ID was specified. */
		MEMORY_ERROR,      /*!< An error occured during memory allocation. */
		INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */
		INVALID_USE,       /*!< The function was called incorrectly. */
		DRIVER_ERROR,      /*!< A system driver error occured. */
		SYSTEM_ERROR,      /*!< A system error occured. */
		THREAD_ERROR       /*!< A thread error occured. */
	};

	//! The constructor.
	RtError(const std::string& message, Type type = RtError::UNSPECIFIED) throw() : message_(message), type_(type) {}

	//! The destructor.
	virtual ~RtError(void) throw() {}

	//! Prints thrown error message to stderr.
	virtual void printMessage(void) const throw() { std::cerr << '\n'
															  << message_ << "\n\n"; }

	//! Returns the thrown error message type.
	virtual const Type& getType(void) const throw() { return type_; }

	//! Returns the thrown error message string.
	virtual const std::string& getMessage(void) const throw() { return message_; }

	//! Returns the thrown error message as a c-style string.
	virtual const char* what(void) const throw() { return message_.c_str(); }

protected:
	std::string message_;
	Type type_;
};

#endif