//------------------------------------------------------------------------------
// 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
 * Mayaテクスチャマネージャ実装
 * @author Junpee
 */

#include "System/stdafx.h"
#include "Texture/MayaTextureManager.h"
#include "Texture/MayaTexture.h"

namespace LampForMaya{

// データベース
HashMap<String, MayaTexture*>* MayaTextureManager::database_ = NULL;
// 配列
ArrayList<MayaTexture*>* MayaTextureManager::array_ = NULL;
// リファレンスカウント
int MayaTextureManager::referenceCount_ = 0;

//------------------------------------------------------------------------------
// 参照の追加
void MayaTextureManager::addReference(){
	referenceCount_++;
	if(referenceCount_ == 1){ initialize(); }
}
//------------------------------------------------------------------------------
// 参照の削除
void MayaTextureManager::removeReference(){
	referenceCount_--;
	Assert(referenceCount_ >= 0);
	if(referenceCount_ == 0){ finalize(); }
}
//------------------------------------------------------------------------------
// 初期化
void MayaTextureManager::initialize(){
	// データベース作成
	Assert(database_ == NULL);
	Assert(array_ == NULL);
	database_ = new HashMap<String, MayaTexture*>();
	array_ = new ArrayList<MayaTexture*>();
}
//------------------------------------------------------------------------------
// 後始末
void MayaTextureManager::finalize(){
	// データベース削除
	Assert(database_ != NULL);
	Assert(array_ != NULL);
	clearDatabase();
	SafeDelete(array_);
	SafeDelete(database_);
}
//------------------------------------------------------------------------------
// バインド
bool MayaTextureManager::bind(const MObject& textureNode){
	if(!textureNode.hasFn(MFn::kFileTexture)){ return false; }
	String nodeName = MayaNodeUtility::getName(textureNode);
	// データベースチェック
	MayaTexture* texture = database_->get(nodeName);
	if(texture == NULL){
		// キャッシュが無かったのでテクスチャ作成
		texture = new MayaTexture(textureNode, nodeName);
		// テクスチャをデータベースに登録
		addDatabase(texture);
	}
	// テクスチャのバインド
	if(!texture->bind()){
		removeDatabase(texture);
		delete texture;
		return false;
	}
	return true;
}
//------------------------------------------------------------------------------
// データベースに追加
void MayaTextureManager::addDatabase(MayaTexture* texture){
	database_->put(texture->getName(), texture);
	array_->add(texture);
}
//------------------------------------------------------------------------------
// データベースから削除
void MayaTextureManager::removeDatabase(MayaTexture* texture){
	MayaTexture* removed = database_->remove(texture->getName());
	Assert(texture == removed);
	int result = array_->removeByValue(texture);
	Assert(result != -1);
}
//------------------------------------------------------------------------------
// データベースのクリア
void MayaTextureManager::clearDatabase(){
	if((array_ == NULL) && (database_ == NULL)){ return; }
	int count = array_->getCount();
	for(int i = 0; i < count; i++){ delete array_->get(i); }
	array_->clear();
	database_->clear();
}
//------------------------------------------------------------------------------
// 名前変更コールバック
void MayaTextureManager::renameCallback(MObject& node, void* data){
	MayaTexture* texture = (MayaTexture*)data;
	removeDatabase(texture);
	delete texture;
}
//------------------------------------------------------------------------------
// 汚れコールバック
void MayaTextureManager::dirtyCallback(void* data){
	MayaTexture* texture = (MayaTexture*)data;
	removeDatabase(texture);
	delete texture;
}
//------------------------------------------------------------------------------
} // End of namespace LampForMaya
//------------------------------------------------------------------------------
