#include <stdlib.h>
#include <stdio.h>

#include "iles.h"

lQueue *newEmptyQueue() {
  lQueue* pf = (lQueue *) malloc(sizeof(lQueue));
  pf->head = NULL;
  pf->queue = NULL;
  pf->length = 0;
  return pf;
}

lStack *newEmptyStack() {
  lStack* pp = (lStack *) malloc(sizeof(lStack));
  pp->top = NULL;
  pp->depth = 0;
  return pp;
}

int isEmptyQueue(lQueue *pf) {
  if (!pf) {
    fprintf(stderr, "isemptyqueue error: null queue !!");
    return -1;
  }
  return !(pf->length);
}

int isEmptyStack(lStack *pp) {
  if (!pp) {
    fprintf(stderr, "isemptystack error: null stack !!");
    return -1;
  }
  return !(pp->depth);
}

void sPush(void *pe, lStack *pp) {
  if (!pp) {
    fprintf(stderr, "spush error: null stack !!");
    return;
  }

  list curr = new_singleton_list(pe);
  curr->succ = pp->top;
  pp->top = curr;
  pp->depth++;
  if (DEBUG_TRACE) print_list_graph(pp->top, "after spush");
}

int sPop(void **ppe, lStack* pp) {
  if (!pp) {
    fprintf(stderr, "spop error: null stack !!");
    return -1;
  }
  if (isEmptyStack(pp)) return 0;
  *ppe = pp->top->content;
  list curr = pp->top;
  pp->top = pp->top->succ;
  pp->depth--;
  free(curr);
  if (DEBUG_TRACE) print_list_graph(pp->top, "after spop");
  return 1;
}

void qPush(void *pe, lQueue *pq) {
  if (!pq) {
    fprintf(stderr, "qpush error: null queue !!");
    return;
  }
  list curr = new_singleton_list(pe);
  curr->succ = pq->head;
  pq->head = curr;
  if (!(pq->queue)) pq->queue = curr;
  pq->length++;
  if (DEBUG_TRACE) print_list_graph(pq->head, "after qpush");
}

int qPop(void **ppe, lQueue* pq) {
  if (!pq) {
    fprintf(stderr, "qpop error: null queue !!");
    return -1;
  }
  if (isEmptyQueue(pq)) return 0;
  *ppe = pq->queue->content;
  if (pq->head == pq->queue) {/// ou si pf->length == 0
    free(pq->head);
    pq->head = pq->queue = NULL;
  } else {
    list curr = pq->queue;
    list prev = pq->head;
    while (prev->succ != curr) prev = prev->succ;
    pq->queue = prev;
    prev->succ = NULL;
    free(curr);
  }
  pq->length--;
  if (DEBUG_TRACE) print_list_graph(pq->head, "after qpop");
  return 1;
}
