#include "ShipEmittor.h"


void ShipEmittorType0::generateParticle( const Point_3<float> &pos, const Vector_3<float> &dir, GraphicParticle &dstParticle )
{

	dstParticle.color[0] = getRandomNumberFrom0To1()*0.2;
	dstParticle.color[1] = getRandomNumberFrom0To1()*0.2;
	dstParticle.color[2] = 0.5 + getRandomNumberFrom0To1()*0.2;
	dstParticle.color[3] = 0.5 + getRandomNumberFrom0To1()*0.3;

	dstParticle.size = 0.25;
	dstParticle.setAcceleration( 0 );
	
	float lifeTime = 25 + getRandomNumberFrom0To1() * 25;	// lifeTime <25,50>
	dstParticle.setLifeTime( lifeTime );		
	dstParticle.setColorOffset( getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.1 , -1.0/lifeTime );
	
	Vector_3<float> particleDir = dir * -0.1 * getRandomNumberFrom0To1();
	particleDir.rotate_around_vector( MAKE_VECTOR<float>(0,1,0), (-1.0 + 2.0 * getRandomNumberFrom0To1()) * 15.0 ); // particle direction differs in angle <-15,15 > from ship direction
	dstParticle.setVelocity(particleDir );

	dstParticle.setSizeOffset( 0.02 );
	dstParticle.textureID = this->texId;

	dstParticle.setPosition( pos  );
}
void ShipEmittorType0::emitParticles( const Point_3<float> &pos, const Vector_3<float> &dir )
{

	assert( dir.y() == 0 ); //y component have to be zero ( we work only in pseudo 3D )
	Vector_3<float> rightVec =  MAKE_VECTOR<float>( -dir.z(), 0, dir.x() ); // perpendicular vector in 2D


	Point_3<float> particlePos1 = pos - dir * 4.0 + rightVec * 1.5;
	Point_3<float> particlePos2 = pos - dir * 4.0 - rightVec * 1.5;

	GraphicParticle *particleLeft = new GraphicParticle();
	this->generateParticle( particlePos1, dir, *particleLeft );
	this->particles.push_back( particleLeft );
	
	GraphicParticle *particleRight = new GraphicParticle();
	this->generateParticle( particlePos2, dir, *particleRight );
	this->particles.push_back( particleRight );
}

//############################################################################

void ShipEmittorType1::generateParticle( const Point_3<float> &pos, const Vector_3<float> &dir, GraphicParticle &dstParticle )
{

	dstParticle.color[0] = getRandomNumberFrom0To1()*0.1;
	dstParticle.color[1] = 0.6 + getRandomNumberFrom0To1()*0.2;
	dstParticle.color[2] = getRandomNumberFrom0To1()*0.1;
	dstParticle.color[3] = 0.8;

	dstParticle.size = 0.25;
	dstParticle.setAcceleration( 0 );
	
	float lifeTime = 35 + getRandomNumberFrom0To1() * 50;	// lifeTime <35,85>
	dstParticle.setLifeTime( lifeTime );		
	dstParticle.setColorOffset( getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.1 , -1.0/lifeTime );
	
	Vector_3<float> particleDir = dir * -0.15 * getRandomNumberFrom0To1();
	particleDir.rotate_around_vector( MAKE_VECTOR<float>(0,1,0), (-1.0 + 2.0 * getRandomNumberFrom0To1()) * 20.0 ); // particle direction differs in angle <-20,20 > from ship direction
	dstParticle.setVelocity(particleDir );

	dstParticle.setSizeOffset( 0.015 );
	dstParticle.textureID = this->texId;

	dstParticle.setPosition( pos  );
}
void ShipEmittorType1::emitParticles( const Point_3<float> &pos, const Vector_3<float> &dir  )
{
	assert( dir.y() == 0 ); //y component have to be zero ( we work only in pseudo 3D )
	Vector_3<float> rightVec =  MAKE_VECTOR<float>( -dir.z(), 0, dir.x() ); // perpendicular vector in 2D

	Point_3<float> centerPos = pos - dir * 6.0;

	GraphicParticle *particleCenter = new GraphicParticle();
	this->generateParticle( centerPos, dir, *particleCenter );
	this->particles.push_back( particleCenter );
}

