//------------------------------------------------------------------------------
// 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 "System/stdafx.h"
#include "Translator/Instance/TranslationSceneNodeInstance.h"
#include "Graphics/SceneNode/SceneNodeManager.h"

namespace LampForMaya{

//------------------------------------------------------------------------------
// コンストラクタ
TranslationSceneNodeInstance::TranslationSceneNodeInstance(
	const MDagPath& initializePath, const String& initializeName) :
	TranslationInstance(initializePath, initializeName),
	source_(NULL), destination_(NULL){
}
//------------------------------------------------------------------------------
// デストラクタ
TranslationSceneNodeInstance::~TranslationSceneNodeInstance(){
}
//------------------------------------------------------------------------------
// 分析
bool TranslationSceneNodeInstance::analyze(){
	if(!analyzeInstance()){ return false; }

	MStatus result;
	String errorString;
	// トランスフォーム初期化
	MFnTransform transform(dagPath_, &result);
	MayaStatusCheck(result);

	// スケールピボット移動値が0であるかチェック
	MPoint scalePivotTrans =
		transform.scalePivotTranslation(MSpace::kTransform, &result);
	MayaStatusCheck(result);
	if(!zeroCheck(scalePivotTrans)){
		errorString.format("TranslationSceneNodeInstance::analyze() "
			"scalePivotTranslationが0でない ( %8f, %8f, %8f ) %s",
			scalePivotTrans.x, scalePivotTrans.y, scalePivotTrans.z,
			name_.getBytes());
		MayaErrorOut(errorString);
		return false;
	}

	// 回転ピボット移動値が0であるかチェック
	MPoint rotationPivotTrans =
		transform.rotatePivotTranslation(MSpace::kTransform, &result);
	MayaStatusCheck(result);
	if(!zeroCheck(rotationPivotTrans)){
		errorString.format("TranslationSceneNodeInstance::analyze() "
			"rotationPivotTransが0でない ( %8f, %8f, %8f ) %s",
			rotationPivotTrans.x, rotationPivotTrans.y,
			rotationPivotTrans.z, name_.getBytes());
		MayaErrorOut(errorString);
		return false;
	}

	// シアーが0であるかチェック
	double shearArray[3];
	result = transform.getShear(shearArray);
	MPoint shear(shearArray);
	if(!zeroCheck(shear)){
		errorString.format("TranslationSceneNodeInstance::analyze() "
			"shearが0でない ( %8f, %8f, %8f ) %s",
			shear.x, shear.y, shear.z, name_.getBytes());
		MayaErrorOut(errorString);
		return false;
	}

	// ピボット
	MPoint scalePivot = transform.scalePivot(MSpace::kTransform, &result);
	MayaStatusCheck(result);
	MPoint rotationPivot =
		transform.rotatePivot(MSpace::kTransform, &result);
	MayaStatusCheck(result);
	MPoint pivotDifference = scalePivot - rotationPivot;
	if(!zeroCheck(pivotDifference)){
		errorString.format("TranslationSceneNodeInstance::analyze() "
			"scalePivotとrotationPivotが同じでない "
			"scale ( %8f, %8f, %8f ) rotation ( %8f, %8f, %8f ) %s",
			scalePivot.x, scalePivot.y, scalePivot.z,
			rotationPivot.x, rotationPivot.y, rotationPivot.z,
			name_.getBytes());
		MayaErrorOut(errorString);
		return false;
	}
	pivot_.set((float)rotationPivot.x,
		(float)rotationPivot.y, (float)rotationPivot.z);

	// スケール
	double scale[3];
	result = transform.getScale(scale);
	MayaStatusCheck(result);
	scale_.set((float)scale[0], (float)scale[1], (float)scale[2]);

	// 回転
	MEulerRotation rotation;
	result = transform.getRotation(rotation);
	MayaStatusCheck(result);
	if(rotation.order != MEulerRotation::kXYZ){
		errorString.format("TranslationSceneNodeInstance::analyze() "
			"回転順序はXYZしかサポートしていません %s", name_.getBytes());
		MayaErrorOut(errorString);
		return false;
	}
	rotation_.set((float)rotation.x, (float)rotation.y, (float)rotation.z);

	// 移動
	MVector translation =
		transform.translation(MSpace::kTransform, &result);
	MayaStatusCheck(result);
	translation_.set(
		(float)translation.x, (float)translation.y, (float)translation.z);

	// ピボットのコンパイル
	translation_ += pivot_;
	pivot_.set(0.f, 0.f, 0.f);
	return true;
}
//------------------------------------------------------------------------------
// Lampへの変換
bool TranslationSceneNodeInstance::convertToLamp(Scene* scene){
	// 親シーンノードの検索
	SceneNodeManager* sceneNodeManager = scene->getSceneNodeManager();
	SceneNode* target = sceneNodeManager->search(parentSceneNodeName_);
	if(target == NULL){
		MayaErrorOut(String("TranslationSceneNodeInstance::convertToLamp() "
			"インスタンス先のシーンノードが見つかりません ") +
			parentSceneNodeName_);
		return false;
	}

	// シーンノードインスタンス
	SceneNode* sceneNode = sceneNodeManager->search(name_);
	if(sceneNode == NULL){
		MayaErrorOut(String("TranslationSceneNodeInstance::convertToLamp() "
			"インスタンス元のシーンノード" + name_ + "が見つかりません ") +
			parentSceneNodeName_);
		return false;
	}
	source_ = sceneNode;
	SceneNode* copySceneNode = sceneNode->copy(0);
	destination_ = copySceneNode;

	// 値のコピー
	copySceneNode->setScale(scale_);
	copySceneNode->setRotationXYZ(rotation_);
	copySceneNode->setTranslation(translation_);
	copySceneNode->setEnabled(visibility_);
	target->addSceneNode(copySceneNode);
	return true;
}
//------------------------------------------------------------------------------
} // End of namespace LampForMaya
//------------------------------------------------------------------------------
