import java.io.*;
import fi.jyu.mit.ohj2.*;
import java.util.*;
/**
 * Kerhon harrastukset joka osaa mm. lisätä uuden harrastuksen
 *
 * @author Vesa Lappalainen
 * @version 1.0, 20.03.2003
 */
public class Harrastukset {
  private boolean muutettu = false;
  private String nimi = "";
  private Collection alkiot = new ArrayList();

  public Harrastukset() {  }

  /**
   * Lisää uuden harrastuksen tietorakenteeseen.  Ottaa harastuksen omistukseensa.
   * @param har lisätäävän harrastusken viite.
   *            Huom tietorakenne muuttuu omistajaksi.
   */
  public void lisaa(Harrastus har) {
    alkiot.add(har);
    muutettu = true;
  }


  /**
   * Lukee harrastukset tiedostosta.
   * @param tied tiedoston nimen alkuosa
   * @throws SailoException jos lukeminen epäonnistuu
   */
  public void lue_tiedostosta(String tied) throws SailoException {
    nimi = tied;
    BufferedReader fi = Tiedosto.avaa_lukemista_varten(getTiedoston_nimi());
    if ( fi == null ) throw new SailoException("Tiedosto " + getTiedoston_nimi() + " ei aukea");

    String rivi;
    try {
      while ( ( rivi = fi.readLine() ) != null ) {
        rivi = rivi.trim();
        if ( rivi.equals("") || rivi.startsWith(";") ) continue;
        Harrastus har = new Harrastus();
        har.parse(rivi);  // voisi olla virhekäsittely
        lisaa(har);
      }
      muutettu = false;

    } catch ( IOException e ) {


    } finally {
      try {
        fi.close();
      } catch (IOException ex) {
      }
    }
  }

  /**
   * Tallentaa harrastukset tiedostoon.
   * @throws SailoException jos talletus epäonnistuu
   */
  public void talleta() throws SailoException {
    if ( !muutettu ) return;

    File fbak  = new File(getBak_nimi());
    File ftied = new File(getTiedoston_nimi());
    if ( !fbak.delete() )         ; //System.err.println("Ei voi tuhota");
    if ( !ftied.renameTo(fbak) )  ; //System.err.println("Ei voi nimetä");

    PrintWriter fo = Tiedosto.avaa_kirjoittamista_varten(ftied.getName());
    if ( fo == null )
      throw new SailoException("Tiedosto " + ftied.getName() + "ei aukea");
    try {
      for (Iterator i=iterator(); i.hasNext(); ) {
        Harrastus har = (Harrastus)i.next();
        fo.println(har.toString());
      }
    } finally {
      fo.close();
    }

    muutettu = false;
  }

  /**
   * Palauttaa kerhon harrastusten lukumäärän
   * @return harrastusten lukumäärä
   */
  public int getLkm()                    { return alkiot.size();               }

  /**
   * Palauttaa tiedoston nimen, jota käytetään tallennukseen
   * @return tallennustiedoston nimi
   */
  public String getTiedoston_nimi()      { return nimi + ".har";               }

  /**
   * Palauttaa varakopiotiedoston nimen
   * @return varakopiotiedoston nimi
   */
  public String getBak_nimi()            { return nimi + ".hbak";              }

  /**
   * Palauttaa iteraattorin jolla kaikki harrastukset voidaan käydä lävitse
   * @return iteraattori kaikkien läpikäymiseen
   */
  public Iterator iterator() {
    return alkiot.iterator();
  }

  /**
   * Iteraattori, jolla käydään lävitse tietyn henkilön harrastukset.
   * @author Vesa Lappalainen
   * @version 1.0, 20.03.2003
   */
  public class HarrastuksetIterator implements Iterator {
    private int jasenid;
    private Iterator iter = alkiot.iterator();
    private Harrastus seuraava = null;

    public HarrastuksetIterator(int jid) {
      jasenid = jid;
    }

    public boolean hasNext() {
      if ( seuraava != null ) return true;
      while ( true ) {
        if ( !iter.hasNext() ) return false;
        seuraava = (Harrastus)iter.next();
        if ( seuraava.getJasen_id()== jasenid ) return true;
      }
    }

    public Object next() throws NoSuchElementException {
      if ( seuraava != null ) {
        Harrastus pal = seuraava;
        seuraava = null;
        return pal;
      }
      while ( true ) {
        Harrastus har = (Harrastus)iter.next();
        if ( har.getJasen_id()== jasenid ) return har;
      }
    }

    public void remove() throws UnsupportedOperationException {
      throw new UnsupportedOperationException("Me ei poisteta");
    }

  }

  /**
   * Palauttaa iteraattorin jolla tietyn jäsenen harrastukset voidaan
   * käydä lävitse
   * @param jasen_id minkä jäsenen harrastukset iteroidaan
   * @return iteraattori valitun jäsenen harrastusten läpikäymiseen
   */
  public Iterator iterator(int jasen_id) {
    return new HarrastuksetIterator(jasen_id);
  }

  private static void testi(Object o) {
    Harrastus har = (Harrastus)o;
    System.out.print(har.getJasen_id() + " ");
    har.tulosta(System.out);
  }

  /**
   * Testiohjelma harrastuksille
   * @param args ei käytössä
   */
  public static void main(String args[]) {
    Harrastukset harrasteet = new Harrastukset();
    Harrastus pitsi1 = new Harrastus();
    pitsi1.vastaa_pitsin_nyplays(2);
    Harrastus pitsi2 = new Harrastus();
    pitsi2.vastaa_pitsin_nyplays(1);
    Harrastus pitsi3 = new Harrastus();
    pitsi3.vastaa_pitsin_nyplays(2);
    Harrastus pitsi4 = new Harrastus();
    pitsi4.vastaa_pitsin_nyplays(2);

    harrasteet.lisaa(pitsi1);
    harrasteet.lisaa(pitsi2);
    harrasteet.lisaa(pitsi3);
    harrasteet.lisaa(pitsi2);
    harrasteet.lisaa(pitsi4);

    System.out.println("============= Harrastukset testi =================");


    for (Iterator i=harrasteet.iterator(2); i.hasNext(); ) {
      testi(i.next());
    }
    { // Testataan toimiiko iteraattori ilman hasNextiä
      System.out.println("============= Iteraattori testi =================");
      Iterator i=harrasteet.iterator(2);
      System.out.println(i.hasNext() + " " + i.hasNext());
      testi(i.next());
      System.out.println(i.hasNext() + " " + i.hasNext());
      testi(i.next());
      System.out.println(i.hasNext() + " " + i.hasNext());
      testi(i.next());
      System.out.println(i.hasNext() + " " + i.hasNext());
    }

  }

}