//############################################################################

void ShipEmittorType2::generateParticle( const Point_3<float> &pos, const Vector_3<float> &dir, GraphicParticle &dstParticle )
{

	dstParticle.color[0] = 0.8 + getRandomNumberFrom0To1()*0.2;
	dstParticle.color[1] = getRandomNumberFrom0To1()*0.1;
	dstParticle.color[2] = getRandomNumberFrom0To1()*0.1;
	dstParticle.color[3] = 1.0;

	dstParticle.size = 0.15;
	dstParticle.setAcceleration( 0 );
	
	float lifeTime = 40 + getRandomNumberFrom0To1() * 30;	// lifeTime <40,70>
	dstParticle.setLifeTime( lifeTime );		
	dstParticle.setColorOffset( getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.1 , -1.0/lifeTime );
	
	Vector_3<float> particleDir = dir * -0.2 * getRandomNumberFrom0To1();
	particleDir.rotate_around_vector( MAKE_VECTOR<float>(0,1,0), (-1.0 + 2.0 * getRandomNumberFrom0To1()) * 10.0 ); // particle direction differs in angle <-10,10 > from ship direction
	dstParticle.setVelocity(particleDir );

	dstParticle.setSizeOffset( 0.02 );
	dstParticle.textureID = this->texId;

	dstParticle.setPosition( pos  );
}
void ShipEmittorType2::emitParticles( const Point_3<float> &pos, const Vector_3<float> &dir )
{

	assert( dir.y() == 0 ); //y component have to be zero ( we work only in pseudo 3D )
	Vector_3<float> rightVec =  MAKE_VECTOR<float>( -dir.z(), 0, dir.x() ); // perpendicular vector in 2D


	Point_3<float> particlePos1 = pos - dir * 4.0 + rightVec * 1.5;
	Point_3<float> particlePos2 = pos - dir * 4.0 - rightVec * 1.5;

	GraphicParticle *particleLeft = new GraphicParticle();
	this->generateParticle( particlePos1, dir, *particleLeft );
	this->particles.push_back( particleLeft );
	
	GraphicParticle *particleRight = new GraphicParticle();
	this->generateParticle( particlePos2, dir, *particleRight );
	this->particles.push_back( particleRight );
}

//#########################################################################

void ShipEmittorType3::generateParticle( const Point_3<float> &pos, const Vector_3<float> &dir, GraphicParticle &dstParticle )
{

	dstParticle.color[0] = getRandomNumberFrom0To1()*0.1;
	dstParticle.color[1] = getRandomNumberFrom0To1()*0.3;
	dstParticle.color[2] = 0.5 + getRandomNumberFrom0To1()*0.3;
	dstParticle.color[3] = 0.5 + getRandomNumberFrom0To1()*0.3;

	dstParticle.size = 0.4;
	dstParticle.setAcceleration( 0 );
	
	float lifeTime = 35 + getRandomNumberFrom0To1() * 35;	// lifeTime <35,70>
	dstParticle.setLifeTime( lifeTime );		
	dstParticle.setColorOffset( getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.1, getRandomNumberFrom0To1() * 0.1 , -1.0/lifeTime );
	
	Vector_3<float> particleDir = dir * -0.1 * getRandomNumberFrom0To1();
	particleDir.rotate_around_vector( MAKE_VECTOR<float>(0,1,0), (-1.0 + 2.0 * getRandomNumberFrom0To1()) * 15.0 ); // particle direction differs in angle <-15,15 > from ship direction
	dstParticle.setVelocity(particleDir );

	dstParticle.setSizeOffset( 0.025 );
	dstParticle.textureID = this->texId;

	dstParticle.setPosition( pos  );
}
void ShipEmittorType3::emitParticles( const Point_3<float> &pos, const Vector_3<float> &dir )
{
	assert( dir.y() == 0 ); //y component have to be zero ( we work only in pseudo 3D )
	Vector_3<float> rightVec =  MAKE_VECTOR<float>( -dir.z(), 0, dir.x() ); // perpendicular vector in 2D


	Point_3<float> particlePos1 = pos - dir * 5.0 + rightVec * 1.1;
	Point_3<float> particlePos2 = pos - dir * 5.0 - rightVec * 1.1;

	GraphicParticle *particleLeft = new GraphicParticle();
	this->generateParticle( particlePos1, dir, *particleLeft );
	this->particles.push_back( particleLeft );
	
	GraphicParticle *particleRight = new GraphicParticle();
	this->generateParticle( particlePos2, dir, *particleRight );
	this->particles.push_back( particleRight );
}

