/* Implémentation des piles par tableaux */
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>

#include "pile.h"

// Invariant de structure: nb_elem <= taille_max
struct pile {
	int taille_max;
	int nb_elem;
	int* tab;
};

pile_t* pile_vide(){
	pile_t* p = malloc(sizeof(pile_t));
	p->nb_elem = 0;
	p->taille_max = 10;
	p->tab = malloc(p->taille_max*sizeof(int));
	return p;
}

bool est_vide(pile_t* p){
	return (p->nb_elem == 0);
}

void empiler(pile_t* p, int x){
	// Redimensionner
	if(p->nb_elem == p->taille_max){
		int new_taille_max = 2 * p->taille_max;
		p->tab = realloc(p->tab, new_taille_max * sizeof(int));
		p->taille_max = new_taille_max;
	}
	// Empiler
	assert(p->nb_elem < p->taille_max);
	p->tab[p->nb_elem] = x;
	p->nb_elem++;
}

int depiler(pile_t* p){
	assert(!est_vide(p));
	int res = p->tab[p->nb_elem-1];
	p->nb_elem--;
	if (p->nb_elem <= p->taille_max/4){
		int new_taille_max = p->taille_max/2;
		p->tab = realloc(p->tab, new_taille_max * sizeof(int));
		p->taille_max = new_taille_max;
	}	
	return res;
}

void free_pile(pile_t* p){
	free(p->tab);
	free(p);
}


void affiche_pile(pile_t* p){
	for (int i = 0; i < p->nb_elem; ++i)
	{
		printf("%d ", p->tab[i]);
	}
	printf("\n");
}

int taille(pile_t* p){
	return p->nb_elem;
}