package cap19.grafo;

import cap13.insieme.*;
import java.util.Iterator;

public class Grafo
{ private Insieme<Nodo> nodi;
  private Nodo cerca(Nodo n)
  { Iterator<Nodo> i = dammiNodi();
    while (i.hasNext())
    { Nodo m = i.next();
      if (m.equals(n))
        return m;
    }
    return null;
  }
  public Grafo()
  { nodi = new InsiemeList<Nodo>();
  }
  public boolean aggiungiNodo(Nodo n)
  { return nodi.aggiungi(n);
  }
  public boolean rimuoviNodo(Nodo n)
  { if (nodi.rimuovi(n))
    { Iterator<Nodo> i = dammiNodi();
      while (i.hasNext())
        i.next().rimuoviAdiacenza(n);
      return true;
    }
    return false;
  }
  public boolean aggiungiArco(Arco a)
  { aggiungiNodo(a.sorgente());
    aggiungiNodo(a.destinazione());
    return cerca(a.sorgente()).aggiungiArco(a);
  }
  public boolean rimuoviArco(Arco a)
  { Nodo n = cerca(a.sorgente());
    if (n == null)
      return false;
    else
      return n.rimuoviArco(a);
  }
  public Iterator<Nodo> dammiNodi()
  { return nodi.iterator();
  }
  public Iterator<Arco> dammiArchi()
  { return new IteratoreArchi(dammiNodi());
  }
  private class IteratoreArchi implements Iterator<Arco>
  { Iterator<Nodo> i;
    Iterator<Arco> j;
    IteratoreArchi(Iterator<Nodo> i)
    { this.i = i;
      vaiPrimoConArchi();
    }
    private void vaiPrimoConArchi()
    { j = null;
      while (i.hasNext())
      { j = i.next().archiUscenti();
        if (j.hasNext())
          return;
        j = null;
      }
    }
    public boolean hasNext()
    { if (j == null)
        return false;
      if (j.hasNext())
        return true;
      vaiPrimoConArchi();
      return j != null;
    }
    public Arco next() throws IllegalStateException
    { if (j == null)
        throw new IllegalStateException();
      if (j.hasNext())
        return j.next();
      vaiPrimoConArchi();
      if (j == null)
        throw new IllegalStateException();
      return j.next();
    }
    public void remove() throws IllegalStateException
    { if (j == null)
        throw new IllegalStateException();
      j.remove();
    }
  }
}
