
#include "camera.h"

static inline void		camera_internal_apply (struct s_camera_part* camera_part, char modulo)
{
	switch (camera_part->mode_pos)
	{
		case CAMERA_MODE_INSTANT:
			coord_set_pos (&camera_part->coord_actual, camera_part->coord_target.px, camera_part->coord_target.py, camera_part->coord_target.pz);
		break;

		case CAMERA_MODE_RELATIVE:
			coord_interpolate_pos_relative (&camera_part->coord_actual, &camera_part->coord_target, camera_part->coef_pos_1);
		break;

		case CAMERA_MODE_SPEED:
			coord_interpolate_pos_speed (&camera_part->coord_actual, &camera_part->coord_target, &camera_part->coord_speed, camera_part->coef_pos_1, camera_part->coef_pos_2);
		break;
	}

	switch (camera_part->mode_rot)
	{
		case CAMERA_MODE_INSTANT:
			coord_set_rot (&camera_part->coord_actual, camera_part->coord_target.rx, camera_part->coord_target.ry, camera_part->coord_target.rz);
		break;

		case CAMERA_MODE_RELATIVE:
			coord_interpolate_rot_relative (&camera_part->coord_actual, &camera_part->coord_target, camera_part->coef_rot_1, modulo);
		break;

		case CAMERA_MODE_SPEED:
			coord_interpolate_rot_speed (&camera_part->coord_actual, &camera_part->coord_target, &camera_part->coord_speed, camera_part->coef_rot_1, camera_part->coef_rot_2, modulo);
		break;
	}
}

void	camera_begin (struct s_camera *camera)
{
	if (camera->reset)
	{
		coord_copy_pos (&camera->part_focus.coord_actual, &camera->part_focus.coord_target);
		coord_copy_rot (&camera->part_focus.coord_actual, &camera->part_focus.coord_target);
		coord_copy_pos (&camera->part_shift.coord_actual, &camera->part_shift.coord_target);
		coord_copy_rot (&camera->part_shift.coord_actual, &camera->part_shift.coord_target);
		coord_set_pos (&camera->part_focus.coord_speed, 0, 0, 0);
		coord_set_rot (&camera->part_focus.coord_speed, 0, 0, 0);
		coord_set_pos (&camera->part_shift.coord_speed, 0, 0, 0);
		coord_set_rot (&camera->part_shift.coord_speed, 0, 0, 0);

		camera->reset = 0;
	}
	else
	{
		camera_internal_apply (&camera->part_focus, camera->modulo);
		camera_internal_apply (&camera->part_shift, camera->modulo);
	}

	coord_item (&camera->part_shift.coord_actual);
	coord_view (&camera->part_focus.coord_actual);
}

void	camera_coef_pos (struct s_camera *camera, float coef_focus_pos_1, float coef_focus_pos_2, float coef_shift_pos_1, float coef_shift_pos_2)
{
	camera->part_focus.coef_pos_1 = coef_focus_pos_1;
	camera->part_focus.coef_pos_2 = coef_focus_pos_2;
	camera->part_shift.coef_pos_1 = coef_shift_pos_1;
	camera->part_shift.coef_pos_2 = coef_shift_pos_2;
}

void	camera_coef_rot (struct s_camera *camera, float coef_focus_rot_1, float coef_focus_rot_2, float coef_shift_rot_1, float coef_shift_rot_2)
{
	camera->part_focus.coef_rot_1 = coef_focus_rot_1;
	camera->part_focus.coef_rot_2 = coef_focus_rot_2;
	camera->part_shift.coef_rot_1 = coef_shift_rot_1;
	camera->part_shift.coef_rot_2 = coef_shift_rot_2;
}

void	camera_define (struct s_camera *camera)
{
	camera_coef_pos (camera, CAMERA_COEF_POS_1, CAMERA_COEF_POS_2, CAMERA_COEF_POS_1, CAMERA_COEF_POS_2);
	camera_coef_rot (camera, CAMERA_COEF_ROT_1, CAMERA_COEF_ROT_2, CAMERA_COEF_ROT_1, CAMERA_COEF_ROT_2);
	camera_mode (camera, CAMERA_MODE_INSTANT, CAMERA_MODE_INSTANT, CAMERA_MODE_INSTANT, CAMERA_MODE_INSTANT, 0);

	coord_set_pos (&camera->part_focus.coord_actual, 0, 0, 0);
	coord_set_rot (&camera->part_focus.coord_actual, 0, 0, 0);
	coord_set_pos (&camera->part_focus.coord_speed, 0, 0, 0);
	coord_set_rot (&camera->part_focus.coord_speed, 0, 0, 0);
	coord_set_pos (&camera->part_focus.coord_target, 0, 0, 0);
	coord_set_rot (&camera->part_focus.coord_target, 0, 0, 0);
	coord_set_pos (&camera->part_shift.coord_actual, 0, 0, 0);
	coord_set_rot (&camera->part_shift.coord_actual, 0, 0, 0);
	coord_set_pos (&camera->part_shift.coord_speed, 0, 0, 0);
	coord_set_rot (&camera->part_shift.coord_speed, 0, 0, 0);
	coord_set_pos (&camera->part_shift.coord_target, 0, 0, 0);
	coord_set_rot (&camera->part_shift.coord_target, 0, 0, 0);

	camera->focus = &camera->part_focus.coord_target;
	camera->shift = &camera->part_shift.coord_target;
	camera->reset = 1;
}

void	camera_mode (struct s_camera *camera, enum e_camera_mode mode_focus_pos, enum e_camera_mode mode_focus_rot, enum e_camera_mode mode_shift_pos, enum e_camera_mode mode_shift_rot, char modulo)
{
	camera->part_focus.mode_pos = mode_focus_pos;
	camera->part_focus.mode_rot = mode_focus_rot;
	camera->part_shift.mode_pos = mode_shift_pos;
	camera->part_shift.mode_rot = mode_shift_rot;

	camera->modulo = modulo;
}

void	camera_stop (void)
{
	coord_stop ();
	coord_stop ();
}
