#include "SpaceMapGameInterface.h"
#include "..\gameSettings.h"

void SpaceMapGame::handleKeyboard( Keyboard &keyboard )
{
	this->mapFunctionality.handleKeyboard( keyboard );
}
void SpaceMapGame::handleMouse( Mouse &mouse )
{
	this->mapFunctionality.handleMouse( mouse );
}
void SpaceMapGame::simulate( float dt )
{
	this->mapFunctionality.simulate( this->galaxyPart.spacePlanets, this->galaxyPart.spaceShips, dt );
}
void SpaceMapGame::render( void )
{
	this->mapFunctionality.render( this->renderer, this->galaxyPart.spacePlanets, this->galaxyPart.spaceShips, this->getActiveShipPtr() );
}
void SpaceMapGame::setActiveShipId( unsigned long shipId)
{
	this->activeShipId = shipId;

	SpaceShip * shipPtr = this->galaxyPart.findShip( shipId );
	if ( shipPtr == NULL ) return;

}

void SpaceMapGame::centerCameraToShip( unsigned long shipId )
{
	SpaceShip * shipPtr = this->getShipPtr( shipId );
	if ( shipPtr == NULL ) return;

	// move camera and its pivot to selected object position
	Vector_3<double> cameraOffset=  shipPtr->getPos() - this->mapFunctionality.cameraPivot;
	this->mapFunctionality.cameraPivot += cameraOffset;
	this->mapFunctionality.camera.pos += cameraOffset;
}

SpaceShip*  SpaceMapGame::getShipPtr( unsigned long shipId )
{
	return this->galaxyPart.findShip( shipId  );
}


SpaceShip*  SpaceMapGame::getActiveShipPtr( void )
{
	return this->getShipPtr( this->activeShipId  );
}

void SpaceMapGame::setBackground( unsigned int skyTex )
{
	this->mapFunctionality.setBackground( skyTex );
}

const int NEAR_ZOOM = 50.0;
const int FAR_ZOOM = 20000000.0;
const int CAMERA_MOVE_BOUNDARY = 500000;
const int MAX_VISIBLE_AREA = 20000000;
const int PICK_PLANE_SIZE = MAX_VISIBLE_AREA * 2; 
 
/*
	MapFunctionality(	unsigned int backgroundTexID, const AnimationEffect &explosionPrototype, int pickPlaneSize, 
						int maxVisibleAreaSize, int cameraBoundary, int particleGarbageLimit, int nearCameraZoom, int farCameraZoom, 
						float mouseSensitivity, float keyboardSensitivity );
						*/
SpaceMapGame::SpaceMapGame( SoftProjRender &renderer, const AnimationEffect &explosionClone, const AnimationEffect &warpClone  ): renderer( renderer ), 
	mapFunctionality(0, explosionClone, warpClone, PICK_PLANE_SIZE, MAX_VISIBLE_AREA, CAMERA_MOVE_BOUNDARY, 100, NEAR_ZOOM, FAR_ZOOM, 0.001, 0.01 )
{
	this->activeShipId = false;
}
void SpaceMapGame::activateRadar( unsigned long shipId )
{
	if ( this->getShipPtr(shipId) == NULL ) return;

	//radius is depandant on the zoom level
	const float MAX_RADIUS = 50000.0;
	const float RADIUS_OFFSET = MAX_RADIUS / 30.0;
	this->mapFunctionality.signalize( this->getShipPtr(shipId)->getPos(), MAX_RADIUS, RADIUS_OFFSET );
}
void SpaceMapGame::signalizeShip( unsigned long shipId )
{
	if ( this->getShipPtr(shipId) == NULL ) return;

	//radius is depandant on the zoom level
	const float MAX_RADIUS = this->mapFunctionality.getCameraZoom() / 10.0;
	const float RADIUS_OFFSET = MAX_RADIUS / 40.0;
	this->mapFunctionality.signalize(  this->getShipPtr(shipId)->getPos(), MAX_RADIUS, RADIUS_OFFSET );
}
void SpaceMapGame::setEmittorTex( ShipType type, unsigned int particleTex )
{
	switch ( type )
	{
		case type0:
		{
			//basic ship model
			ShipEmittorType0 *emittor = new ShipEmittorType0();
			emittor->texId = particleTex;
			this->mapFunctionality.particleEmittor[ type0 ] = emittor;
		}
		break;

		case type1:
		{
			//Submarine model
			ShipEmittorType1 *emittor = new ShipEmittorType1();
			emittor->texId = particleTex;
			this->mapFunctionality.particleEmittor[ type1 ] = emittor;
		}
		break;

		case type2:
		{
			//Cruiser model
			ShipEmittorType2 *emittor = new ShipEmittorType2();
			emittor->texId = particleTex;
			this->mapFunctionality.particleEmittor[ type2 ] = emittor;
		}
		break;

		case type3:
		{
			//Taxi model
			ShipEmittorType3 *emittor = new ShipEmittorType3();
			emittor->texId = particleTex;
			this->mapFunctionality.particleEmittor[ type3 ] = emittor;
		}
		break;


		case type4:
		{
			//X-fighter model
			ShipEmittorType4 *emittor = new ShipEmittorType4();
			emittor->texId = particleTex;
			this->mapFunctionality.particleEmittor[ type4 ] = emittor;
		}
		break;

		case type5:
		{
			//Enterprise model
			ShipEmittorType5 *emittor = new ShipEmittorType5();
			emittor->texId = particleTex;
			this->mapFunctionality.particleEmittor[ type5 ] = emittor;
		}
		break;

		case 6:
		{
			//mining machine emittor
			MiningEmittor *emittor = new MiningEmittor();
			emittor->texId = particleTex;
			this->mapFunctionality.particleEmittor[ type ] = emittor;
		}

		break;
		default:
			assert( !"Unsupported type");


	}

}
void SpaceMapGame::removeNotUpdatedObjects( const float lastSynchronisationDt, bool removeShips, bool removePlanets )
{
//############################################################
//remove ships, that were not updated longer than given function value
	if ( removeShips )
	{
		ShipDatabase::iterator shipIt = galaxyPart.spaceShips.begin(); 
		while ( shipIt != galaxyPart.spaceShips.end() )
		{
			if ( shipIt->second->lastSynchronizationTime > lastSynchronisationDt )
			{
				//remove & move shipIt to next item in container if remove was ok
				bool removeOk = galaxyPart.removeShip( galaxyPart.spaceShips, shipIt->first , shipIt );

				if ( !removeOk )
				{
					++shipIt;
				}
			}
			else
			{
				++shipIt;
			}
		}
	}
//############################################################
//remove planets, that were not updated longer than given function value
	if ( removePlanets )
	{
		PlanetDatabase::iterator planetIt = galaxyPart.spacePlanets.begin(); 
		while ( planetIt != galaxyPart.spacePlanets.end() )
		{
			if ( planetIt->second->lastSynchronizationTime > lastSynchronisationDt )
			{
				//remove & move planetIt to next item in container if remove was ok
				bool removeOk = galaxyPart.removePlanet( galaxyPart.spacePlanets, planetIt->first , planetIt );

				if ( !removeOk )
				{
					++planetIt;
				}

			}
			else
			{
				++planetIt;
			}
		}
	}
}