#ifndef STACK_H
#define STACK_H
#include <stdlib.h>

struct stack_t
{
    struct stack_node_t *head;
    struct stack_node_t *rear;

    void (*enqueue)(struct stack_t *, int);
    void (*dequeue)(struct stack_t *, int *);
    void (*delete)(struct stack_t *);
};

struct stack_node_t
{
    int data;
    struct stack_node_t *next;
};

void enqueue(struct stack_t *self, int v)
{
    struct stack_node_t *n = (struct stack_node_t *)malloc(sizeof(struct stack_node_t));
    n->data = v;
    n->next = NULL;

    if (!self->head)
    {
        self->head = self->rear = n;
        return;
    }

    self->rear->next = n;
    self->rear = n;
}

void dequeue(struct stack_t *self, int *r)
{
    struct stack_node_t *p = self->head;
    while (p)
    {
        if (p->next == self->rear)
            break;
        p = p->next;
    }

    *r = self->rear->data;
    free(self->rear);
    p->next = NULL;
    self->rear = p;
}

void delete(struct stack_t *self)
{
    while (self->head)
    {
        struct stack_node_t *tmp = self->head;
        self->head = self->head->next;
        free(tmp);
    }

    self->head = NULL;
    self->rear = NULL;
}

void init_stack(struct stack_t *s)
{
    s->head = NULL;
    s->rear = NULL;
}

#endif // STACK_H
