/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   pf_p.c                                             :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: bchanot <bchanot@students.42.fr>           +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2016/02/27 01:51:30 by bchanot           #+#    #+#             */
/*   Updated: 2018/10/14 03:36:55 by bchanot          ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "libftprintf.h"
#include <stdlib.h>

static int	pf_width_p(char *s, t_inf inf, int len, void *p)
{
	int i;

	i = p == (void *)0 && inf.prec == -1 ? 0 : (int)ft_strlen(s);
	if (inf.prec > i)
	{
		if (len < inf.width - inf.prec)
			return (true);
	}
	else if (len < inf.width - i)
		return (true);
	return (false);
}

static char	get_digit(int n)
{
	if (n >= 0 && n <= 9)
		return (n + '0');
	return (n - 10 + 'a');
}

static char	*ft_ptoa(void *p)
{
	unsigned long	tmpn;
	unsigned long	n;
	int				len;
	char			*s;

	n = (unsigned long)p;
	tmpn = (unsigned long)p;
	len = 2;
	while (tmpn /= 16)
		len++;
	if (!(s = (char*)ft_memalloc(sizeof(char) * len)))
		return (NULL);
	s[--len] = '\0';
	while (len--)
	{
		s[len] = get_digit(n % 16);
		n = n / 16;
	}
	return (s);
}

static int	pf_p2(char *s, t_inf inf, int len)
{
	len += pf_putstr(s, inf.fd);
	if (inf.width > 0 && inf.min == 1)
		while (len < inf.width && len++ >= 0)
			ft_putchar_fd(' ', inf.fd);
	if (s)
		free(s);
	return (len);
}

int			pf_p(va_list ap, t_inf inf)
{
	char	*s;
	int		len;
	void	*p;
	int		cpt;

	p = va_arg(ap, void*);
	s = ft_ptoa(p);
	len = 2;
	if (inf.zero && inf.prec != 0)
		inf.zero = 0;
	if (inf.width > 0 && !inf.min && !inf.zero && inf.width > inf.prec)
		while (pf_width_p(s, inf, len, p) && len++ >= 0)
			ft_putchar_fd(' ', inf.fd);
	pf_putstr("0x", inf.fd);
	cpt = -1;
	if (inf.prec > 0)
		while (++cpt < inf.prec - ((int)ft_strlen(s)) && len++ >= 0)
			ft_putchar_fd('0', inf.fd);
	cpt = -1;
	if (inf.width && inf.zero && !inf.min)
		while (++cpt < inf.width - ((int)ft_strlen(s) + 2) && len++ >= 0)
			ft_putchar_fd('0', inf.fd);
	return (pf_p2(s, inf, len));
}
