/**
 * @file Exception.h
 * @brief 例外の定義を行う.
 * @author S.F.
 * @version $Id:
 *
 * Copyright (C) 2000-2002 Satoshi Fujiwara. All Rights Reserved.
 */

/// 重複インクルード防止マクロ
#if !defined(AFX_EXCEPTION_H__F0B6B43A_53BE_4C53_AB43_D64FED220C3B__INCLUDED_)
#define AFX_EXCEPTION_H__F0B6B43A_53BE_4C53_AB43_D64FED220C3B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "sf.h"
#include <string>
#include <strstream>
#include "boost/format.hpp"
extern "C" {
namespace sf {
	namespace system {
/// 例外 
class  Exception {
	public:
	/// エラーの種類
	enum ERROR_TYPE{
		DEFAULT,///< デフォルト
		DEVICE_NOT_FOUND,///< デバイスが見つからなかった
		BUFFER_IS_FULL,///< バッファーがフル
		SCENE_IS_EMPTY///< シーンは空である
	};

	/// コンストラクタ		
	Exception::Exception()
	{
		mErrID = DEFAULT;
	};

	/** コンストラクタ 
	 * @param pValue エラー文字列
	 * @param fileName ファイルネーム
	 * @param line 行番号
	* @param err ERROR_TYPE */
	Exception(const wchar_t * const pValue,const wchar_t * const fileName,const int line,const ERROR_TYPE err = DEFAULT)
		{mErrString = pValue; mFileName = fileName;mLineNumber = line; mErrID = err;};
	/** コンストラクタ 
	 * @param value エラー文字列
	 * @param fileName ファイルネーム
	 * @param line 行番号
	 * @param err ERROR_TYPE */
	Exception(std::wstring & value,const wchar_t * const fileName,const int line,const ERROR_TYPE err = DEFAULT)
		{mErrString = value;mFileName = fileName ; mLineNumber = line; mErrID = err;};
	/// デストラクタ
	virtual ~Exception(){};
	
	/** エラー文字列を参照する.
	 * @return エラー文字列をstd::stringの参照で返します*/
	virtual std::wstring & reason(void)
	{return mErrString;};
	
	/** エラー文字列をセットする.
	 * @param value エラー文字列(std::string) */
	virtual void reason(const std::wstring& value){mErrString = value;};
	
	/** エラー文字列をセットする.
	 * @param value エラー文字列(const char *) */
	virtual void reason(const wchar_t * const pValue){mErrString = pValue;};
	
	/** エラーを起こしたファイルネームをセットする 
	 * @param pValue エラーを起こしたファイルネーム */
	virtual void sourceFileName(const wchar_t * const pValue){mFileName = pValue;};
	
	/** エラーを起こしたファイルネームを参照する 
	 * @return エラーを起こしたファイルネーム */
	virtual const std::wstring  sourceFileName(void) const {return mFileName;};

	/** エラーを起こした行番号をセットする
	 * @param value エラーを起こした行番号 */
	virtual void lineNumber(const int value){mLineNumber = value;};
	
	/** エラーを起こした行番号をセットする
	 * @param value エラーを起こした行番号 */
	virtual const int lineNumber(void){return mLineNumber;};
	
	/** ERROR_TYPEをセットする
	 * @param value ERROR_TYPE(例外の種類) */
	virtual void errorType(const ERROR_TYPE value){mErrID = value;};
	
	/** ERROR_TYPEを参照する
	 * @return ERROR_TYPE(例外の種類) */
	virtual const ERROR_TYPE errorType(void) const {return mErrID;};

	/** デフォルトエラー表示メッセージを参照する
	 * @return エラー文字列 */
	virtual const wchar_t * const Exception::getDefaultMessage(void){
		return (boost::wformat(L"%s\n%s:line%d") % reason() % sourceFileName() % lineNumber()).str().c_str();
	}// getDefaultMessage()		

private:
	std::wstring mErrString;///< エラー文字列
	std::wstring mFileName;///< エラーを起こしたファイル名
	std::wstring mDefaultMessage;///< デフォルトのメッセージ
	int mLineNumber;///< 行番号
	ERROR_TYPE mErrID;///< エラーID
};

/// 致命的な例外
class FatalErrorException : public Exception {
public:
		/** コンストラクタ 
		 * @param pValue エラー文字列
		 * @param fileName ファイルネーム
		 * @param line 行番号
		 * @param err ERROR_TYPE */
		FatalErrorException(const wchar_t * const pValue,const wchar_t * const fileName,const int line,const ERROR_TYPE err = DEFAULT)
			: Exception(pValue,fileName,line)
			{;};
		/** コンストラクタ 
		 * @param pValue エラー文字列
		 * @param fileName ファイルネーム
		 * @param line 行番号
		 * @param err ERROR_TYPE */
		FatalErrorException(std::wstring & value,const wchar_t * const fileName,const int line,const ERROR_TYPE err = DEFAULT)
			: Exception(value,fileName,line)
			{;};
};

///修復可能な例外
class RecoverbleErrorException : public Exception {
public:
		/** コンストラクタ 
		 * @param pValue エラー文字列
		 * @param fileName ファイルネーム
		 * @param line 行番号
		 * @param err ERROR_TYPE */
		RecoverbleErrorException(const wchar_t * const pValue,const wchar_t * const fileName,const int line,const ERROR_TYPE err = DEFAULT)
			: Exception(pValue,fileName,line)
			{;};
		/** コンストラクタ 
		 * @param pValue エラー文字列
		 * @param fileName ファイルネーム
		 * @param line 行番号
		 * @param err ERROR_TYPE */
		RecoverbleErrorException(std::wstring & value,const wchar_t * const fileName,const int line,const ERROR_TYPE err = DEFAULT)
			: Exception(value,fileName,line)
			{;};

};
	}// system
}// sf
}
#endif // !defined(AFX_EXCEPTION_H__F0B6B43A_53BE_4C53_AB43_D64FED220C3B__INCLUDED_)
