package espressioni;

// servono le collezioni

import java.util.*;

public class EspressioneSomma extends EspressioneIntera {

// componenti: una sequenza di espressioni intere; usiamo
// una sequenza perche' ci si aspetta che per esempio a+b e
// b+a siano stampate diversamente, anche se poi producono
// lo stesso risultato

  private LinkedList<EspressioneIntera> comp;

// costruttore: qui va clonata la lista, altrimenti non si
// sarebbe realizzato l'incapsulamento

  public EspressioneSomma(LinkedList<EspressioneIntera> c) {
    if(null==c)
      throw new RuntimeException("Tentativo di creazione di EspressioneSomma con insieme nullo");

    comp=(LinkedList<EspressioneIntera>) c.clone();

    // gli elementi di c non vanno clonati, dato che nessuna
    // espressione intera e' modificabile
  }

// il metodo get e' realizzato con un iteratore privato a
// questa classe

  public Iterator<EspressioneIntera> iterator() {
    return new IteratoreInteri(comp);
  }

// in questo caso, la classe dell'iteratore la mettiamo
// direttamente dentro la classe
// gli oggetti di questa classe sono quasi come gli
// iteratori di comp, pero' non hanno il metodo remove

  private class IteratoreInteri implements Iterator<EspressioneIntera> {
    private Iterator<EspressioneIntera> it;

    private IteratoreInteri(LinkedList<EspressioneIntera> s) {
      it=s.iterator();
    }

    public boolean hasNext() {
      return it.hasNext();
    }

    public EspressioneIntera next() {
      return it.next();
    }

    public void remove() {
      throw new UnsupportedOperationException("L'iteratore su espressioni intere non permette la rimozione");
    }
  }

// toString

  public String toString() {
    return comp.toString();
  }

// equals

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

    EspressioneSomma s=(EspressioneSomma) o;

    return this.comp.equals(s.comp);
  }

// hashCode

  public int hashCode() {
    return comp.hashCode();
  }


// clone; si clona ogni componente, e poi ogni componente
// della componente, ecc.

  public Object clone() {
    // qui e' errore fare new
    EspressioneSomma s=(EspressioneSomma) super.clone();

    // per la lista, si poteva anche fare new
    s.comp=(LinkedList<EspressioneIntera>) s.comp.clone();

    ListIterator<EspressioneIntera> it=s.comp.listIterator();

    while(it.hasNext()) {
      EspressioneIntera a=(EspressioneIntera) it.next().clone();
      it.set(a);
    }

    return s;
  }

}

