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

#include <Graphics/Light/GlobalLight.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * ディレクショナルライト
 */
class DirectionalLight : public GlobalLight{
friend class LightManager;
public:
	//--------------------------------------------------------------------------
	/**
	 * コピー
	 * @param copyMask コピーマスク
	 * @return コピーされたシーンリーフ
	 */
	virtual SceneLeaf* copy(u_int copyMask = 0) const{
		return copyDirectionalLight();
	}

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

	/**
	 * ディレクショナルライトのコピー
	 * @return コピーされたモデル
	 */
	virtual DirectionalLight* copyDirectionalLight() 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 direction ライトの方向
	 */
	virtual void setDirection(const Vector3& direction){
		direction_ = direction;
		// 正規化しておく
		direction_.normalize();
	}

	/**
	 * ライトの方向取得
	 * @return ライトの方向
	 */
	virtual const Vector3& getDirection() const{ return direction_; }

	/**
	 * ライトのワールド方向取得
	 * @return ライトのワールド方向
	 */
	virtual const Vector3& getWorldDirection() const{
		Assert(getParent() != NULL);
		return worldDirection_;
	}

	//--------------------------------------------------------------------------
	/**
	 * ディレクショナルライトかどうか
	 * @return ディレクショナルライトならtrue
	 */
	virtual bool isDirectionalLight() const{ return true; }

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

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

	//--------------------------------------------------------------------------
	/**
	 * 走査
	 * @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 direction_;
	// ワールド方向
	Vector3 worldDirection_;

};

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