// ########################################################################

void ShipEmittorType4::generateParticle( const Point_3<float> &pos, const Vector_3<float> &dir, GraphicParticle &dstParticle )
{

	dstParticle.color[0] = 0.5 + getRandomNumberFrom0To1()*0.2;
	dstParticle.color[1] = 0.5 + getRandomNumberFrom0To1()*0.2;
	dstParticle.color[2] = getRandomNumberFrom0To1()*0.1;
	dstParticle.color[3] = 1.0;

	dstParticle.size = 0.25;
	dstParticle.setAcceleration( 0 );
	
	float lifeTime = 25 + getRandomNumberFrom0To1() * 25;	// lifeTime <25,50>
	dstParticle.setLifeTime( lifeTime );		
	dstParticle.setColorOffset( getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.1 , -1.0/lifeTime );
	
	Vector_3<float> particleDir = dir * -0.1 * getRandomNumberFrom0To1();
	particleDir.rotate_around_vector( MAKE_VECTOR<float>(0,1,0), (-1.0 + 2.0 * getRandomNumberFrom0To1()) * 15.0 ); // particle direction differs in angle <-15,15 > from ship direction
	dstParticle.setVelocity(particleDir );

	dstParticle.setSizeOffset( 0.02 );
	dstParticle.textureID = this->texId;

	dstParticle.setPosition( pos  );
}
void ShipEmittorType4::emitParticles( const Point_3<float> &pos, const Vector_3<float> &dir  )
{
	assert( dir.y() == 0 ); //y component have to be zero ( we work only in pseudo 3D )
	
	Point_3<float> particlePos1 = pos - dir * 4.3;

	GraphicParticle *particleCenter = new GraphicParticle();
	this->generateParticle( particlePos1, dir, *particleCenter );
	this->particles.push_back( particleCenter );
}

//#########################################################################

void ShipEmittorType5::generateParticle( const Point_3<float> &pos, const Vector_3<float> &dir, GraphicParticle &dstParticle )
{

	dstParticle.color[0] = 0.3 + getRandomNumberFrom0To1()*0.6;
	dstParticle.color[1] = 0.3 + getRandomNumberFrom0To1()*0.6;
	dstParticle.color[2] = 0.3 + getRandomNumberFrom0To1()*0.6;
	dstParticle.color[3] = 1.0;

	dstParticle.size = 0.25;
	dstParticle.setAcceleration( 0 );
	
	float lifeTime = 25 + getRandomNumberFrom0To1() * 25;	// lifeTime <25,50>
	dstParticle.setLifeTime( lifeTime );		
	dstParticle.setColorOffset( getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.05, getRandomNumberFrom0To1() * 0.1 , -1.0/lifeTime );
	
	Vector_3<float> particleDir = dir * -0.1 * getRandomNumberFrom0To1();
	particleDir.rotate_around_vector( MAKE_VECTOR<float>(0,1,0), (-1.0 + 2.0 * getRandomNumberFrom0To1()) * 15.0 ); // particle direction differs in angle <-15,15 > from ship direction
	dstParticle.setVelocity(particleDir );

	dstParticle.setSizeOffset( 0.02 );
	dstParticle.textureID = this->texId;

	dstParticle.setPosition( pos  );
}

