/*
 * ExNihilo 3D Engine
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Please read AUTHORS file !!!
 * 
 * $Id: ExManagerCamera.cpp,v 1.8 2002/11/24 11:58:56 data Exp $
 *
 */
#include "ExManagerCamera.h"

bool ExManagerCamera::m_flag = false; 
ExManagerCamera* ExManagerCamera::m_instance = NULL; 

ExManagerCamera* ExManagerCamera::CreateSingleton(void){
Guard(ExManagerCamera* ExManagerCamera::CreateSingleton(void))
	if(!m_flag)
	{
		m_flag = true; // We are creating the error log now, so set flag to true
		m_instance = new ExManagerCamera; // Create the error log
	}else
	{
		std::cout<<"Error singleton already created"<<std::endl;
	}
	return m_instance; 
UnGuard
}

ExManagerCamera::ExManagerCamera(void)
{
	
}

ExManagerCamera::~ExManagerCamera(void)
{
}

void ExManagerCamera::Reset(void)
{
Guard(void ExManagerCamera::Reset(void))
	ExManagerObject<ExCCamera *>::Reset();
	Init();
UnGuard
}

void ExManagerCamera::Init(void)
{
Guard(void ExManagerCamera::Init(void))
	ExManagerObject<ExCCamera *>::Init();
	AddCamera("Camera",CAMERA_DEFAULT);
	AddCamera("Camera2",CAMERA_DEFAULT);
	AddCamera("Camera3",CAMERA_DEFAULT);
	AddCamera("CameraChase",CAMERA_CHASE);
	AddCamera("CameraFirst",CAMERA_FIRST);
	AddCamera("CameraFlight",CAMERA_FLIGHT);
	SetCurrentObject("Camera");
UnGuard
}
void ExManagerCamera::AddCamera(std::string CameraName,CameraType Type)
{
Guard(void ExManagerCamera::AddCamera(std::string CameraName,CameraType Type))
	ExCCamera *Camera;
	switch(Type) 
	{
	case CAMERA_DEFAULT:
		Camera = new ExCCamera;
		break;
	case CAMERA_FREE:
		Camera = new ExCCameraFree;
		break;
	case CAMERA_CHASE:
		Camera = new ExCCameraChase;
		((ExCCameraChase *)Camera)->SetManagerModel(ManagerModel);
		break;
	case CAMERA_FIRST:
		Camera= new ExCCameraFirst;
		((ExCCameraFirst *)Camera)->SetManagerModel(ManagerModel);
		break;
	case CAMERA_FLIGHT:
		Camera= new ExCCameraFlight;
		break;
	}
	Camera->SetName(CameraName);
	ExManagerObject<ExCCamera *>::Add(Camera);
UnGuard
}
void ExManagerCamera::Draw(void)
{
Guard(void ExManagerCamera::Draw(void))
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0,0,glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT));
	gluPerspective(GetCurrentObject()->GetZoom(),
		(1.0f *glutGet(GLUT_WINDOW_WIDTH)/glutGet(GLUT_WINDOW_HEIGHT)),
		GetCurrentObject()->GetClipNear(),
		GetCurrentObject()->GetClipFar());
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	//Draw camera gizmo
	for(m_ItMap=m_Map->begin();m_ItMap!=m_Map->end();m_ItMap++)
	{
		m_ItMap->second->DrawCameraGizmo();
	}
	GetCurrentObject()->Draw();	
UnGuard
}

ExCCamera* ExManagerCamera::GetCurrentObject(void)
{
Guard(ExCCamera* ExManagerCamera::GetCurrentObject(void))
	return GetObject(m_CurrentObjectId);
UnGuard
}

ExCCamera * ExManagerCamera::GetObject(ExNihilo::ExId id)
{
Guard(ExCCamera *ExManagerCamera::GetObject(ExNihilo::ExId id))
	for(m_ItMap=m_Map->begin();m_ItMap!=m_Map->end();m_ItMap++)
	{
		if(m_ItMap->second->GetId()==id)return m_ItMap->second;
	}
	return NULL;
UnGuard
}

ExCAction ExManagerCamera::InputCommand(ExCCommand Command)
{
Guard(ExManagerCamera::InputCommand(ExCCommand Command))
	if(GetCurrentObject()==NULL)return NOTHING;
	return	NOTHING;
UnGuard
}

