/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   ft_atoi_base.c                                     :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: jayang <[email protected]>                      +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2022/02/09 14:32:56 by jayang            #+#    #+#             */
/*   Updated: 2022/02/09 17:50:29 by jayang           ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include <unistd.h>

char	*ft_space_special(char *str, int *minus) // 공백 건너뛰고, 음양 판단
{
	while (*str == ' ' || (9 <= *str && *str <= 13))
		str++;
	*minus = 1;
	while (*str == '+' || *str == '-')
	{
		if (*str == '-') // '-' 나올 때마다 -1 곱함
			*minus *= -1;
		str++;
	}
	return (str); // 연산이 끝난 str 주소 리턴
}

int	check_base_error(char	*base) // base 문자열 오류 체크
{
	int	idx;
	int	target;

	idx = 0;
	while (base[idx])
	{
		target = 0;
		if (base[idx] == '+' || base[idx] == '-') // +, - 기호 거름
			return (0);
		else if (!(' ' <= base[idx] && base[idx] <= '~')) // 출력 가능한 애들만 있어야 함
			return (0);
		while (target < idx) // idx가 증가할 때마다 0부터 idx-1만큼 계속해서 중복체크
		{
			if (base[target] == base[idx])
				return (0);
			target++;
		}
		idx++;
	}
	if (idx <= 1) // base의 idx가 1이하라고 판단될 경우 진수 계산이 불가능하다고 판단.
		return (0);
	return (1);
}

int nb_base(char c, char *base) // base를 밑으로 하는 문자를 치환
{                               // 동시에 c가 base 문자열 내에 없으면 -1 리턴.
	int nb;
	
	nb = 0;
	while (base[nb])
	{
		if (c == base[nb]) // 입력받은 문자와 같은 값이 있을 경우
			return (nb);     // 해당 인덱스에 해당하는 값을 리턴!!!!!
		nb++;              // ex) "0123456789abcdef"
	}                    // 16진수 f는 1
	return (-1);
}

int	ft_atoi_base(char *str, char *base)
{
	int 	minus; // 부호 판단
	int 	result; // 정수형 결과 저장용 변수
	int		base_rdx; // base 진수 확인용

	if (check_base_error(base)) // base 예외처리
	{
		str = ft_space_special(str, &minus); // 공백 건너뛰고, 음/양 판단
		base_rdx = 0;
		while (base[base_rdx]) // base 크기를 세어 밑을 확인
				base_rdx++;          // ex) base 크기가 16이면 16진수를 밑으로 하는 str 문자열
 		result = 0;
		while (nb_base(*str, base) != -1)
		{
			result = (result * base_rdx) + nb_base(*str, base);
					// 나머지(역순) *   자릿수   + (base 문자열의 str 인덱스 값을 가져옴)
			str++;
		}
		return (minus * result); // 결과 리턴
	}
	return (0); // base가 null이거나 size가 1일 경우
}