/* ************************************************************************** */
/*                                                                            */
/*                                                        ::::::::            */
/*   render_sprite_utils.c                              :+:    :+:            */
/*                                                     +:+                    */
/*   By: whaffman <whaffman@student.codam.nl>         +#+                     */
/*                                                   +#+                      */
/*   Created: 2025/05/14 21:21:57 by whaffman      #+#    #+#                 */
/*   Updated: 2025/05/18 12:51:23 by whaffman      ########   odam.nl         */
/*                                                                            */
/* ************************************************************************** */

#include "cub3d.h"

void	sort_sprites(t_game *game)
{
	int			i;
	int			j;
	t_sprite	key;

	i = 1;
	while (i < game->map->n_sprites)
	{
		key = game->map->sprites[i];
		j = i - 1;
		while (j >= 0 && game->map->sprites[j].dist < key.dist)
		{
			game->map->sprites[j + 1] = game->map->sprites[j];
			j--;
		}
		game->map->sprites[j + 1] = key;
		i++;
	}
}

void	calculate_sprite_dist(t_game *game)
{
	t_vec2		player_pos;
	int			i;

	i = 0;
	player_pos = game->player->pos;
	while (i < game->map->n_sprites)
	{
		game->map->sprites[i].dist = dist_point_line(game->map->sprites[i].pos,
				(t_vec2_line){player_pos, game->player->camera});
		i++;
	}
}

void	cam_fraction(t_game *game, t_sprite *sprite)
{
	t_vec2		ps;
	t_vec2		cam;
	double		frac_cam;
	double		frac_sprite;
	double		denominator;

	cam = game->player->camera;
	ps = sub(sprite->pos, game->player->pos);
	frac_cam = ps.y * game->player->dir.x - ps.x * game->player->dir.y;
	denominator = ps.x * cam.y - ps.y * cam.x;
	frac_sprite = cam.y * game->player->dir.x - cam.x * game->player->dir.y;
	sprite->cam_frac = NAN;
	if (denominator == 0 || (frac_sprite / denominator) < 0)
		return ;
	sprite->cam_frac = frac_cam / denominator;
	if (sprite->cam_frac < -1 || sprite->cam_frac > 1)
		sprite->cam_frac = NAN;
	return ;
}

unsigned int	calculate_alpha(int x, int y, double dist)
{
	int		alpha;

	dist = (dist > 1) * dist + (dist <= 1) * 1;
	alpha = 255.0 / dist;
	return (alpha);
}

unsigned int
	sample_texture_color(
		t_sprite *sprite,
		t_vec2_int tex,
		int n
	)
{
	mlx_texture_t	*texture;
	int				index;
	int				width;
	int				n_frames;

	n_frames = sprite->n_frames;
	width = sprite->texture->width / n_frames;
	texture = sprite->texture;
	index = (tex.x + n * width + tex.y * width * n_frames);
	index *= texture->bytes_per_pixel;
	return ((unsigned int)texture->pixels[index] << 24
		| (unsigned int)texture->pixels[index + 1] << 16
		| (unsigned int)texture->pixels[index + 2] << 8
		| (texture->pixels[index + 3] != 0) * sprite->alpha);
}
