package esprbooleane;

// servono le liste, quindi importiamo questo package

import java.util.*;

public class EspressioneAnd extends EspressioneBooleana {

// un and e' una sequenza di espressioni, quindi si usa List
// invece che Set; come diritti di accesso usiamo il livello
// package, dato che questo campo deve essere accessibile
// dall'iteratore (vedi sotto)

  List<EspressioneBooleana> componenti;

// costruttore; creiamo una espressione vuota

  public EspressioneAnd() {
    componenti=new LinkedList<EspressioneBooleana>();
  }

// serve un meccanismo per poter creare una espressione che
// contiene un numero qualsiasi di elementi; usiamo un
// metodo per aggiungere espressioni

  public void add(EspressioneBooleana e) {
    componenti.add(componenti.size(), e);
  }

// serve un modo per leggere gli elementi di un and; il modo
// piu' facile, ma meno efficiente, e' quello di usare il
// metodo get delle liste

  public int size() {
    return componenti.size();
  }

  public EspressioneBooleana get(int index) {
    return componenti.get(index);
  }

// il modo migliore e' quello di definire un iteratore, dal
// momento che questo permette la scansione senza
// ricominciare ogni volta dall'inizio; definiamo un
// iteratore apposta per questi oggetti

  public Iterator<EspressioneBooleana> iteratoreAnd() {
    return new IteratoreAnd(this);
  }

// toString, come al solito

  public String toString() {
    String s="[";

    Iterator<EspressioneBooleana> i=componenti.iterator();

    while(i.hasNext())
      s=s+i.next();

     return s+"]";
  }

// va ridefinito equals; sfruttiamo come al solito quante
// piu' cose sono gia' implementate; in questo caso, il
// confronto di classi ereditato dalla sovraclasse e
// l'equals di List

  public boolean equals(Object o) {
    if(!this.stessaClasse(o))
      return false;

    EspressioneAnd e=(EspressioneAnd) o;

    return this.componenti.equals(e.componenti);
  }

// quando si ridefinisce toString va ridefinito anche
// hashCode

  public int hashCode() {
    int s=7;

    Iterator<EspressioneBooleana> i=componenti.iterator();

    while(i.hasNext())
      s=5*s+i.next().hashCode();

    return s;
  }

// clone: qui non basta il clone della sovraclasse, perche'
// poi vanno clonati sia la list che gli oggetti attaccati

  public Object clone() {
    EspressioneAnd e=(EspressioneAnd) super.clone();

    e.componenti=new LinkedList<EspressioneBooleana>();

    Iterator<EspressioneBooleana> i=this.componenti.iterator();

    while(i.hasNext())
      e.componenti.add(e.componenti.size(), (EspressioneBooleana) i.next().clone());

    return e;
  }

}

