#include <stdio.h>
#define SIZE 10

typedef struct //definition of the struct
{
	int top;
	int arr[SIZE];
} st;

void init_stack(st *stack); 	//a function to initialize the stack (set top to -1)
int is_full(st *stack); 		//check if the stack is full
int is_empty(st *stack); 		//check if the stack is empty
int push(st *stack, int val); 	//push val into the stack
int pop(st *stack); 			//pop from the stack
int top(st *stack); 		//check stack's top element
int size(st *stack); 		//returns the stack's size
void print_stack(st *stack); 	//print the stack's elements


int main(void)
{
    st stack;
    init_stack(&stack);
    
    print_stack(&stack);
    printf("Top of stack: %d\n", top(&stack));
    
    push(&stack, 12); //push 12
    push(&stack, 13); //push 13
    push(&stack, 14); //push 14
    push(&stack, 15); //push 15
    
    print_stack(&stack);
    printf("Top of stack: %d\n", top(&stack));
	printf("Stack size: %d\n", size(&stack));
	
	pop(&stack); //pop 15
	print_stack(&stack);
    printf("Top of stack: %d\n", top(&stack));
	
	pop(&stack); //pop 14
	print_stack(&stack);
    pop(&stack); //pop 13
	print_stack(&stack);
    printf("Top of stack: %d\n", top(&stack));

    pop(&stack); //pop 12
    printf("Top of stack: %d\n", top(&stack));

	print_stack(&stack);
	pop(&stack); //nothing to pop
	print_stack(&stack);
    pop(&stack); //nothing to pop
	print_stack(&stack);
    
    push(&stack, 21);
    push(&stack, 22);
    push(&stack, 23);
    push(&stack, 24);
    push(&stack, 25);
    push(&stack, 26);
    push(&stack, 27);
    push(&stack, 28);
    push(&stack, 29);
    push(&stack, 30);
    push(&stack, 31); //stack is full, cannot push
    push(&stack, 31); //stack is full, cannot push

    
    return 0;
}

void init_stack(st *stack)
{
	stack->top = -1;
}

int is_full(st *stack)
{
	if (stack->top == SIZE-1)
		return 1;
	
	else return 0;
}

int is_empty(st *stack)
{
	if (stack->top == -1)
		return 1;
	else 
		return 0;
}

int push(st *stack, int val)
{
	if (is_full(stack))
	{
		printf("Stack is full! I cannot push!\n");
		return -1;
	}
	
	(stack->top)++;
	stack->arr[stack->top]=val;
	printf("I pushed %d\n", val);
	return 1;
}

int pop(st *stack)
{
	if (is_empty(stack))
	{
		printf("I cannot pop!\n");
		return -1;
	}
	
	(stack->top)--;
	printf("I popped %d\n", stack->arr[(stack->top)+1]);
	return stack->arr[(stack->top)+1];
}

int top(st *stack)
{
	if (is_empty(stack))
	{
		printf("Stack is empty!\n");
		return -1;
	}
	return stack->arr[stack->top];
}

int size(st *stack)
{
	return stack->top+1;
}

void print_stack(st *stack)
{
	int i;
	if (is_empty(stack))
		printf("Stack is empty!\n");
	else
	{
		printf("Stack:\n");
		for (i=stack->top; i>=0; i--)
			printf("%d\n",stack->arr[i]);
		printf("\n");
	}
}


