/**********************************************************************\
* Kurzbeschreibung:
* queue.c - realisiert eine Queue (Warteschlange)
*
* Datum:     Autor:
*
\**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

/*--- Struktur eines Listenelements ----------------------------------*/

/*Ein Listenelement (Node) besteht aus:
 - value: dem gespeicherten Wert (hier ein int)
 - next:  Zeiger auf das nächste Element in der Liste
 */
typedef struct Node {
   int value;
   struct Node *next;
} Node_t;

/*--- Modulglobale Variablen: Zeiger auf Kopf und Ende der Liste -----*/

/*head: Zeigt auf das erste Element der Queue (Kopf)
 tail: Zeigt auf das letzte Element der Queue (Ende)
 Sind beide NULL, ist die Queue leer.*/
static Node_t *head = NULL;
static Node_t *tail = NULL;

/*--- put(): Einfügen am Ende der Liste ------------------------------*/
/*Fügt eine neue Zahl am Ende der Queue ein.
 Rückgabewert: TRUE bei Erfolg, FALSE bei Speicherfehler.*/
Bool put(int zahl) {
   // Speicher für neues Element reservieren
   Node_t *newNode = (Node_t *)malloc(sizeof(Node_t));
   if (newNode == NULL) {
       fprintf(stderr, "Speicher konnte nicht freigegeben werden.\n");
       return FALSE; // Fehler: kein Speicher verfügbar
   }
   newNode->value = zahl; // Wert setzen
   newNode->next = NULL;  // Am Ende zeigt next auf NULL

   if (tail != NULL) {
       // Es gibt schon Elemente: neues Element ans Ende anhängen
       tail->next = newNode;
   } else {
       // Die Liste war leer: head zeigt jetzt auf das neue Element
       head = newNode;
   }
   // tail zeigt immer auf das letzte Element
   tail = newNode;
   return TRUE;
}

/*--- get(): Entfernt das erste Element ------------------------------*/

/*Entfernt das erste Element (Kopf) der Queue und gibt dessen Wert zurück.
 Ist die Queue leer, wird QLEER zurückgegeben und eine Fehlermeldung ausgegeben.*/
int get(void) {
   if (head == NULL) {
       // Die Queue ist leer
       fprintf(stderr, "Fehler: Queue ist leer.\n");
       return QLEER;
   }
   Node_t *tmp = head;         // Temporärer Zeiger auf das erste Element
   int value = tmp->value;   // Wert des ersten Elements speichern
   head = head->next;        // Kopf auf das nächste Element setzen
   if (head == NULL) {
       // Nach dem Entfernen ist die Queue leer, also tail auch auf NULL setzen
       tail = NULL;
   }
   free(tmp);                // Speicher des entfernten Elements freigeben
   return value;             // Wert zurückgeben
}

/*--- isEmpty(): Prüft, ob Liste leer ist ----------------------------*/
/*
 * Gibt TRUE zurück, wenn die Queue leer ist, sonst FALSE.
 */
Bool isEmpty(void) {
   return head == NULL ? TRUE : FALSE;
}