/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   fractol.h                                          :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: gtertysh <marvin@42.fr>                    +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2017/03/16 20:59:04 by gtertysh          #+#    #+#             */
/*   Updated: 2017/03/25 17:36:38 by gtertysh         ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#ifndef FRACTOL_H
# define FRACTOL_H

# include "libft.h"
# include "mlx.h"
# include <math.h>
# include <pthread.h>
# include <time.h>

# define HEIGHT			700
# define WIDTH			1300

# define RED			16711680
# define ORANGE			16744448
# define YELLOW			16776960
# define GREEN			65280
# define BLUE			255
# define INDIGO			4915330
# define VIOLET			8323327
# define BLACK			0
# define WHITE			16777215

# define NUM_COLORS		8

# define FRAC_MAX_ITR	150

# define NUM_THREADS     24

typedef struct	s_complex
{
	long double	rl;
	long double	im;
}				t_complex;

typedef struct	s_move
{
	long double	x;
	long double	y;
	long double	z;
}				t_move;

typedef struct	s_color
{
	int			red;
	int			grn;
	int			blu;
}				t_color;

typedef struct	s_gradient
{
	t_color		grd[NUM_COLORS];
}				t_gradient;

typedef struct	s_frac_data
{
	t_complex	com_const;
	t_gradient	grd;
	t_move		mov;
	int			max_itr;
	int			com_rl_im_change;
	int			allow_mouse_change;
	int			frac_type;
}				t_frac_data;

typedef struct	s_image
{
	void		*ptr;
	char		*data;
	int			l_size;
	int			end;
	int			bpp;
}				t_image;

typedef t_color	(*t_frac_func)(t_frac_data *data, int x, int y);

typedef struct	s_fractol
{
	void		*mlx;
	void		*win;
	t_frac_data	*frac;
	t_frac_func fr_funcs[3];
	int			w_height;
	int			w_width;
	t_image		*img;
}				t_fractol;

typedef struct	s_thread_data
{
	t_fractol	fr;
	int			y_start;
	int			y_end;
	t_frac_func	fractal_func;
}				t_thread_data;

void			quit(t_fractol *fractol);
void			print_help(void);
void			parse_input(int ac, char **av);

t_color			gradient(float value, t_gradient gradient);
t_gradient		default_gradient(void);
t_gradient		random_gradient(void);

t_fractol		*fractol_init(void *mlx, int frac_type);

int				key_hook(int keycode, void *m);
int				mouse_move_hook(int x, int y, void *fr);
int				mouse_button_hook(int btn, int x, int y, void *fr);

void			put_pixel_to_image(int x, int y, t_color col, t_fractol *fr);
void			new_and_clear_image(t_fractol *fr);

void			complex_equal(double real, double imag, t_complex *c);

t_frac_data		*frac_init(int frac_type);
void			*fractal_routine(void *th_data);
t_color			julia(t_frac_data *ju, int x, int y);
t_color			mandelbrot(t_frac_data *ma, int x, int y);
t_color			ship(t_frac_data *sh, int x, int y);

void			fractal_fork(int frac_type);
void			parallel_fractal(t_fractol *fr);

void			zoom_in(t_fractol *frm, int x, int y);
void			zoom_out(t_fractol *fr);
void			zoom_in_key(t_fractol *fr);
void			zoom_out_key(t_fractol *fr);
void			move_left(t_fractol *fr);
void			move_right(t_fractol *fr);
void			move_up(t_fractol *fr);
void			move_down(t_fractol *fr);
void			reset(t_fractol	*fr);
void			change_limit_down(t_fractol *fr);
void			change_limit_up(t_fractol *fr);
int				change_real(t_fractol *fr, int x, int *start_x);
int				change_imagianry(t_fractol *fr, int x, int *start_x);
void			gradient_hook(t_fractol *fr);

void			julia_samples(t_fractol *fr, double real, double img);
void			mandelbrot_samples(t_fractol *fr, double x, double y);

#endif