#include "push_swap.h"

// size is initialized to 1 because the loop check the next element, so it will end one step before reaching it
// it checks the next one to avoid handle the first one with ->limit set to 1
int	sublist_size(t_stack *list)
{
	int	size;

	if (list == NULL)
		return (0);
	size = 1;
	while (list->next != NULL && list->next->limit != 1)
	{
		list = list->next;
		size++;
	}
	return (size);
}

int	nbr_element_smaller(t_stack *list, int size, int pivot)
{
	int	nbr;

	nbr = 0;
	while (size-- > 0)
	{
		if (list->n < pivot)
			nbr++;
		list = list->next;
	}
	return (nbr);
}

// pivot is the smallest of the bigger group
int	find_pivot(t_stack *list, int size)
{
	int		pivot;
	t_stack	*head;

	pivot = list->n;
	head = list;
	while (head->next && nbr_element_smaller(list, size, pivot) != size / 2)
	{
		head = head->next;
		pivot = head->n;
	}
	return (pivot);
}

int	divide_a(t_stack **a, t_stack **b, t_list *solution)
{
	int		list_size;
	int		pivot;
	t_stack	*first_rotate;

	first_rotate = NULL;
	list_size = sublist_size(*a);
	pivot = find_pivot(*a, list_size);
	(*a)->limit = 0;
	while (list_size-- > 0)
	{
		if ((*a)->n >= pivot)
		{
			if (!first_rotate)
				first_rotate = *a;
			ra(a, &solution);
		}
		else
			pb(b, a, &solution);
	}
	while (*a != first_rotate)
		rra(a, &solution);
	(*a)->limit = 1;
	(*b)->limit = 1;
	mark_step(solution, "divide_a");
	return (0);
}

int	divide_b(t_stack **a, t_stack **b, t_list *solution)
{
	int	list_size;
	int	pivot;
	t_stack	*first_rotate;

	first_rotate = NULL;
	list_size = sublist_size(*b);
	pivot = find_pivot(*b, list_size);
	(*b)->limit = 0;
	while (list_size-- > 0)
	{
		if ((*b)->n >= pivot)
			pa(a, b, &solution);
		else
		{
			if (!first_rotate)
				first_rotate = *b;
			rb(b, &solution);
		}
	}
	while (*b != first_rotate)
		rrb(b, &solution);
	(*a)->limit = 1;
	(*b)->limit = 1;
	mark_step(solution, "divide_b");
	return (0);
}

void	send_sublist_to_a(t_stack **a, t_stack **b, t_list *solution)
{
	int	list_size;

	list_size = sublist_size(*b);
	(*b)->limit = 0;
	while (list_size-- > 0)
		pa(a, b, &solution);
	(*a)->limit = 1;
	if (*b)
		(*b)->limit = 1;
	mark_step(solution, "send_sublist_to_a");
}

void	recursif_sort(t_stack **a, t_stack **b, t_list *solution)
{
	if (sublist_size(*a) > 4)
		divide_a(a, b, solution);
	else
	{

	//	sort_big(a, b, solution)
		mini_sort(a, solution);
//		minisort(a, solution);
		if (sublist_size(*b) > 4)
			divide_b(a, b, solution);
		else if (sublist_size(*b) > 0)
			send_sublist_to_a(a, b, solution);
		else
			return ;
	}
	recursif_sort(a, b, solution);
}

void	hugo_sort(t_stack **a, t_stack **b, t_list *solution)
{
	if (sublist_size(*a) <= 3)
		special_sort_3(a, b, solution);
	else if (sublist_size(*a) <= 5)
		special_sort_5(a, b, solution);
	else
		recursif_sort(a, b, solution);
}

