//------------------------------------------------------------------------------
// 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
 */

#include "LampBasic.h"
#include "Graphics/Material/BasicMaterial.h"
#include "Graphics/Scene/Scene.h"
#include "Graphics/Material/MaterialManager.h"
#include "Graphics/Texture/Texture.h"
#include "Graphics/Shader/ShaderManager.h"
#include "Graphics/Shader/BasicShaderFixed.h"

namespace Lamp{

//------------------------------------------------------------------------------
// コンストラクタ
BasicMaterial::BasicMaterial(const String& name, Scene* scene) :
	Material(name, scene), baseTexture_(NULL), glossTexture_(NULL),
	lightTexture_(NULL), stainTexture_(NULL),
	diffuseColor_(1.f, 1.f, 1.f), specularColor_(0.f, 0.f, 0.f),
	ambientColor_(1.f, 1.f, 1.f), emissiveColor_(0.f, 0.f, 0.f),
	specularPower_(0.f),
	baseUVIndex_(0), glossUVIndex_(0), lightUVIndex_(0), stainUVIndex_(0){
}
//------------------------------------------------------------------------------
// デストラクタ
BasicMaterial::~BasicMaterial(){
}
//------------------------------------------------------------------------------
// 子の破棄
int BasicMaterial::destroyChildren(){
	int result = 0;
	Texture* texture;
	// ベーステクスチャの破棄
	texture = getBaseTexture();
	if(texture != NULL){
		removeBaseTexture();
		result += Texture::recursiveDestroy(texture);
	}
	// 光沢テクスチャの破棄
	texture = getGlossTexture();
	if(texture != NULL){
		removeGlossTexture();
		result += Texture::recursiveDestroy(texture);
	}
	// ライトテクスチャの破棄
	texture = getLightTexture();
	if(texture != NULL){
		removeLightTexture();
		result += Texture::recursiveDestroy(texture);
	}
	// 汚れテクスチャの破棄
	texture = getStainTexture();
	if(texture != NULL){
		removeStainTexture();
		result += Texture::recursiveDestroy(texture);
	}
	return result;
}
//------------------------------------------------------------------------------
// ステートブロックの構築
void BasicMaterial::buildStateBlock(
	Direct3DStateBlock** startBlock, Direct3DStateBlock** endBlock){
	ShaderManager* shaderManager = ShaderManager::getInstance();
	// ハードウェアの対応状況を調べ、適切なシェーダでステートブロックを構築する
	setPipelineMode(pipelineModeFixed);
	BasicShaderFixed* fixedShader = shaderManager->getBasicShaderFixed();
	fixedShader->buildStateBlock(startBlock, endBlock, this,
		baseTexture_, baseUVIndex_,  lightTexture_, lightUVIndex_,
		stainTexture_, stainUVIndex_, diffuseColor_, specularColor_,
		ambientColor_, emissiveColor_, specularPower_);
}
//------------------------------------------------------------------------------
// 描画
void BasicMaterial::draw(DrawRequest* request){
	// 描画のセットアップ
	drawSetup(request);

	ShaderManager* shaderManager = ShaderManager::getInstance();
	// ハードウェアの対応状況を調べ、適切なシェーダにリクエストを送る
	setPipelineMode(pipelineModeFixed);
	BasicShaderFixed* fixedShader = shaderManager->getBasicShaderFixed();
	fixedShader->draw(request);
}
//------------------------------------------------------------------------------
// 基本マテリアルのコピー
BasicMaterial* BasicMaterial::copyBasicMaterial(u_int copyMask) const{
	MaterialManager* manager = scene_->getMaterialManager();
	BasicMaterial* destination =
		manager->createBasicMaterial(manager->rename(name_));
	// マテリアルのコピー
	copyMaterialValue(destination);
	// メンバのコピー
	destination->setDiffuseColor(diffuseColor_);
	destination->setSpecularColor(specularColor_);
	destination->setAmbientColor(ambientColor_);
	destination->setEmissiveColor(emissiveColor_);
	destination->setSpecularPower(specularPower_);
	destination->setBaseUVIndex(baseUVIndex_);
	destination->setGlossUVIndex(glossUVIndex_);
	destination->setLightUVIndex(lightUVIndex_);
	destination->setStainUVIndex(stainUVIndex_);
	// テクスチャ
	if((copyMask & copyTexture) == 0){
		// テクスチャを共有する
		destination->setBaseTexture(baseTexture_);
		destination->setGlossTexture(glossTexture_);
		destination->setLightTexture(lightTexture_);
		destination->setStainTexture(stainTexture_);
	}else{
		// テクスチャをコピーする
		if(baseTexture_ != NULL){
			destination->setBaseTexture(baseTexture_->copy(copyMask));
		}
		if(glossTexture_ != NULL){
			destination->setGlossTexture(glossTexture_->copy(copyMask));
		}
		if(lightTexture_ != NULL){
			destination->setLightTexture(lightTexture_->copy(copyMask));
		}
		if(stainTexture_ != NULL){
			destination->setStainTexture(stainTexture_->copy(copyMask));
		}
	}
	return destination;
}
//------------------------------------------------------------------------------
} // End of namespace Lamp
//------------------------------------------------------------------------------
