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

#include <Graphics/Material/Material.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * 基本マテリアル
 */
class BasicMaterial : public Material{
friend class MaterialManager;
public:
	/**
	 * 基本マテリアルかどうか
	 * @return 基本マテリアルならtrue
	 */
	virtual bool isBasicMaterial() const{ return true; }

	//--------------------------------------------------------------------------
	/**
	 * コピー
	 * @param copyMask コピーマスク
	 * @return コピーされたマテリアル
	 */
	virtual Material* copy(u_int copyMask = 0) const{
		return copyBasicMaterial(copyMask);
	}

	/**
	 * 基本マテリアルのコピー
	 * @param copyMask コピーマスク
	 * @return コピーされたマテリアル
	 */
	virtual BasicMaterial* copyBasicMaterial(u_int copyMask = 0) const;

	//--------------------------------------------------------------------------
	// 描画
	//--------------------------------------------------------------------------
	/**
	 * 描画
	 * @param request 描画リクエスト
	 */
	virtual void draw(DrawRequest* request);

	//--------------------------------------------------------------------------
	// ベーステクスチャインターフェース
	//--------------------------------------------------------------------------
	/**
	 * ベーステクスチャの設定
	 * @param baseTexture 設定するベーステクスチャ
	 */
	virtual void setBaseTexture(Texture* baseTexture){
		baseTexture_ = setTextureReferense(baseTexture_, baseTexture);
	}

	/**
	 * ベーステクスチャの取得
	 * @return ベーステクスチャ
	 */
	virtual Texture* getBaseTexture() const{ return baseTexture_; }

	/**
	 * ベーステクスチャの削除
	 */
	virtual void removeBaseTexture(){ setBaseTexture(NULL); }

	//--------------------------------------------------------------------------
	/**
	 * ベースUVインデックスの設定
	 * @param baseUVIndex ベースUVインデックス
	 */
	virtual void setBaseUVIndex(int baseUVIndex){
		Assert((baseUVIndex >= 0) && (baseUVIndex < 8));
		baseUVIndex_ = baseUVIndex;
	}

	/**
	 * ベースUVインデックスの取得
	 * @return ベースUVインデックス
	 */
	virtual int getBaseUVIndex() const{ return baseUVIndex_; }

	//--------------------------------------------------------------------------
	// 光沢テクスチャインターフェース
	//--------------------------------------------------------------------------
	/**
	 * 光沢テクスチャの設定
	 * @param glossTexture 設定する光沢テクスチャ
	 */
	virtual void setGlossTexture(Texture* glossTexture){
		glossTexture_ = setTextureReferense(glossTexture_, glossTexture);
	}

	/**
	 * 光沢テクスチャの取得
	 * @return 光沢テクスチャ
	 */
	virtual Texture* getGlossTexture() const{ return glossTexture_; }

	/**
	 * 光沢テクスチャの削除
	 */
	virtual void removeGlossTexture(){ setGlossTexture(NULL); }

	//--------------------------------------------------------------------------
	/**
	 * 光沢UVインデックスの設定
	 * @param glossUVIndex 光沢UVインデックス
	 */
	virtual void setGlossUVIndex(int glossUVIndex){
		Assert((glossUVIndex >= 0) && (glossUVIndex < 8));
		glossUVIndex_ = glossUVIndex;
	}

	/**
	 * 光沢UVインデックスの取得
	 * @return 光沢UVインデックス
	 */
	virtual int getGlossUVIndex() const{ return glossUVIndex_; }

	//--------------------------------------------------------------------------
	// ライトテクスチャインターフェース
	//--------------------------------------------------------------------------
	/**
	 * ライトテクスチャの設定
	 * @param lightTexture 設定するライトテクスチャ
	 */
	virtual void setLightTexture(Texture* lightTexture){
		lightTexture_ = setTextureReferense(lightTexture_, lightTexture);
	}

	/**
	 * ライトテクスチャの取得
	 * @return ライトテクスチャ
	 */
	virtual Texture* getLightTexture() const{ return lightTexture_; }

	/**
	 * ライトテクスチャの削除
	 */
	virtual void removeLightTexture(){ setLightTexture(NULL); }

	//--------------------------------------------------------------------------
	/**
	 * ライトUVインデックスの設定
	 * @param lightUVIndex ライトUVインデックス
	 */
	virtual void setLightUVIndex(int lightUVIndex){
		Assert((lightUVIndex >= 0) && (lightUVIndex < 8));
		lightUVIndex_ = lightUVIndex;
	}

	/**
	 * ライトUVインデックスの取得
	 * @return ライトUVインデックス
	 */
	virtual int getLightUVIndex() const{ return lightUVIndex_; }

