//------------------------------------------------------------------------------
// 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 POINT_LIHGT_H_
#define POINT_LIHGT_H_

#include <Graphics/Light/LocalLight.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * ポイントライト
 */
class PointLight : public LocalLight{
friend class LightManager;
public:
	//--------------------------------------------------------------------------
	/**
	 * コピー
	 * @param copyMask コピーマスク
	 * @return コピーされたシーンリーフ
	 */
	virtual SceneLeaf* copy(u_int copyMask = 0) const{
		return copyPointLight();
	}

	/**
	 * コピー
	 * @return コピーされたライト
	 */
	virtual Light* copyLight() const{ return copyPointLight(); }

	/**
	 * ポイントライトのコピー
	 * @return コピーされたモデル
	 */
	virtual PointLight* copyPointLight() const;

	//--------------------------------------------------------------------------
	/**
	 * ライト色の設定
	 * @param color ライト色
	 */
	virtual void setColor(const Color3f& color){
		diffuseColor_ = specularColor_ = color;
	}

	/**
	 * ライト色の取得
	 * @return ライト色
	 */
	virtual Color3f getColor() const{
		Color3f result(Math::maximum(diffuseColor_.r, specularColor_.r),
			Math::maximum(diffuseColor_.g, specularColor_.g),
			Math::maximum(diffuseColor_.b, specularColor_.b));
		return result;
	}

	//--------------------------------------------------------------------------
	/**
	 * ディフューズライト色の設定
	 * @param color ディフューズライト色
	 */
	virtual void setDiffuseColor(const Color3f& color){ diffuseColor_ = color; }

	/**
	 * ディフューズライト色の取得
	 * @return ディフューズライト色
	 */
	virtual const Color3f& getDiffuseColor() const{ return diffuseColor_; }

	//--------------------------------------------------------------------------
	/**
	 * スペキュラライト色の設定
	 * @param color スペキュラライト色
	 */
	virtual void setSpecularColor(const Color3f& color){
		specularColor_ = color;
	}

	/**
	 * スペキュラライト色の取得
	 * @return スペキュラライト色
	 */
	virtual const Color3f& getSpecularColor() const{ return specularColor_; }

	//--------------------------------------------------------------------------
	/**
	 * ライトの位置設定
	 * @param position ライトの位置
	 */
	virtual void setPosition(const Vector3& position){ position_ = position; }

	/**
	 * ライトのワールド位置取得
	 * @return ライトのワールド位置
	 */
	virtual const Vector3& getPosition() const{ return position_; }

	/**
	 * ライトのワールド位置取得
	 * @return ライトのワールド位置
	 */
	virtual const Vector3& getWorldPosition() const{
		Assert(getParent() != NULL);
		return worldPosition_;
	}

	//--------------------------------------------------------------------------
	/**
	 * レンジの設定
	 * @param range レンジ
	 */
	virtual void setRange(float range){ range_ = range; }

	/**
	 * レンジの取得
	 * @return レンジ
	 */
	virtual float getRange() const{ return range_; }

	/**
	 * グローバルレンジの取得
	 * @return グローバルレンジ
	 */
	virtual float getGlobalRange() const{ return globalRange_; }

	//--------------------------------------------------------------------------
	/**
	 * 減衰係数の設定
	 * @param attenuation0 減衰係数0
	 * @param attenuation1 減衰係数1
	 * @param attenuation2 減衰係数2
	 */
	virtual void setAttenuation(
		float attenuation0, float attenuation1, float attenuation2){
		attenuation0_ = attenuation0;
		attenuation1_ = attenuation1;
		attenuation2_ = attenuation2;
	}

	//--------------------------------------------------------------------------
	/**
	 * 減衰係数0の設定
	 * @param attenuation0 減衰係数0
	 */
	virtual void setAttenuation0(float attenuation0){
		attenuation0_ = attenuation0;
	}

	/**
	 * 減衰係数0の取得
	 * @return 減衰係数0
	 */
	virtual float getAttenuation0() const{ return attenuation0_; }

	//--------------------------------------------------------------------------
	/**
	 * 減衰係数1の設定
	 * @param attenuation1 減衰係数1
	 */
	virtual void setAttenuation1(float attenuation1){
		attenuation1_ = attenuation1;
	}

	/**
	 * 減衰係数1の取得
	 * @return 減衰係数1
	 */
	virtual float getAttenuation1() const{ return attenuation1_; }

	//--------------------------------------------------------------------------
	/**
	 * 減衰係数2の設定
	 * @param attenuation2 減衰係数2
	 */
	virtual void setAttenuation2(float attenuation2){
		attenuation2_ = attenuation2;
	}

	/**
	 * 減衰係数2の取得
	 * @return 減衰係数2
	 */
	virtual float getAttenuation2() const{ return attenuation2_; }

	//--------------------------------------------------------------------------
	/**
	 * カメラとの距離の2乗の設定
	 * @param squaredCameraDistance カメラとの距離の2乗
	 */
	virtual void setSquaredCameraDistance(float squaredCameraDistance){
		squaredCameraDistance_ = squaredCameraDistance;
	}

	/**
	 * カメラとの距離の2乗の取得
	 * @return カメラとの距離の2乗
	 */
	virtual float getSquaredCameraDistance() const{
		return squaredCameraDistance_;
	}

	//--------------------------------------------------------------------------
	/**
	 * ポイントライトかどうか
	 * @return ポイントライトならtrue
	 */
	virtual bool isPointLight() const{ return true; }

protected:
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 * @param name 名前
	 * @param scene シーン
	 */
	PointLight(const String& name, Scene* scene);

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

	//--------------------------------------------------------------------------
	/**
	 * 走査
	 * @param parentMatrix 親行列
	 * @param parentEnabled 親が有効か
	 * @param parentScaled 親がスケールを使用しているか
	 * @param parentChanged 親に変更があったか
	 */
	virtual void traverse(const Matrix34& parentMatrix, bool parentEnabled,
		bool parentScaled, bool parentChanged);

	//--------------------------------------------------------------------------
private:
	// ディフューズカラー
	Color3f diffuseColor_;
	// スペキュラカラー
	Color3f specularColor_;
	// 位置
	Vector3 position_;
	// ワールド位置
	Vector3 worldPosition_;
	// レンジ
	float range_;
	// グローバルレンジ
	float globalRange_;
	// 減衰係数0
	float attenuation0_;
	// 減衰係数1
	float attenuation1_;
	// 減衰係数2
	float attenuation2_;
	// カメラとの距離の2乗
	float squaredCameraDistance_;

};

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

