/*
 *  StQ 01.12.2001
 *  Coda = Buffer Circolare:
 *    ADT con struttura
 *    su vettore statico (enqueue, dequeue, init)
 *  Utilizza il numero di elementi memorizzati per valutare le condizioni
 *  di full e empty
 */

#include <stdio.h>
#include <string.h>

#define QUEUE_SIZE 5
#define MAX_STR    10

#define FULL 0
#define EMPTY 1
#define OK 2
#define KO 3

struct queueStruct {
  int queueArray[QUEUE_SIZE];
  int head;
  int tail;
  int n;
  };

int enqueue (struct queueStruct *queue, int elemento);
int dequeue (struct queueStruct *queue, int *elemento);
void queueInit (struct queueStruct *queue);
void lettura (int *elemento);
void stampa (int elemento);

void main ( void )
{
  char scelta[MAX_STR];
  struct queueStruct queue;
  int elemento, status;

  queueInit (&queue);

  do {
    printf ("Effettua la scelta (en, de, fine): ");
    scanf ("%s", scelta);
   
    if (strcmp (scelta, "en") == 0) {
      lettura (&elemento);
      status = enqueue (&queue, elemento);
    } else
      if (strcmp (scelta, "de") == 0) {
        if (dequeue (&queue, &elemento) == OK) {
          stampa (elemento);
        }
      } else {
        if (strcmp (scelta, "fine") != 0) {
          printf ("Scelta errata!!!\n");
        }
      }
  } while (strcmp (scelta, "fine") != 0);

  return;
}

int enqueue ( struct queueStruct *queueP, int elemento )
{
  if (queueP->n == QUEUE_SIZE) {
    fprintf (stderr,
      "Queue Pieno: Impossibile inserire un ulteriore elemento!\n");
    return (KO);
  } else {
    queueP->n = queueP->n + 1;
    queueP->queueArray[queueP->tail] = elemento;
    queueP->tail = (queueP->tail+1) % QUEUE_SIZE; 
    return (OK);
  }
}

int dequeue ( struct queueStruct *queueP, int *elemento )
{
  if (queueP->n == 0) {
    fprintf (stderr,
      "Queue Vuoto: Impossibile estrarre un ulteriore elemento!\n");
    return (KO);
  } else {
    queueP->n = queueP->n - 1;
    *elemento = queueP->queueArray[queueP->head];
    queueP->head = (queueP->head+1) % QUEUE_SIZE; 
    return (OK);
  }
}

void
queueInit ( struct queueStruct *queueP )
{
  queueP->head = 0;
  queueP->tail = 0;
  queueP->n = 0;

  return;
}

/* lettura dati */
void lettura ( int *elemento )
{
  fprintf (stdout, "Elemento da introdurre = ");
  scanf ("%d", elemento);

  return;
}

/* visualizzazione dati */
void stampa ( int elemento )
{
  fprintf (stdout, "Elemento estratto = %d\n", elemento);

  return;
}




