/*
** EPITECH PROJECT, 2018
** task01
** File description:
** I do task
*/
#include <stdlib.h>
#include "lib/my_stdlib.h"
#include "game/memory.h"
#include "game/game.h"
#include "game/core.h"

static int check_object_map(uint8_t *map, int x, int y, int width)
{
	return ((map[(x >> 6) + (y >> 6) * width] == ID_GROUND
	|| map[(x + 24 >> 6) + (y >> 6) * width] == ID_GROUND
	|| map[(x + 24 >> 6) + (y + 24 >> 6) * width] == ID_GROUND
	|| map[(x >> 6) + (y + 24 >> 6) * width] == ID_GROUND) ? 0 : 1);
}

static void check_collision(sfml_t *sfml, object_t *object)
{
	if (sfml->scene->level->map[(object->x >> 6) +
	(object->y >> 6) * sfml->scene->level->width] == ID_GROUND
	|| sfml->scene->level->map[(object->x + 24 >> 6) +
	(object->y >> 6) * sfml->scene->level->width] == ID_GROUND
	|| sfml->scene->level->map[(object->x >> 6) +
	(object->y + 24 >> 6) * sfml->scene->level->width] == ID_GROUND
	|| sfml->scene->level->map[(object->x + 24>> 6) +
	(object->y + 24 >> 6) * sfml->scene->level->width] == ID_GROUND){
		object->y = (object->y >> 6 << 6) + 40;
		object->dy = 0;
		object->dx = 0;
	}
}

static void update_object(sfml_t *sfml, object_t *object, uint8_t action)
{
	if (object == NULL)
		return;
	if (action != ID_THROWER_STONE){
		if (!check_object_map(sfml->scene->level->map,
			object->x, object->y, sfml->scene->level->width))
			object->sleep = BULLET_STOP;
		object->x += object->dx;
		object->y += object->dy;
		return;
	}
	object->sleep = (object->sleep + 1) % THROWER_DX_SLEEP;
	if (object->dx
		&& !(object->sleep % (THROWER_DX_SLEEP / my_llabs(object->dx)))
		&& check_object_map(sfml->scene->level->map,
		object->x + sgn(object->dx), object->y,
		sfml->scene->level->width))
		object->x += sgn(object->dx);
	object->y += object->dy / 4;
	object->dy += (object->dy < PLAYER_FALL_MAX) ? 1 : 0;
	check_collision(sfml, object);
}

static void add_new_object(thrower_t *thrower)
{
	int i;

	i = -1;
	if (thrower->object[0])
		free(thrower->object[0]);
	while (++i < NB_OBJECT - 1)
		thrower->object[i] = thrower->object[i + 1];
	thrower->object[NB_OBJECT - 1] = init_object(thrower);
}

void update_thrower(sfml_t *sfml, thrower_t **thrower, level_t *level)
{
	int i;
	int j;

	if (!thrower || level->thrower_counter <= 0)
		return;
	i = -1;
	while (++i < level->thrower_counter){
		if ((thrower[i]->action == ID_THROWER_STONE
			&& !level->timer_stone)
			|| (thrower[i]->action != ID_THROWER_STONE
			&& !level->timer_bullet))
			add_new_object(thrower[i]);
		j = -1;
		while (++j < NB_OBJECT)
			update_object(sfml, thrower[i]->object[j],
			thrower[i]->action);
	}
	level->timer_stone = (level->timer_stone + 1) % THROWER_STONE_SLEEP;
	level->timer_bullet = (level->timer_bullet + 1) % THROWER_BULLET_SLEEP;
}
