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

struct cliente{
  unsigned int noggetti;
  struct cliente *prox;
};

/* prototipi */
struct cliente *inserisci_cliente(struct cliente *p, unsigned int n);
struct cliente *rimuovi_cliente(struct cliente *p);
unsigned int n_clienti(struct cliente *p);
unsigned int n_oggetti(struct cliente *p);

int main(int argc, char **argv){

  int n; /* numero casse */
  struct cliente **cassa; /* array di casse */
  int ii;
  char strin[51];
  char c;
  unsigned int ncassa, noggetti;

  printf("Inserire il numero di casse da gestire: ");
  scanf("%d",&n);
  c=getchar();

  //alloco e inizializzo l'array di casse
  cassa=malloc(sizeof(struct cassa*)*n);
  if(!cassa){
    fprintf(stderr,"Errore non sono riuscito ad allocare le casse\n");
    exit(EXIT_FAILURE);
  }
  for(ii=0;ii<n;++ii) 
    cassa[ii]=NULL;

  while(1){
    printf("Inserire il comando: ");
    fgets(strin,50,stdin);
    strin[strlen(strin)-1]='\0'; // elimino lo \n

    // caso STOP
    if(!strcmp(strin,"STOP"))
      exit(EXIT_SUCCESS);

    //caso STATUS
    if(!strcmp(strin,"STATUS")){
      // parte status
      for(ii=0;ii<n;++ii){
	printf("cassa %d: clienti %d oggetti %d\n",ii,n_clienti(cassa[ii]),n_oggetti(cassa[ii]));
      }
      continue;
    }

    //ciclo di analisi stringa
    ii=0;
    while(strin[ii]){
      // ignoro eventuale spazio
      if(strin[ii]==' '){
	++ii;
	continue;
      }
      // i primi due caratteri che incontro sono il numero cassa
      ncassa=(strin[ii]-'0')*10+(strin[ii+1]-'0');
      // i secondi due caratteri che incontro sono il numero di oggetti
      noggetti=(strin[ii+2]-'0')*10+(strin[ii+3]-'0');
      ii+=4;
      if(noggetti) // ovvero se e' un nuovo cliente
	cassa[ncassa]=inserisci_cliente(cassa[ncassa],noggetti);
      else
	cassa[ncassa]=rimuovi_cliente(cassa[ncassa]);
    }
  }
}

// inserimento in coda
struct cliente *inserisci_cliente(struct cliente *p, unsigned int n){
  if(!p){
    p=malloc(sizeof(struct cliente));
    p->prox=NULL;
    p->noggetti=n;
  }else{
    p->prox=inserisci_cliente(p->prox,n);
  }
  return p;
}


// rimozione in testa (in modo da rimuovere il piu' vecchio)
struct cliente *rimuovi_cliente(struct cliente *p){
  struct cliente *n;
  if(!p){
    fprintf(stderr, "Errore hai cercato di rimuovere un elemento da una coda vuota\n");
    exit(EXIT_FAILURE);
  }
 n=p->prox;
 free(p);
 return n;
}

// restituisce il numero clienti (in sostanza la dimensione della lista)
unsigned int n_clienti(struct cliente *p){
  if(!p) return 0;
  return 1 + n_clienti(p->prox);
}

// restituisce il numero oggetti (molto simile alla precedente)
unsigned int n_oggetti(struct cliente *p){
  if(!p) return 0;
  return p->noggetti + n_oggetti(p->prox);
}