
#include "ball_list.hh"
#include "pad.hh"

void	pad_define (struct s_pad* pad, struct s_particle* particle, struct s_surface* surface, GLUquadricObj* quadric, float x1, float x2, float y1)
{
	CHD_LoadSound ("data/sounds/pad_ball.wav", FMOD_DEFAULT, &pad->sound[PAD_SOUND_BALL]);
	CHD_LoadSound ("data/sounds/pad_load.wav", FMOD_LOOP_NORMAL, &pad->sound[PAD_SOUND_LOAD]);
	CHD_LoadSound ("data/sounds/pad_release.wav", FMOD_DEFAULT, &pad->sound[PAD_SOUND_RELEASE]);

	surface_load (surface, "data/pad.png", &pad->texture);

	coord_set_pos (&pad->coord, (x1 + x2) / 2, y1, 0);
	coord_set_rot (&pad->coord, 0, 90, 0);

	pad->length_change = 0;
	pad->length_effect = 0;
	pad->length_factor = 2;
	pad->length = pad->length_factor * PAD_SIZE_LENGTH;
	pad->particle = particle;
	pad->quadric = quadric;
	pad->state_effect = 0;
	pad->state_time = 0;
	pad->state = PAD_STATE_READY;
	pad->x1 = x1;
	pad->x2 = x2;
}

void	pad_draw (struct s_pad* pad)
{
	coord_item (&pad->coord);
		glColor3f (1, 1, 1);
		glEnable (GL_TEXTURE_2D);
		glBindTexture (GL_TEXTURE_2D, pad->texture);

		glPushMatrix ();
			glTranslatef (0, 0, pad->length);
			gluSphere (pad->quadric, PAD_SIZE_RADIUS, PAD_QUADRIC_SLICE, PAD_QUADRIC_SLICE);
		glPopMatrix ();

		glPushMatrix ();
			glTranslatef (0, 0, -pad->length);
			gluSphere (pad->quadric, PAD_SIZE_RADIUS, PAD_QUADRIC_SLICE, PAD_QUADRIC_SLICE);
		glPopMatrix ();

		glTranslatef (0, 0, -pad->length);
		gluCylinder (pad->quadric, PAD_SIZE_RADIUS, PAD_SIZE_RADIUS, pad->length * 2, PAD_QUADRIC_SLICE, PAD_QUADRIC_SLICE);
		glDisable (GL_TEXTURE_2D);
	coord_stop ();
}

void	pad_length (struct s_pad* pad, char way)
{
	int	length;

	length = pad->length_factor + way;

	if (length < 1)
		length = 1;
	else if (length > 10)
		length = 10;

	pad->length_change = 1;
	pad->length_factor = length;
}