	//--------------------------------------------------------------------------
	// 汚れテクスチャインターフェース
	//--------------------------------------------------------------------------
	/**
	 * 汚れテクスチャの設定
	 * @param stainTexture 設定する汚れテクスチャ
	 */
	virtual void setStainTexture(Texture* stainTexture){
		stainTexture_ = setTextureReferense(stainTexture_, stainTexture);
	}

	/**
	 * 汚れテクスチャの取得
	 * @return 汚れテクスチャ
	 */
	virtual Texture* getStainTexture() const{ return stainTexture_; }

	/**
	 * 汚れテクスチャの削除
	 */
	virtual void removeStainTexture(){ setStainTexture(NULL); }

	//--------------------------------------------------------------------------
	/**
	 * 汚れUVインデックスの設定
	 * @param stainUVIndex 汚れUVインデックス
	 */
	virtual void setStainUVIndex(int stainUVIndex){
		Assert((stainUVIndex >= 0) && (stainUVIndex < 8));
		stainUVIndex_ = stainUVIndex;
	}

	/**
	 * 汚れUVインデックスの取得
	 * @return 汚れUVインデックス
	 */
	virtual int getStainUVIndex() const{ return stainUVIndex_; }

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

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

	//--------------------------------------------------------------------------
	// スペキュラ
	//--------------------------------------------------------------------------
	/**
	 * スペキュラカラーの設定
	 * @param specularColor スペキュラカラー
	 */
	virtual void setSpecularColor(const Color3f& specularColor){
		specularColor_ = specularColor;
		stateChanged();
	}

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

	//--------------------------------------------------------------------------
	/**
	 * スペキュラパワーの設定
	 * @param specularPower スペキュラパワー
	 */
	virtual void setSpecularPower(float specularPower){
		specularPower_ = specularPower;
		stateChanged();
	}

	/**
	 * スペキュラパワーの取得
	 * @return スペキュラパワー
	 */
	virtual float getSpecularPower() const{ return specularPower_; }

	//--------------------------------------------------------------------------
	/**
	 * スペキュラが有効か
	 * @return スペキュラが有効ならtrue
	 */
	virtual bool isSpecularEnabled() const{
		return (specularColor_ != Color3f::black);
	}

	//--------------------------------------------------------------------------
	// アンビエント
	//--------------------------------------------------------------------------
	/**
	 * アンビエントカラーの設定
	 * @param ambientColor アンビエントカラー
	 */
	virtual void setAmbientColor(const Color3f& ambientColor){
		ambientColor_ = ambientColor;
		stateChanged();
	}

	/**
	 * アンビエントカラーの取得
	 * @return アンビエントカラー
	 */
	virtual const Color3f& getAmbientColor() const{ return ambientColor_; }

	//--------------------------------------------------------------------------
	// エミッシブ
	//--------------------------------------------------------------------------
	/**
	 * エミッシブカラーの設定
	 * @param emissiveColor エミッシブカラー
	 */
	virtual void setEmissiveColor(const Color3f& emissiveColor){
		emissiveColor_ = emissiveColor;
		stateChanged();
	}

	/**
	 * エミッシブカラーの取得
	 * @return エミッシブカラー
	 */
	virtual const Color3f& getEmissiveColor() const{ return emissiveColor_; }

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

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

	//--------------------------------------------------------------------------
	/**
	 * 子の破棄
	 * @return 破棄したオブジェクト数
	 */
	virtual int destroyChildren();

	//--------------------------------------------------------------------------
	// 描画
	//--------------------------------------------------------------------------
	/**
	 * ステートブロックの構築
	 * @param startBlock [out]開始ステートブロック
	 * @param endBlock [out]終了ステートブロック
	 */
	virtual void buildStateBlock(
		Direct3DStateBlock** startBlock, Direct3DStateBlock** endBlock);

	//--------------------------------------------------------------------------
private:
	// ベーステクスチャ
	Texture* baseTexture_;
	// 光沢テクスチャ
	Texture* glossTexture_;
	// ライトテクスチャ
	Texture* lightTexture_;
	// 汚れテクスチャ
	Texture* stainTexture_;
	// ディフューズカラー
	Color3f diffuseColor_;
	// スペキュラカラー
	Color3f specularColor_;
	// アンビエントカラー
	Color3f ambientColor_;
	// エミッシブカラー
	Color3f emissiveColor_;
	// スペキュラパワー
	float specularPower_;
	// ベースUVインデックス
	int baseUVIndex_;
	// 光沢UVインデックス
	int glossUVIndex_;
	// ライトUVインデックス
	int lightUVIndex_;
	// 汚れUVインデックス
	int stainUVIndex_;

};

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