// C/C++ File
// AUTHOR:   fotonmootn
// FILE:     inc/fdf.h
// ROLE:     to rule them all
// CREATED:  2017-02-13 20:07:04
// MODIFIED: 2017-03-18 02:33:34


#ifndef FDF_H
# define FDF_H

#include "libft.h"
#include "mlx.h"
#include <math.h>
#include <fcntl.h>

# define HEIGHT			700
# define WIDTH			700
# define COLOR1			0
# define COLOR2			16777215
# define INIT_X			30
# define INIT_Y			-20
# define INIT_Z			-45
# define INIT_X_SCALE	0.9
# define INIT_Y_SCALE	0.9
# define INIT_Z_SCALE	0.1

typedef struct	s_swap
{
	int 		swap_x;
	int 		swap_z;
	int 		swap_coord;
}				t_swap;


typedef struct 	s_color
{
	int 		red;
	int 		green;
	int 		blue;
}				t_color;

typedef struct	s_vec
{
	float		x;
	float		y;
	float		z;
}				t_vec;

typedef struct	s_pnt
{
	int 		x;
	int 		y;
	float 		z;
	t_color		color;
}				t_pnt;

typedef struct 	s_line
{
	t_pnt		p1;
	t_pnt		p2;
}				t_line;

typedef struct	s_mw
{
	void		*mlx;
	void		*win;
}				t_mw;

typedef struct	s_mat4
{
	double 		mx[4][4];
}				t_mat4;

typedef struct	s_trnsf
{
	t_mat4		*tr;
	t_mat4		*sc;
	t_mat4		*vp;
	t_mat4		*pr;
	t_mat4		*xr;
	t_mat4		*yr;
	t_mat4		*zr;
	t_mat4		*vp_pr_tr;
	t_mat4		*fin;
}				t_trnsf;

typedef struct	s_map
{
	t_trnsf		*trnsf;
	t_vec		**arr_vec;
	t_pnt		**arr_pnt;
	t_color		*low;
	t_color		*high;
	int 		x_max;
	int 		y_max;
	int 		z_max;
	int 		z_min;
	int 		z_rot;
	int 		x_rot;
	int 		y_rot;
	float 		scale[3];
}				t_map;

typedef struct 	s_FDF
{
	t_map		*map;
	t_mw		*mw;
	int 		w_height;
	int 		w_width;
	int 		bpp;
	int 		line_size;
	void 		*image;
	char 		*image_data;
	int 		endian;
}				t_FDF;

void			parse_input(int ac, char **av, t_FDF **FDF);

t_map			*map_init(char *path);

void			pnt_init(t_map *map);
t_mat4			*mat4_init(void);

t_trnsf			*trnsf_mat_init();
t_mat4 			*viewport_mat_init(int x, int y);

t_mat4			*orth_mat_init(float r, float t, float f);
void			initial_trnsf_mats(t_FDF *FDF);
void			mat4_mult_chain(t_trnsf *tf);
void			viewport_projection_translate(t_trnsf *tf);
void			mat4_translate(t_mat4 *m, double x, double y, double z);
void			mat4_scale(t_mat4 *m, double x, double y, double z);

void			mat4_z_rot(t_mat4 *m, double angle);
void			mat4_x_rot(t_mat4 *m, double angle);
void			mat4_y_rot(t_mat4 *m, double angle);
void			vec_mat_mult(t_mat4 *m, t_vec *v, t_pnt *result);

t_mat4			*mat4_mult(t_mat4 *m1, t_mat4 *m2);

void			transform(t_mat4 *mat, t_map *map);
void			recalculate_trnsf_matrs(t_map *map);
void			center(t_map *map);

int 			tab_length(char **tab);

void			free_tab(char **tab);
void			quit(t_FDF *FDF);
void			swap_init(t_swap *s);
void			print_help(void);
t_color			color_init(int red, int green, int blue);
t_color			color_lerp(t_color c1, t_color c2, double step);

t_color			int_to_color(int c);
int				color_to_int(t_color c);
t_color			choose_color(t_line *line, t_swap *s);
void			first_color(t_pnt *pnt, float z, t_map *map);
t_mw			*mlx_and_win_ptr_init(int x, int y);
t_FDF			*FDF_init(char *path, t_color *low, t_color *high);

int     		key_hook(int keycode, void *m);

void			line(t_pnt p1, t_pnt p2, t_FDF *FDF);
void			render(t_FDF *FDF);
void			put_pixel_to_image(t_line *line, t_swap *s, t_FDF *FDF);

void			left_rot(t_FDF *FDF);
void			right_rot(t_FDF *FDF);
void			forw_rot(t_FDF *FDF);
void			back_rot(t_FDF *FDF);
void			clock_rot(t_FDF *FDF);
void			aclock_rot(t_FDF *FDF);
void			scale_up_z(t_FDF *FDF);
void			scale_down_z(t_FDF *FDF);
void			zoom_in(t_FDF *FDF);
void			zoom_out(t_FDF *FDF);
void			reset(t_FDF *FDF);

#endif
