//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * フォグヘッダ
 * @author Junpee
 */

#ifndef FOG_H_
#define FOG_H_

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * フォグ
 */
class Fog{
friend class Scene;
public:
	/// モード
	enum Mode{
		/// 線形フォグ
		modeLinear = 0,
		/// 指数フォグ
		modeExponent,
		/// 二乗の指数フォグ
		modeExponent2
	};

	//--------------------------------------------------------------------------
	/**
	 * 限界値の取得
	 * @return 限界値
	 */
	virtual float getLimit();

	//--------------------------------------------------------------------------
	/**
	 * 有効、無効の設定
	 * @param enabled trueなら有効、falseなら無効
	 */
	virtual void setEnabled(bool enabled){ enabled_ = enabled; }

	/**
	 * 有効、無効の取得
	 * @return trueなら有効、falseなら無効
	 */
	virtual bool isEnabled() const{ return enabled_; }

	//--------------------------------------------------------------------------
	/**
	 * 色の設定
	 * @param color 色
	 */
	virtual void setColor(const Color4c& color){
		Assert(color.a == 0);
		color_ = color;
	}

	/**
	 * 色の取得
	 * @return 色
	 */
	virtual const Color4c& getColor() const{ return color_; }

	//--------------------------------------------------------------------------
	/**
	 * モードの設定
	 * @param mode モード
	 */
	virtual void setMode(Mode mode){ mode_ = mode; }

	/**
	 * モードの取得
	 * @return モード
	 */
	virtual Mode getMode() const{ return mode_; }

	/**
	 * モード文字列の設定
	 * @param mode モード文字列
	 */
	virtual void setModeString(const String& mode){
		if(mode == "linear"){
			mode_ = modeLinear;
		}else if(mode == "exponent"){
			mode_ = modeExponent;
		}else if(mode == "exponent2"){
			mode_ = modeExponent2;
		}else{
			ErrorOut("Fog::setModeString() "
				"Unknown fog mode " + mode);
		}
	}

	/**
	 * モード文字列の取得
	 * @return モード文字列
	 */
	virtual String getModeString() const{
		if(mode_ == modeLinear){
			return "linear";
		}else if(mode_ == modeExponent){
			return "exponent";
		}else if(mode_ == modeExponent2){
			return "exponent2";
		}
		return "";
	}

	//--------------------------------------------------------------------------
	/**
	 * 濃度の設定
	 *
	 * モードがmodeExponent、modeExponent2の時に使用されます
	 * @param density 濃度
	 */
	virtual void setDensity(float density){
		Assert(density >= 0.f);
		Assert(density <= 1.f);
		density_ = density;
	}

	/**
	 * 濃度の取得
	 *
	 * モードがmodeExponent、modeExponent2の時に使用されます
	 * @return 濃度
	 */
	virtual float getDensity() const{ return density_; }

	//--------------------------------------------------------------------------
	/**
	 * ニアの設定
	 *
	 * モードがmodeLifogNearの時に使用されます
	 * @param fogNear ニア
	 */
	virtual void setNear(float fogNear){
		Assert(fogNear >= 0.f);
		fogNear_ = fogNear;
	}

	/**
	 * ニアの取得
	 *
	 * モードがmodeLifogNearの時に使用されます
	 * @return ニア
	 */
	virtual float getNear() const{ return fogNear_; }

	//--------------------------------------------------------------------------
	/**
	 * ファーの設定
	 *
	 * モードがmodeLifogNearの時に使用されます
	 * @param fogFar ファー
	 */
	virtual void setFar(float fogFar){
		Assert(fogFar >= 0.f);
		fogFar_ = fogFar;
	}

	/**
	 * ファーの取得
	 *
	 * モードがmodeLifogNearの時に使用されます
	 * @return ファー
	 */
	virtual float getFar() const{ return fogFar_; }

	//--------------------------------------------------------------------------
protected:
	/**
	 * コンストラクタ
	 */
	Fog();

	/**
	 * デストラクタ
	 */
	virtual ~Fog();

	//--------------------------------------------------------------------------
private:
	// コピーコンストラクタの隠蔽
	Fog(const Fog& copy);

	// 代入コピーの隠蔽
	void operator =(const Fog& copy);

	// 色
	Color4c color_;
	// モード
	Mode mode_;
	// 濃度
	float density_;
	// ニア
	float fogNear_;
	// ファー
	float fogFar_;
	// 有効、無効
	bool enabled_;
	// リミット値
	static const float limitValue;
	// 指数ドロップオフリミット係数
	static const float exponentLimit;
	// 二乗の指数ドロップオフリミット係数
	static const float exponent2Limit;

};

//------------------------------------------------------------------------------
} // End of namespace Lamp
#endif // End of FOG_H_
//------------------------------------------------------------------------------
