/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   parse_map.c                                        :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: qmennen <qmennen@student.codam.nl>         +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2025/04/22 13:12:04 by whaffman          #+#    #+#             */
/*   Updated: 2025/05/28 17:07:32 by qmennen          ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "cub3d.h"
#include <math.h>

t_vec2	parse_dir(int x, int y)
{
	t_vec2	dir;

	dir.x = (double)x;
	dir.y = (double)y;
	return (dir);
}

int	parse_player(t_game *game, int y, int x, char c)
{
	t_player	*player;

	player = game->player;
	if (player->pos.x != -1 || player->pos.y != -1)
	{
		ft_putstr_fd("Error: Multiple players found\n", 2);
		return (FAILURE);
	}
	player->pos.x = ((double)x + 0.5f);
	player->pos.y = ((double)y + 0.5f);
	if (c == 'N')
		player->dir = parse_dir(0, -1);
	else if (c == 'E')
		player->dir = parse_dir(1, 0);
	else if (c == 'S')
		player->dir = parse_dir(0, 1);
	else if (c == 'W')
		player->dir = parse_dir(-1, 0);
	player->camera = rot(player->dir, 0.5f * M_PI);
	return (SUCCESS);
}

int	parse_map_line(char **lines, t_game *game, int y)
{
	int		x;
	t_map	*map;

	map = game->map;
	map->grid[y] = malloc(sizeof(t_tile) * (map->width + 1));
	if (!map->grid[y])
		return (FAILURE);
	x = 0;
	while (x < map->width)
	{
		if (x >= ft_strlen(lines[y]))
			map->grid[y][x] = TILE_VOID;
		else
			map->grid[y][x] = parse_tile(lines[y][x]);
		if (map->grid[y][x] == TILE_PLAYER)
		{
			if (!parse_player(game, y, x, lines[y][x]))
				return (FAILURE);
		}
		if (map->grid[y][x] == -2)
			return (FAILURE);
		x++;
	}
	return (SUCCESS);
}

int	count_sprites(char *line)
{
	int	count;
	int	i;

	count = 0;
	i = 0;
	while (line[i])
	{
		if (line[i] >= 'a' && line[i] <= 'z')
			count++;
		i++;
	}
	return (count);
}

int	prepare_map(char **lines, t_game *game)
{
	int		y;
	t_map	*map;

	map = game->map;
	y = 0;
	map->n_sprites_max = 0;
	map->n_sprites = 0;
	while (lines[y])
	{
		map->n_sprites_max += count_sprites(lines[y]);
		y++;
	}
	map->height = y;
	map->width = map_width(lines);
	map->grid = malloc(sizeof(t_tile *) * (map->height + 1));
	if (!map->grid)
		return (FAILURE);
	ft_memset(map->grid, 0, sizeof(t_tile *) * (map->height + 1));
	printf(" n_sprite_max %d\n", map->n_sprites_max);
	map->sprites = malloc(sizeof(t_sprite) * (map->n_sprites_max + 1));
	if (!map->sprites)
		return (FAILURE);
	ft_memset(map->sprites, 0, sizeof(t_sprite) * (map->n_sprites_max + 1));
	return (SUCCESS);
}

int	parse_map_line_sprites(char *line, t_game *game, int y)
{
	int				x;
	t_map			*map;
	t_sprite_lib	*sprite_lib;

	map = game->map;
	sprite_lib = map->sprite_lib;
	x = 0;
	while (line[x])
	{
		if (line[x] >= 'a' && line[x] <= 'z')
		{
			if (sprite_lib[line[x] - 'a'].texture == NULL)
			{
				ft_putstr_fd("Error: Undefined sprite symbol\n", 2);
				return (FAILURE);
			}
			map->sprites[map->n_sprites] = make_sprite(
					&sprite_lib[line[x] - 'a'],
					(double)x + 0.5f, (double)y + 0.5f);
			map->n_sprites++;
		}
		x++;
	}
	return (SUCCESS);
}

int	parse_map(char **lines, t_game *game)
{
	int		y;
	t_map	*map;

	map = game->map;
	if (!prepare_map(lines, game))
		return (FAILURE);
	y = 0;
	while (y < map->height)
	{
		if (!parse_map_line(lines, game, y))
			return (FAILURE);
		if (!parse_map_line_sprites(lines[y], game, y))
			return (FAILURE);
		y++;
	}
	return (SUCCESS);
}