void						pad_loop (struct s_pad* pad, struct s_ball_list* ball_list)
{
	enum e_particle_color	color;
	struct s_coord			coord;
	float					delta;
	float   				power;
	float					x;

	// change length
	if (pad->length_change)
	{
		delta = pad->length_factor * PAD_SIZE_LENGTH - pad->length;

		if (delta < -PAD_SIZE_EPSILON || delta > PAD_SIZE_EPSILON)
		{
			if (pad->length_effect <= gl_vertex.time)
			{
				coord_set_pos (&coord, 0, pad->coord.py, pad->coord.pz);
				coord_set_rot (&coord, 0, 0, 0);

				color = delta < 0 ? particle_color_red : particle_color_green;

				coord.px = pad->coord.px - pad->length;
				particle_create (pad->particle, &coord, color, particle_define_pad_length, delta * 0.005f);
				coord.px = pad->coord.px + pad->length;
				particle_create (pad->particle, &coord, color, particle_define_pad_length, delta * -0.005f);

				pad->length_effect = gl_vertex.time + PAD_DELAY_EFFECT;
			}

			pad->length = pad->length + delta * PAD_FACTOR_LENGTH * gl_vertex.speed;
		}
		else
			pad->length_change = 0;
	}

	// load or cancel power
	switch (pad->state)
	{
		case PAD_STATE_CANCEL:
			if ((power = pad->state_time - gl_vertex.time) >= 0)
			{
				if (pad->state_effect <= gl_vertex.time)
				{
					particle_create (pad->particle, &pad->coord, particle_color_blue, particle_define_pad_load, power * 0.001f);
					pad->state_effect = gl_vertex.time + PAD_DELAY_EFFECT;
				}

				CHD_SetFrequency (pad->sound[PAD_SOUND_LOAD], 1 + power * PAD_FACTOR_SOUND / PAD_DELAY_CANCEL, 1);
			}
			else
			{
				CHD_PlayStop (pad->sound[PAD_SOUND_LOAD]);
				pad->state = PAD_STATE_READY;
			}

		case PAD_STATE_READY:
			if (VTX_KEY_PRESSED (SDL_BUTTON_LEFT))
			{
				if (ball_list->empty)
				{
					CHD_PlayStart (pad->sound[PAD_SOUND_BALL], 0);
					ball_list_insert (ball_list, pad->coord.px, pad->coord.py);

					pad->state = PAD_STATE_RELEASE;
				}
				else
				{
					CHD_PlayStop (pad->sound[PAD_SOUND_LOAD]);
					CHD_PlayStart (pad->sound[PAD_SOUND_LOAD], 0);
					CHD_SetLoop (pad->sound[PAD_SOUND_LOAD], -1);

					pad->state_time = gl_vertex.time;
					pad->state = PAD_STATE_LOAD;
				}
			}
		break;

		case PAD_STATE_LOAD:
			if ((power = gl_vertex.time - pad->state_time) > PAD_DELAY_LOAD)
				power = PAD_DELAY_LOAD;

			if (pad->state_effect <= gl_vertex.time)
			{
				particle_create (pad->particle, &pad->coord, particle_color_blue, particle_define_pad_load, power * 0.001f);
				pad->state_effect = gl_vertex.time + PAD_DELAY_EFFECT;
			}

			if (VTX_KEY_PRESSED (SDL_BUTTON_LEFT))
				CHD_SetFrequency (pad->sound[PAD_SOUND_LOAD], 1 + power * PAD_FACTOR_SOUND / PAD_DELAY_LOAD, 1);
			else
			{
				pad->state_time = gl_vertex.time + power * PAD_DELAY_CANCEL / PAD_DELAY_LOAD;
				pad->state = PAD_STATE_CANCEL;
			}
		break;

		case PAD_STATE_RELEASE:
			if (!VTX_KEY_PRESSED (SDL_BUTTON_LEFT))
				pad->state = PAD_STATE_READY;
		break;
	}

	// get new pad position
	x = pad->coord.px + gl_vertex.input.mouse_x * 0.01f;

	if (x - PAD_SIZE_RADIUS < pad->x1)
		pad->x = pad->x1 + PAD_SIZE_RADIUS;
	else if (x + PAD_SIZE_RADIUS > pad->x2)
		pad->x = pad->x2 - PAD_SIZE_RADIUS;
	else
		pad->x = x;
}

void	pad_move (struct s_pad* pad)
{
	pad->coord.px = pad->x;
}

float		pad_release (struct s_pad* pad)
{
	float   power;

	if (pad->state != PAD_STATE_LOAD)
		return 0;

	CHD_PlayStart (pad->sound[PAD_SOUND_RELEASE], 0);
	CHD_PlayStop (pad->sound[PAD_SOUND_LOAD]);

	if ((power = gl_vertex.time - pad->state_time) > PAD_DELAY_LOAD)
		power = PAD_DELAY_LOAD;

	particle_create (pad->particle, &pad->coord, particle_color_blue, particle_define_pad_release, power * 0.001f);
	pad->state = PAD_STATE_RELEASE;

	return power * PAD_FACTOR_POWER;
}
