//Capo: capo.cpp
// Definisce: Capo, Cintura, Vestiario
#include <iostream.h>
#include <iomanip.h>
#include "capo.h"

/******************************************************/
/* Classe Capo                                        */
/******************************************************/

/* Operatore di confronto (diverso).
 * Ritrona 'true' (-1) se un capo uguale a 'c' non e' compreso nella lista corrente,
 * 'false' (0) se e' contenuto */
int Capo::operator != (Capo *c)
{
  if (!c)                        // Se non ho la lista dei capi
    return -1;                   // Allora non ci sara' di sicuro dentro
  if (Genere != c -> Genere ||   // Se e' diverso il genere
    Modello != c -> Modello)     // Oppure e' diverso il modello
  {
    if (Next ())                 // Se c'e' un altro elemento in lista
      return Next () != c;       // Esegue il confronto sul resto della lista (niente cast, uso template)
    else                         // Se la lista e' finita, allora
      return -1;                 // Non e' contenuto nella lista, quindi 'true'
  }
  return 0;                      // Altrimenti ritorna 'false' - non sono diversi
}

/* Operatore di confronto (uguale): ritorna 'true' se il capo corrente
 * corrisponde ai criteri contenuti nella lista 'l', 'false' altrimenti */
int Capo::operator == (AttrList *l)
{
  return *l == Genere &&  // La lista deve corrispondere al genere
    *l == Modello;        // ed anche al modello (uso operator == di 'Attrlist')
}

void Capo::Pausa (int num)
{
  if ((num%24) == 0)                         // Se il numero corrente (la riga) e' divisibile per 24
  {
    cout << "Premi A-Capo per continuare";   // Stampa un prompt
    cin.ignore (10,'\n');                    // Ed attende un carattere
  }
}

void Capo::show (int num)
{
  Pausa (num);                                         // controlla se fermarsi
  cout << setw (2) << num << "|" <<                    // formatta la linea
  setw (30) << setiosflags (ios::left) << Genere.val () << "|" <<
  setw (30) << Modello.val () << setiosflags (ios::right) << "|   |" << endl;
  if (Next ())                                         // se c'e' un nuovo capo
    Next () -> show (num + 1);                         // continua la stampa (niente cast, uso template)
}

/******************************************************/
/* Classe Cintura                                     */
/******************************************************/

/* Operatore di confronto (diverso).
 * Ritrona 'true' (-1) se un capo uguale a 'c' non e' compreso nella lista corrente,
 * 'false' (0) se e' contenuto */
int Cintura::operator != (Capo *c)
{
  if (!c)                                 // Se non ho la lista dei capi
    return -1;                            // Allora non ci sara' di sicuro dentro
  if (Genere != ((Cintura *)c) -> Taglia) // Se la taglia e' diversa
  {
    if (Next ())                         // Se c'e' un altro elemento in lista
      return Next () != c;               // Esegue il confronto sul resto della lista (niente cast, uso template)
    else                                 // Se la lista e' finita, allora
      return -1;                         // Non e' contenuto nella lista, quindi 'true'
  }
  else
    return Capo::operator != (c);        // Se la taglia non corrisponde, confronta il resto della lista
}

/* Operatore di confronto (uguale): ritorna 'true' se il capo corrente
 * corrisponde ai criteri contenuti nella lista 'l', 'false' altrimenti */
int Cintura::operator == (AttrList *l)
{
  return Capo::operator == (l) &&  // La lista deve corrispondere secondo i criteri di 'Capo'
    *l == Taglia;                  // ed anche per la Taglia
}

void Cintura::show (int num)  // identica a quella della superclasse, ma stampa tutti gli attributi
{
  Pausa (num);
  cout << setw (2) << num << "|" <<
  setw (30) << setiosflags (ios::left) << Genere.val () << "|" <<
  setw (30) << Modello.val () << setiosflags (ios::right) << "|" <<
  setw (3) << Taglia.val () << "|" << endl;
  if (Next ())
  Next () -> show (num + 1); //  (niente cast, uso template)
}

/******************************************************/
/* Classe Vestiario                                   */
/******************************************************/

/* Operatore di confronto (diverso).
 * Ritrona 'true' (-1) se un capo uguale a 'c' non e' compreso nella lista corrente,
 * 'false' (0) se e' contenuto */
int Vestiario::operator != (Capo *c)
{
  if (!c)                                   // Se non ho la lista dei capi
    return -1;                              // Allora non ci sara' di sicuro dentro
  if (Genere != ((Vestiario *)c) -> Colore) // Se il colore e' diverso
  {
    if (Next ())                         // Se c'e' un altro elemento in lista
      return Next () != c;               // Esegue il confronto sul resto della lista (niente cast, uso template)
    else                                 // Se la lista e' finita, allora
      return -1;                         // Non e' contenuto nella lista, quindi 'true'
  }
  else
    return Cintura::operator != (c);     // Se la taglia non corrisponde, confronta il resto della lista
}

/* Operatore di confronto (uguale): ritorna 'true' se il capo corrente
 * corrisponde ai criteri contenuti nella lista 'l', 'false' altrimenti */
int Vestiario::operator == (AttrList *l)
{
  return Cintura::operator == (l) &&  // La lista deve corrispondere secondo i criteri di 'Capo'
    *l == Colore;                     // ed anche per il Colore
}

void Vestiario::show (int num)  // identica a quella della superclasse, ma stampa tutti gli attributi
{
  Pausa (num);
  cout << setw (2) << num << "|" <<
  setw (30) << setiosflags (ios::left) << Genere.val () << "|" <<
  setw (30) << Modello.val () << setiosflags (ios::right) << "|" <<
  setw (3) << Taglia.val () << "|" << Colore.val () << endl;
  if (Next ())
    Next () -> show (num + 1); //  (niente cast, uso template)
}