void ShipEmittorType5::emitParticles( const Point_3<float> &pos, const Vector_3<float> &dir  )
{
	assert( dir.y() == 0 ); //y component have to be zero ( we work only in pseudo 3D )
	Vector_3<float> rightVec =  MAKE_VECTOR<float>( -dir.z(), 0, dir.x() ); // perpendicular vector in 2D

	Vector_3<float> upVec =  MAKE_VECTOR<float>( 0, 1.0 , 0 ); 
	
	Point_3<float> particlePos1 = pos - dir * 4.5 + rightVec * 2.0;
	Point_3<float> particlePos2 = pos - dir * 4.5 - rightVec * 2.0;
	Point_3<float> particlePos3 = pos - dir * 4.5 + upVec * 1.0;

	GraphicParticle *particleLeft = new GraphicParticle();
	this->generateParticle( particlePos1, dir, *particleLeft );
	this->particles.push_back( particleLeft );
	
	GraphicParticle *particleRight = new GraphicParticle();
	this->generateParticle( particlePos2, dir, *particleRight );
	this->particles.push_back( particleRight );

	GraphicParticle *particleUp = new GraphicParticle();
	this->generateParticle( particlePos3, dir, *particleUp );
	this->particles.push_back( particleUp );
}


//#########################################################################

void MiningEmittor::generateParticle( const Point_3<float> &pos, const Vector_3<float> &dir, GraphicParticle &dstParticle )
{

	dstParticle.color[0] = 0.1 + getRandomNumberFrom0To1()*0.3;
	dstParticle.color[1] = 0.1 + getRandomNumberFrom0To1()*0.3;
	dstParticle.color[2] = 0.4 + getRandomNumberFrom0To1()*0.2;
	dstParticle.color[3] = 1.0;

	dstParticle.size = 1.1 + getRandomNumberFrom0To1() * 0.6; //size in range <1.1, 1.7>
	dstParticle.setAcceleration( 0 );
	
	float lifeTime = 18 + getRandomNumberFrom0To1() * 7;	// lifeTime <18,25>
	dstParticle.setLifeTime( lifeTime );		
	dstParticle.setColorOffset( getRandomNumberFrom0To1() * 0.08, getRandomNumberFrom0To1() * 0.08, getRandomNumberFrom0To1() * 0.08 , -1.0/lifeTime );
	
	Vector_3<float> particleDir = dir * 0.01; // * -0.1 * getRandomNumberFrom0To1();
	particleDir.rotate_around_vector( MAKE_VECTOR<float>(0,1,0), (-1.0 + 2.0 * getRandomNumberFrom0To1()) * 5.0 ); // particle direction differs in angle <-5,5 > from ship direction
	dstParticle.setVelocity( dir * 0.04 );

	dstParticle.setSizeOffset( (-0.5 + getRandomNumberFrom0To1())*0.1 ); // offset in range
	dstParticle.textureID = this->texId;

	float positionOffset = 5.0;
	dstParticle.setPosition( pos + dir.get_normalized_vector() * positionOffset  );
}

void MiningEmittor::emitParticles( const Point_3<float> &pos, const Vector_3<float> &dir  )
{
	assert( dir.y() == 0 ); //y component have to be zero ( we work only in pseudo 3D )

	const float dirShorteningFactor = 0.8;

	//number of generated particles is depandadnt on the mining distance 
	//the higher distance the more particles
	//generated particles are shifted in the mining direction
	for ( int i=0; i< (int) dir.get_length() / 3; ++i )
	{
		//shift particle in the mining direction
		Point_3<float> newParticlePos = pos + dir.get_normalized_vector() / 3 * i;

		//shift randomly in range <0,1.0 >
		newParticlePos +=  dir.get_normalized_vector() * ( getRandomNumberFrom0To1() * 1.0 );
		
		GraphicParticle *particle = new GraphicParticle();
		this->generateParticle( newParticlePos, dir * dirShorteningFactor, *particle );
		this->particles.push_back( particle );
	}

}