ExCAction ExManagerCamera::InputAction(ExCAction Action)
{
Guard(ExManagerCamera::InputAction(ExCAction Action))
	switch(Action.m_Action)
	{
	case CAMERA_CURRENT_INCREASE_SPEED:
		GetCurrentObject()->m_speed++;
		break;

	case CAMERA_CURRENT_DECREASE_SPEED:
		GetCurrentObject()->m_speed--;
		break;

	case CAMERA_CURRENT_FULL_STOP:
		GetCurrentObject()->m_speed=0;
		break;

	case CAMERA_CURRENT_START_ROTATEX_UP:
		GetCurrentObject()->StartAction(ROTATE_X_UP	);
		break;
	
	case CAMERA_CURRENT_STOP_ROTATEX_UP:
		GetCurrentObject()->StopAction(ROTATE_X_UP);
		break;
	
	case CAMERA_CURRENT_ROTATEX_UP:
		GetCurrentObject()->m_Angle.IncX(2);
		break;
	
	case CAMERA_CURRENT_START_ROTATEX_DOWN:
		GetCurrentObject()->StartAction(ROTATE_X_DOWN);
		break;
	
	case CAMERA_CURRENT_STOP_ROTATEX_DOWN:
		GetCurrentObject()->StopAction(ROTATE_X_DOWN);
		break;
	
	case CAMERA_CURRENT_ROTATEX_DOWN:
		GetCurrentObject()->m_Angle.DecX(2);
		break;

	case CAMERA_CURRENT_START_ROTATEZ_UP:
		GetCurrentObject()->StartAction(ROTATE_Z_UP);
		break;
	
	case CAMERA_CURRENT_STOP_ROTATEZ_UP:
		GetCurrentObject()->StopAction(ROTATE_Z_UP);
		break;
	
	case CAMERA_CURRENT_ROTATEZ_UP:
		GetCurrentObject()->m_Angle.IncZ(2);
		break;
	
	case CAMERA_CURRENT_START_ROTATEZ_DOWN:
		GetCurrentObject()->StartAction(ROTATE_Z_DOWN);
		break;
	
	case CAMERA_CURRENT_STOP_ROTATEZ_DOWN:
		GetCurrentObject()->StopAction(ROTATE_Z_DOWN);
		break;
	
	case CAMERA_CURRENT_ROTATEZ_DOWN:
		GetCurrentObject()->m_Angle.DecZ(2);
		break;

	case CAMERA_CURRENT_START_ROTATEY_UP:
		GetCurrentObject()->StartAction(ROTATE_Y_UP);
		break;
	
	case CAMERA_CURRENT_STOP_ROTATEY_UP:
		GetCurrentObject()->StopAction(ROTATE_Y_UP);
		break;
	
	case CAMERA_CURRENT_ROTATEY_UP:
		GetCurrentObject()->m_Angle.IncY(2);
		break;
	
	case CAMERA_CURRENT_START_ROTATEY_DOWN:
		GetCurrentObject()->StartAction(ROTATE_Y_DOWN);
		break;
	
	case CAMERA_CURRENT_STOP_ROTATEY_DOWN:
		GetCurrentObject()->StopAction(ROTATE_Y_DOWN);
		break;
	
	case CAMERA_CURRENT_ROTATEY_DOWN:
		GetCurrentObject()->m_Angle.DecY(2);
		break;
            	
	case CAMERA_NEXT_CAM:
		NextObject();
		break;
	case CAMERA_PREV_CAM:
		PreviousObject();
		break;

	case CAMERA_CURRENT_INCREASE_ZOOM:
		GetCurrentObject()->ZoomOut();
		break;
	case CAMERA_CURRENT_START_INCREASE_ZOOM:
		GetCurrentObject()->StartAction(ZOOM_UP);
		break;
	case CAMERA_CURRENT_STOP_INCREASE_ZOOM:
		GetCurrentObject()->StopAction(ZOOM_UP);
		break;

	case CAMERA_CURRENT_DECREASE_ZOOM:
		GetCurrentObject()->ZoomIn();
		break;
	case CAMERA_CURRENT_START_DECREASE_ZOOM:
		GetCurrentObject()->StartAction(ZOOM_DOWN);
		break;
	case CAMERA_CURRENT_STOP_DECREASE_ZOOM:
		GetCurrentObject()->StopAction(ZOOM_DOWN);
		break;	
	case CAMERA_SET_POS_X:
		GetCurrentObject()->m_Position.SetX(atof(Action.m_Param.data()));
		break;
	case CAMERA_SET_POS_Y:
		GetCurrentObject()->m_Position.SetY(atof(Action.m_Param.data()));
		break;
	case CAMERA_SET_POS_Z:
		GetCurrentObject()->m_Position.SetZ(atof(Action.m_Param.data()));
		break;
	case CAMERA_SET_TARGET_POS_X:
		GetCurrentObject()->m_Target.SetX(atof(Action.m_Param.data()));
		break;
	case CAMERA_SET_TARGET_POS_Y:
		GetCurrentObject()->m_Target.SetY(atof(Action.m_Param.data()));
		break;
	case CAMERA_SET_TARGET_POS_Z:
		GetCurrentObject()->m_Target.SetZ(atof(Action.m_Param.data()));
		break;
	case CAMERA_SET_ANGLE_X:
		GetCurrentObject()->m_Angle.SetX(atof(Action.m_Param.data()));
		break;
	case CAMERA_SET_ANGLE_Y:
		GetCurrentObject()->m_Angle.SetY(atof(Action.m_Param.data()));
		break;
	case CAMERA_SET_ANGLE_Z:
		GetCurrentObject()->m_Angle.SetZ(atof(Action.m_Param.data()));
		break;
	case CAMERA_CURRENT_SHOW_INFO:
		GetCurrentObject()->SetShowInfoState(true);
		break;
	case CAMERA_CURRENT_HIDE_INFO:
		GetCurrentObject()->SetShowInfoState(false);
		break;
	//--------------------------------------------------------------------
	//Chase cam action
	//--------------------------------------------------------------------
	case CAMERA_CURRENT_START_INCREASE_AROUND:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StartAction(ANGLE_AROUND_TARGET_UP);
		}
		break;
	case CAMERA_CURRENT_STOP_INCREASE_AROUND:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StopAction(ANGLE_AROUND_TARGET_UP);
		}
		break;
	case CAMERA_CURRENT_START_DECREASE_AROUND:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StartAction(ANGLE_AROUND_TARGET_DOWN);
		}
		break;
	case CAMERA_CURRENT_STOP_DECREASE_AROUND:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StopAction(ANGLE_AROUND_TARGET_DOWN);
		}
		break;

	case CAMERA_CURRENT_START_INCREASE_DISTANCE:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StartAction(DISTANCE_FROM_TARGET_UP);
		}
		break;
	case CAMERA_CURRENT_STOP_INCREASE_DISTANCE:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StopAction(DISTANCE_FROM_TARGET_UP);
		}
		break;
	case CAMERA_CURRENT_START_DECREASE_DISTANCE:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StartAction(DISTANCE_FROM_TARGET_DOWN);
		}
		break;
	case CAMERA_CURRENT_STOP_DECREASE_DISTANCE:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StopAction(DISTANCE_FROM_TARGET_DOWN);
		}
		break;

	case CAMERA_CURRENT_START_INCREASE_HEIGHT:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StartAction(HEIGHT_FROM_TARGET_UP);
		}
		break;
	case CAMERA_CURRENT_STOP_INCREASE_HEIGHT:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StopAction(HEIGHT_FROM_TARGET_UP);
		}
		break;
	case CAMERA_CURRENT_START_DECREASE_HEIGHT:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StartAction(HEIGHT_FROM_TARGET_DOWN);
		}
		break;
	case CAMERA_CURRENT_STOP_DECREASE_HEIGHT:
		if(strcmp("class ExCCameraChase",GetCurrentObject()->GetType().data())==0)
		{
			GetCurrentObject()->StopAction(HEIGHT_FROM_TARGET_DOWN);
		}
		break;
	default:
		*Consol<<"Can not file action in CAMERA_ACTION_MAP"<<std::endl;
		break;
	}
	return	NOTHING;
UnGuard
}