/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   sl_loop.c                                          :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: bchanot <bchanot@students.42.fr>           +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2016/11/02 19:11:21 by bchanot           #+#    #+#             */
/*   Updated: 2016/11/15 19:20:46 by bchanot          ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "ft_select.h"
#include <term.h>
#include <unistd.h>
#include <sys/ioctl.h>

static void	sl_unset_arg(t_inf *inf)
{
	char	**tmp;
	int		*ta;
	int		cpt;
	int		cpt2;

	tmp = (char **)ft_memalloc(sizeof(char *) * (inf->nb));
	tmp[inf->nb - 1] = 0;
	ta = (int *)ft_memalloc(sizeof(int) * (inf->nb - 1));
	cpt = 0;
	cpt2 = 0;
	while (inf->args[cpt2])
	{
		if (cpt2 != inf->cur)
		{
			tmp[cpt] = ft_strdup(inf->args[cpt2]);
			ta[cpt] = inf->selected[cpt2];
			cpt++;
		}
		cpt2++;
	}
	ft_memdel2((void ***)&inf->args);
	ft_memdel((void **)&inf->selected);
	inf->selected = ta;
	inf->args = tmp;
	inf->nb--;
}

static void	sl_move_cursor(unsigned long buff, t_inf *inf)
{
	struct winsize	w;
	int				col;

	ioctl(0, TIOCGWINSZ, &w);
	col = inf->nb / (w.ws_row - 1) - (!(inf->nb % (w.ws_row - 1)) ? 1 : 0);
	if (buff == UP || (buff == LEFT && !col))
		inf->cur = inf->cur > 0 ? inf->cur - 1 : inf->nb - 1;
	else if (buff == DOWN || (buff == RIGHT && !col))
		inf->cur = inf->cur < inf->nb - 1 ? inf->cur + 1 : 0;
	else if (buff == RIGHT && inf->cur + (w.ws_row - 1) < inf->nb)
		inf->cur += w.ws_row - 1;
	else if (buff == RIGHT && inf->cur - (w.ws_row - 1) * col - 1 < inf->nb &&
			inf->cur - (((w.ws_row - 1) * col) - 1) >= 0)
		inf->cur -= ((w.ws_row - 1) * col) - 1;
	else if (buff == RIGHT)
		inf->cur -= (w.ws_row - 1) * (col - 1) - 1;
	else if (buff == LEFT && inf->cur - (w.ws_row - 1) >= 0)
		inf->cur -= w.ws_row - 1;
	else if (buff == LEFT && inf->cur + (w.ws_row - 1) * col - 1 < inf->nb &&
			inf->cur + ((w.ws_row - 1) * col) - 1 >= 0)
		inf->cur += (w.ws_row - 1) * col - 1;
	else if (buff == LEFT)
		inf->cur += (w.ws_row - 1) * (col - 1) - 1;
}

static void	sl_check_input(unsigned long buff, t_inf *inf, int *disp)
{
	if (buff == UP || buff == DOWN || buff == RIGHT || buff == LEFT)
		sl_move_cursor(buff, inf);
	else if (buff == SPACE)
	{
		inf->selected[inf->cur] = inf->selected[inf->cur] ? 0 : 1;
		if (inf->selected[inf->cur])
			inf->cur = inf->cur + 1 == inf->nb ? 0 : inf->cur + 1;
	}
	else if (buff == DELETE || buff == BACKSPACE)
	{
		sl_unset_arg(inf);
		inf->cur = inf->cur == inf->nb ? inf->cur - 1 : inf->cur;
	}
	else if (buff != ESCAPE && buff != ENTER)
		*disp = 0;
}

int			sl_launch_loop(t_inf *inf)
{
	unsigned long	buff;
	int				disp;

	buff = 0;
	sl_display_screen(inf);
	while (read(0, &buff, 6) != 0)
	{
		disp = 1;
		sl_check_input(buff, inf, &disp);
		if (buff == ESCAPE || buff == ENTER || !inf->nb)
			break ;
		if (disp)
			sl_display_screen(inf);
		buff = 0;
	}
	ft_putstr_fd(tgetstr("cl", NULL), 0);
	inf->term.c_lflag |= (ICANON | ECHO);
	tcsetattr(0, 0, &inf->term);
	ft_putstr_fd(tgetstr("te", NULL), 0);
	ft_putstr_fd(tgetstr("ve", NULL), 0);
	return (buff == ESCAPE || !inf->nb ? 0 : 1);
}
