/* -*- C++ -*- */
#ifndef __exceptions_header_file__
#define __exceptions_header_file__
#include <exception>
#include "types.h"
namespace fft
{
	/**
	 * Base class for all exception classes.
	 */
	class BaseException : public std::exception
	{
	public:

		/**
		 * Constructor for generating error message. Creates message based
		 * on fmt and possible addition arguments.
		 * 
		 * @param fmt Formating string, same as for printf
		 */
		BaseException(const char* fmt, ...) throw();

		/**
		 * Copy constructor. Creates new BaseException object using data from
		 * src object.
		 * 
		 * @param src Source object
		 */
		BaseException(const BaseException& src);

		/**
		 * Copy operator. Copies new date from rhs object and frees the olde one.
		 * 
		 * @param rhs Right hand side operand of assign operator.
		 * @return Reference to self
		 */
		BaseException& operator=(const BaseException& rhs);

		/**
		 * Exception destructor. Frees message memory.
		 */
		virtual ~BaseException() throw();

		/** 
		 * Returns a C-style character string describing the general cause
		 * of the current error.  
		 * 
		 * @return Exception message
		 */
		virtual const char * what() const throw()
		{
			return const_cast<const char*>(message);
		}
	protected:

		/**
		 * Message describing raised exception.
		 */
		char* message;
	};

	/**
	 * Class containing information about out-of-range exception.
	 */
	class OutOfRangeException : public BaseException
	{
	public:
		/**
		 * Basic constructor of OutOfRangeException object.
		 * 
		 * @param rgMin minimal value of range.
		 * @param rgMax maximal value of range.
		 * @param curVal value, that gets out of defined range.
		 */
		OutOfRangeException(u32 rgMin, u32 rgMax, u32 curVal);

		/**
		 * Copy constructor. Creates new OutOfRangeException object using data from
		 * src object.
		 * 
		 * @param src Source object
		 */
		OutOfRangeException(const OutOfRangeException& src);

		/**
		 * Copy operator. Copies new date from rhs object and frees the olde one.
		 * 
		 * @param rhs Right hand side operand of assign operator.
		 * @return Reference to self
		 */
		OutOfRangeException& operator= (const OutOfRangeException& rhs);

		/**
		 * Gets value of minimal range.
		 * @return value of minimal range.
		 */
		u32 getRangeMin() const 
		{
			return rangeMin;
		}

		/**
		 * Gets value of minimal range.
		 * @return value of minimal range.
		 */
		u32 getRangeMax() const 
		{
			return rangeMax;
		}

		/**
		 * Gets value, that gets out of range and causes this exception.
		 * @return value that gets out of defined range.
		 */
		u32 getCurrentVal() const 
		{
			return currentVal;
		}

	protected:

		/**
		 * Minimal value of range
		 */
		u32 rangeMin;

		/**
		 * Maximal value of range
		 */
		u32 rangeMax;

		/**
		 * Value that gets out of definied range.
		 */
		u32 currentVal;
	};

	class FileNotFoundException : public BaseException
	{
	public:
		FileNotFoundException(const char* file);

		/**
		 * Copy constructor. Creates new FileNotFoundException object using data from
		 * src object.
		 * 
		 * @param src Source object
		 */
		FileNotFoundException(const FileNotFoundException& src);

		/**
		 * Copy operator. Copies new date from rhs object and frees the olde one.
		 * 
		 * @param rhs Right hand side operand of assign operator.
		 * @return Reference to self
		 */
		FileNotFoundException& operator= (const FileNotFoundException& rhs);

		const char* getFileName() const
		{
			return fileName;
		}
	private:
		const char* fileName;
	};

	class InvalidOperationException : public BaseException
	{
	public:
		InvalidOperationException(const char* desc) : BaseException("Invalid Operation: %s", desc)
		{}
	};
}

#endif //__exceptions_header_file__

