#include "../include/zf.h"

#define BOMB_LIFESPAN 500
#define BOMB_RADIUS_RANGE 50.0f

struct ZfBossBomb
{
    unsigned int ref_count;
    int age;
    float radius;
    CLvertex position;
    bool activated;
};


static ZfSmartPointer smart_pointer; 

static bool
is_valid(ZfBossBomb* bomb)
{
    return bomb->activated;
}

static void
reference(ZfBossBomb* bomb)
{
    bomb->ref_count++;
}

static void
release(ZfBossBomb* bomb)
{
    bomb->ref_count--;
    if(bomb->ref_count==0)
	g_free(bomb);
}

static bool
query_collision(ZfBossBomb* bomb,
		const CLUsphere* sphere,
		const CLnormal* force,
		ZfType collider_type,
		CLvertex* collision_position,
		CLnormal* collision_force_perp,
		CLnormal* collision_force_tan)
{
    if(bomb->activated)
    {
	float dist;
	
	dist = cluVertexDistance(&sphere->origin,
				 &bomb->position);
	if(dist < (sphere->radius + bomb->radius))
	    return true;
    }
    return false;
}

static void
step(ZfBossBomb* bomb)
{
    if(bomb->activated)
    {
	bomb->age++;
	bomb->radius+=0.5f;
	if(bomb->age >= BOMB_LIFESPAN)
	    bomb->activated = false;
    }
}

static void
render(ZfBossBomb* bomb)
{
    if(bomb->activated) 
    {
	float t;

	glPushAttrib(GL_ALL_ATTRIB_BITS);

	glDisable(GL_LIGHTING);
	glDisable(GL_TEXTURE_2D);
	glEnable(GL_DEPTH_TEST);

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	t = 1.0f - (float)bomb->age/BOMB_LIFESPAN;

	glColor4f(0.8f + 0.2f * t, 
		  0.5f, 
		  0.2f + 0.3f * t,
		  t*0.6f);
	
	/*glColor3f(0.0f, 0.5f*t, 0.5f*t);*/
	glPushMatrix();
	glTranslatef(bomb->position.x,
		     bomb->position.y,
		     bomb->position.z);

	glutSolidSphere(bomb->radius, 8, 8); 

	glColor4f(0.5f,
		  0.2f,
		  0.8f, 
		  t);
	glutWireSphere(bomb->radius, 8, 8); 

	glPopMatrix();

	glPopAttrib();
    }
}

void
zf_boss_bomb_init(void)
{
    smart_pointer.is_valid = (ZfIsValid*) is_valid;
    smart_pointer.reference = (ZfReference*) reference;
    smart_pointer.release = (ZfRelease*) release;
 
}

void
zf_boss_bomb_close(void)
{
    /* nothing atm - texture later? */
}

void
zf_boss_bomb_new(CLvertex* ship_pos)
{
    ZfBossBomb* bomb;
    bomb = g_new(ZfBossBomb, 1);
    
    bomb->ref_count = 0;
    bomb->age = 0;
    bomb->radius = 0.1f; /* starting value */
    bomb->activated = true;
	
    clCopyVertex(&bomb->position, ship_pos);

    zf_animation_system_add(bomb,
			    &smart_pointer,
			    (ZfAnimate*)step);
    
    zf_render_system_add_translucent(bomb,
				     &smart_pointer,
				     (ZfRender*)render);

    /* has to be static, because the radius of the collider changes!*/
    zf_collision_system_add_static(bomb,
				   &smart_pointer,
				   (ZfQueryCollision*)query_collision,
				   ZF_BOSS_BOMB);
}
