#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "queue.h"

/*******************************
queueData
queueData är av typen void pekare och representerar ett element av godtycklig typ i en queueElem.
*******************************/

/*******************************
queueElem, *link
Representation Convention:
  En queueElem qe representerar en länk i en lista där qe->item representerar elementen i länken. qe->next är nästa queueElem i listan, NULL om qe är sista länken i listan.
Representation invariant:
  Sista länken i listan pekar på NULL, ingen länk pekar på en tidigare länk i listan.
*******************************/

/*******************************
queueRecord, *Queue
Representation Convention
  En queueRecord qr representerar en FIFO-kö där qr->number representerar antalet länkar i kön. qr->first och qr->last representerar första respektive sista elementet i kön. qr->current representerar den länk som iteratorn befinner sig på. Om kön blivit genomitererad pekar qr->current på NULL.
En tom kö representeras av att qr->number är likamed noll samt att qr->first, qr->last och qr->current alla pekar på NULL.
Representation invariant:
  qr->number är antalet länkar i kön. qr->first och qr->last pekar på första respektive sista länken i kön. De pekar på samma länk om endast ett länk finns och båda pekar på NULL om ingen länk finns i kön. 
*******************************/

/*******************************
newQueue()
PRE:  
POST: 
RETURNS: en tom Queue
*******************************/

Queue     newQueue(){
  Queue q = (Queue) malloc(sizeof(queueRecord));
  q->number = 0;
  q->first = NULL;
  q->last = NULL;
  q->current = NULL;
  return q;
}

/*******************************
enque(it, qr)
PRE:  
POST: lägger till en länk med element it sist i qr
Returns:
*******************************/

void      enque(QueueData it, Queue q){
  link l = (link) malloc(sizeof(queueElem));
  l->item = it;
  l->next = NULL;
  if (q->number) 
    q->last->next = l;
  else 
    q->first = l;
  q->last = l;
  q->number++;
  return;
}

/******************************
deque(qr)
PRE:  qr är inte tom
POST: tar bort första länken i qr, sätter iteratorn till NULL om den pekade på den första länken
RETURNS: elementet i första länken i qr
*******************************/

QueueData deque(Queue q){
  assert(q->first);
  QueueData it = q->first->item;
  link l = q->first;
  if (q->first == q->current)
    q->current = NULL;
  if (q->number == 1){
    q->first = NULL;
    q->last = NULL;
  } else {
    q->first = q->first->next;
  }
  free(l);
  q->number--;
  return it;
}

/*******************************
first(qr)
PRE:  
POST:
RETURNS: elementet i första länken i qr, NULL om qr är tom
*******************************/

QueueData first(Queue q){
  if (!q->number) return NULL;
  return q->first->item;
}

/*******************************
qLength(qr)
PRE:  
POST:
RETURNS: antalet länkar i qr
*******************************/

int       qLength(Queue q){
  return q->number;
}

/*******************************
itReset(qr)
PRE:  
POST: initierar iteratorn för qr
RETURNS:
*******************************/

void      itReset(Queue q){
  q->current = q->first;
}

/*******************************
itMore(qr)
PRE:  
POST: 
RETURNS: 1 om iteratorn pekar på en länk i kön, annars 0
*******************************/

int       itMore(Queue q){
  if (q->current)
    return 1;
  return 0;
}

/*******************************
itNext(qr)
PRE:  
POST: stegar fram iteratorn ett steg
RETURNS: returnerar elementet hos den länk iteratorn pekar sig på i qr. Returnerar NULL iteratorn inte pekar på någon länk
*******************************/

QueueData itNext(Queue q){
  QueueData it;
  if (q->current) {
    it = q->current->item;
    q->current = q->current->next;
  }  else it = NULL;
  return it;
}













