/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   ft_convert_base.c                                  :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: pbonilla <marvin@42.fr>                    +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2020/09/22 19:22:14 by pbonilla          #+#    #+#             */
/*   Updated: 2021/03/19 18:42:40 by pbonilla         ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "libft.h"
#include <stdio.h>

int				isinbase(char c, char *base)
{
	int			i;

	i = 0;
	while (base[i])
	{
		if (base[i] == c)
			return (i);
		++i;
	}
	return (-1);
}

long			ft_atoi_base(char *str, char *base)
{
	int			len_base;
	int			i;
	int			signe;
	long long	nbr;

	signe = 1;
	i = 0;
	nbr = 0;
	len_base = ft_strlen(base);
	while (str[i] == '-' || str[i] == '+')
	{
		if (str[i] == '-')
			signe *= -1;
		i++;
	}
	while (isinbase(str[i], base) >= 0)
	{
		nbr = (len_base * nbr) + isinbase(str[i], base);
		i++;
	}
	return (signe * nbr);
}

int				get_size_in_char(long long nbr, int len_base)
{
	int			i;

	i = 1;
	if (nbr < 0)
		++i;
	while (nbr / len_base)
	{
		nbr = nbr / len_base;
		++i;
	}
	return (i);
}

char			*write_base(char *str, long long nbr, char *base, int *i_sgn)
{
	int			len_base;
	long long	nb;

	len_base = ft_strlen(base);
	nb = nbr;
	if (nb < 0)
		nb *= -1;
	if (nb >= len_base)
	{
		str[i_sgn[0]] = base[nb % len_base];
		i_sgn[0] += 1;
		write_base(str, nb / len_base, base, i_sgn);
	}
	else
	{
		str[i_sgn[0]] = base[nb];
		if (i_sgn[1])
			str[i_sgn[0] + 1] = '-';
		str[i_sgn[0] + 1 + i_sgn[1]] = 0;
	}
	return (str);
}

char			*ft_convert_base(char *nbr, char *base_from, char *base_to)
{
	char		*str;
	int			len_base;
	int			size_char;
	long long	number;
	int			i_sgn[2];

	i_sgn[0] = 0;
	i_sgn[1] = 0;
	if (!nbr || !base_from || !base_to)
		return (NULL);
	number = ft_atoi_base(nbr, base_from);
	len_base = ft_strlen(base_to);
	size_char = get_size_in_char(number, len_base);
	if (!(str = malloc(sizeof(char) * (size_char + 1))))
		return (ft_strdup(""));
	if (number < 0)
		i_sgn[1] = 1;
	str = write_base(str, number, base_to, i_sgn);
	str[size_char] = 0;
	ft_rev_int_tab(str, size_char);
	return (str);
}