/* ----------------------------------------------------- */
/*----- Projectile functions for The Nebula Project -----*/
/*-----      Copyright (C) 2003 Matthew Butlar      -----*/
/* ----------------------------------------------------- */

#include "cg_local.h"

void ProjectileInit(void)
{
	// Load models and particles here
}

void CreateProjectile(int model, float speed, vec3_t origin, vec3_t axis[], int particle_1, int particle_2)
{
	cg_projectile_t* end;
	cg_projectile_t* temp;
	
	temp = new cg_projectile_t;
	vec3_Copy(origin, temp->origin);
	vec3_Copy(axis[0], temp->axis[0]);
	vec3_Copy(axis[1], temp->axis[1]);
	vec3_Copy(axis[2], temp->axis[2]);
	temp->id1 = 0;
	temp->id2 = 0;
	temp->model = model;
	temp->particle_1 = particle_1;
	temp->particle_2 = particle_2;
	temp->speed = speed;
	temp->next = NULL;
		
	end = ProjectileFindEnd();
	if(cg_prolist == NULL)
		cg_prolist = temp;
	else
		end->next = temp;
	end = NULL;
	temp = NULL;
}

void UpdateProjectiles(void)
{
	MoveProjectiles();
    CollideProjectiles();
	DrawProjectiles();
}

void MoveProjectiles(void)
{
	vec3_t direction;
	vec3_t velocity;
	cg_projectile_t* current = cg_prolist;

	while(current != NULL)
	{
		vec3_Set(0,0,0, velocity);

		vec3_Copy(current->projectile.axis[1], direction);
		vec3_Normalise(direction);

		vec3_AddScale(velocity, direction, current->speed, velocity);
		vec3_Add(current->origin, velocity, current->origin);
		current = current->next;
	}
}

void CollideProjectiles(void)
{
	vec3_t min;
	vec3_t max;
	vec3_t size;
	vec3_t end;
	vec3_t direction;
	hittest_t test;
	box_t collide_box;
	cg_projectile_t* current = cg_prolist;
	cg_projectile_t* temp;
	while(current != NULL)
	{
		vec3_Copy(current->projectile.axis[1], direction);
		vec3_Normalise(direction);
		vec3_AddScale(end, direction, 1.0f, end);
		vec3_Add(current->origin, end, end);

		cipher_r_GetModelBounds(current->model, min, max);
		vec3_Add(min, max, size);
		vec3_Copy(current->projectile.axis[0], collide_box.axis[0]);
		vec3_Copy(current->projectile.axis[1], collide_box.axis[1]);
		vec3_Copy(current->projectile.axis[2], collide_box.axis[2]);
		vec3_Copy(size, collide_box.extent);

		cipher_SweepBox(&collide_box, current->projectile.origin, end, &test, -1, CV_SOLID);
		if (test.allsolid || test.startsolid)
		{
			temp = current;
			current = temp->next;
			DeleteProjectile(temp);
			temp = NULL;
		}
		else
			current = current->next;
	}
}

void DrawProjectiles(void)
{
	particleinfo_t particle1;
	particleinfo_t particle2;
	cg_projectile_t* current = cg_prolist;
	while(current != NULL)
	{
		// Draw projectile
		com_zeromem(&current->projectile, sizeof(current->projectile));
		vec3_Copy(current->origin, current->projectile.origin);
		vec3_Copy(current->axis[0], current->projectile.axis[0]);
		vec3_Copy(current->axis[1], current->projectile.axis[1]);
		vec3_Copy(current->axis[2], current->projectile.axis[2]);
		current->projectile.model = current->model;
		current->projectile.type = ITEMTYPE_MODEL;
		cipher_r_AddItemToScene(&current->projectile);

		// Update and draw 1st particle
		if(current->particle_1 != NULL)
		{
			particle1.disable = rfalse;
			com_zeromem(&current->particle1, sizeof(current->particle1));
			vec3_Copy(current->origin, current->particle1.origin);
			vec3_Copy(current->axis[0], current->particle1.axis[0]);
			vec3_Copy(current->axis[1], current->particle1.axis[1]);
			vec3_Copy(current->axis[2], current->particle1.axis[2]);
			current->particle1.type = ITEMTYPE_PARTICLESYSTEM;
			if(current->id1 == 0)
				current->id1 = cipher_ps_StartParticleSystem(current->particle_1);
			vec3_Set(0, 0, 0, particle1.emitter_pos);
			cipher_ps_UpdateParticleSystem(current->id1, cg.frametime, &particle1);
			current->particle1.model = current->id1;
			cipher_r_AddItemToScene(&current->particle1);
		}

		// Update and draw 2nd particle
		if(current->particle_2 != NULL)
		{
			particle2.disable = rfalse;
			com_zeromem(&current->particle2, sizeof(current->particle2));
			vec3_Copy(current->origin, current->particle2.origin);
			vec3_Copy(current->axis[0], current->particle2.axis[0]);
			vec3_Copy(current->axis[1], current->particle2.axis[1]);
			vec3_Copy(current->axis[2], current->particle2.axis[2]);
			current->particle2.type = ITEMTYPE_PARTICLESYSTEM;
			if(current->id2 == 0)
				current->id2 = cipher_ps_StartParticleSystem(current->particle_2);
			vec3_Set(0, 0, 0, particle2.emitter_pos);
			cipher_ps_UpdateParticleSystem(current->id2, cg.frametime, &particle2);
			current->particle2.model = current->id2;
			cipher_r_AddItemToScene(&current->particle2);
		}

		current = current->next;
	}
}

cg_projectile_t* ProjectileFindEnd(void)
{
	cg_projectile_t* current = cg_prolist;
	if(current != NULL)
	{
		while(current->next != NULL)
		{
			current = current->next;
		}
	}
	return current;
}

void DeleteProjectile(cg_projectile_t* projectile)
{
	cg_projectile_t* current = cg_prolist;
	cg_projectile_t* temp;
	if(current != NULL)
	{
		if(cg_prolist == projectile)
		{
			temp = cg_prolist->next;
			delete cg_prolist;
			cg_prolist = temp;
		}
		else
		{
			while(current->next != projectile)
			{
				current = current->next;
			}
			current->next = projectile->next;
			delete projectile;
		}
	}
}

void DestroyProjectiles(void)
{
	cg_projectile_t* temp;
	cg_projectile_t* current = cg_prolist;
	while(current != NULL)
	{
		temp = current->next;
		delete current;
		current = temp;
	}
	cg_prolist = NULL;
}
