//------------------------------------------------------------------------------
// 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
 * PS2パッドカメラコントローラ実装
 * @author Junpee
 */

#include "LampBasic.h"
#include "Framework/Utility/PS2PadCameraController.h"
#include "Graphics/Camera/Camera.h"
#include "Input/System/LampInput.h"
#include "Input/Pad/PS2Pad.h"
// アスペクト比
//#include "Graphics/System/LampGraphics.h"
//#include "Graphics/System/GraphicsDeviceCapacity.h"

namespace Lamp{

//------------------------------------------------------------------------------
// コンストラクタ
PS2PadCameraController::PS2PadCameraController() :
	camera_(NULL), pad_(NULL), moveMode_(true){
	rotationSensibility_ = 0.025f;
	translationSensibility_ = 0.5f;
	fovYSensibility_ = 0.01f;
}
//------------------------------------------------------------------------------
// デストラクタ
PS2PadCameraController::~PS2PadCameraController(){
	SafeDelete(pad_);
}
//------------------------------------------------------------------------------
// コントロール
void PS2PadCameraController::control(){
	if((camera_ == NULL) || (pad_ == NULL)){ return; }
	// XY回転
	Vector3 rotation = camera_->getRotation();
	Point2f rightAxis = pad_->getRightAxis();
	rightAxis *= rotationSensibility_;
	Quaternion rotationQuaternion;
	rotationQuaternion.setRotationXYZ(rotation);
	Quaternion addQuaternion;
	addQuaternion.setRotationAxis(Vector3::unitY, -rightAxis.x);
	rotationQuaternion = addQuaternion * rotationQuaternion;
	addQuaternion.setRotationAxis(Vector3::unitX, -rightAxis.y);
	rotationQuaternion = rotationQuaternion * addQuaternion;
	rotationQuaternion.getRotationXYZ(&rotation);

	// 位置
	Vector3 position = camera_->getPosition();
	Point2f leftAxis = pad_->getLeftAxis();
	leftAxis *= translationSensibility_;
	Vector3 addPosition;
	if(pad_->upKeyDown()){
		translationSensibility_ *= 2.0f;
	}
	if(pad_->downKeyDown()){ translationSensibility_ *= 0.5f; }
	if(moveMode_){
		addPosition.x = leftAxis.x;
		addPosition.y = -leftAxis.y;
		addPosition.z = 0.f;
		if(pad_->buttonPressed(PS2Pad::buttonL1)){
			addPosition.z -= translationSensibility_;
		}
		if(pad_->buttonPressed(PS2Pad::buttonL2)){
			addPosition.z += translationSensibility_;
		}
	}else{
		addPosition.x = leftAxis.x;
		addPosition.y = 0.f;
		if(pad_->buttonPressed(PS2Pad::buttonL1)){
			addPosition.y += translationSensibility_;
		}
		if(pad_->buttonPressed(PS2Pad::buttonL2)){
			addPosition.y -= translationSensibility_;
		}
		addPosition.z = leftAxis.y;
	}
	addPosition = rotationQuaternion * addPosition;
	position += addPosition;
	camera_->setTransformation(rotation, position);

	// 移動モード切替
	if(pad_->buttonDown(PS2Pad::buttonL3)){
		moveMode_ = !moveMode_;
	}

	// 画角
	float fovY = camera_->getFovY();
	float aspect = camera_->getAspect();
//	aspect = LampGraphics::getDeviceCapacity()->getBackBufferAspectRate();
	float nearClip = camera_->getNearClip();
	float farClip = camera_->getFarClip();
	if(pad_->buttonPressed(PS2Pad::buttonR1)){
		fovY -= fovYSensibility_;
		if(fovY < Math::toRadian(1.f)){ fovY = Math::toRadian(1.f); }
	}
	if(pad_->buttonPressed(PS2Pad::buttonR2)){
		fovY += fovYSensibility_;
		if(fovY > Math::toRadian(179.f)){ fovY = Math::toRadian(179.f); }
	}
	camera_->setPerspectiveFovY(fovY, aspect, nearClip, farClip);
}
//------------------------------------------------------------------------------
// ジョイスティックの設定
bool PS2PadCameraController::setJoystick(Joystick* joystick){
	if(!PS2Pad::checkCompatibility(joystick)){ return false; }
	pad_ = new PS2Pad(joystick);
	return true;
}
//------------------------------------------------------------------------------
// ジョイスティックの取得
Joystick* PS2PadCameraController::getJoystick(){
	if(pad_ == NULL){ return NULL; }
	return pad_->getJoystick();
}
//------------------------------------------------------------------------------
// ジョイスティックの検索
Joystick* PS2PadCameraController::searchJoystick(){
	int joystickCount = LampInput::getJoystickCount();
	for(int i = 0; i < joystickCount; i++){
		Joystick* joystick = LampInput::getJoystick(i);
		if(setJoystick(joystick)){ return joystick; }
	}
	return NULL;
}
//------------------------------------------------------------------------------
} // End of namespace Lamp
//------------------------------------------------------------------------------
