import java.io.*;
import java.util.*;
import fi.jyu.mit.ohj2.*;
/**
 * Kerhon jäsenistö joka osaa mm. lisätä uuden jäsenen
 *
 * @author Vesa Lappalainen
 * @version 1.0, 22.02.2003
 * @version 1.1, 20.03.2003
 */
public class Jasenet {
  private static final int MAX_JASENIA = 25;
  private int lkm = 0;
  private boolean muutettu = false;
  private String nimi = "";
  private String koko_nimi = "";
  private Jasen alkiot[] = new Jasen[MAX_JASENIA];

  public Jasenet() {  }

  /**
   * Lisää uuden jäsenen tietorakenteeseen.  Ottaa jäsenen omistukseensa.
   * @param jasen lisätäävän jäsnen viite.  Huom tietorakenne muuttuu omistajaksi
   * @throws SailoException jos tietorakennen on jo täynnä
   */
  public void lisaa(Jasen jasen) throws SailoException {
    muutettu = true;
    if ( lkm >= alkiot.length ) throw new SailoException("Liikaa alkioita");
    alkiot[lkm] = jasen;
    lkm++;
  }


  /**
   * Palauttaa viitteen i:teen jäseneen.
   * @param i monennenko jäsenen viite halutaan
   * @return viite jäseneen, jonka indeksi on i
   * @throws SailoException jos i ei ole sallitulla alueella
   */
  public Jasen anna(int i) throws SailoException {
    if ( i < 0 || lkm <= i ) throw new SailoException("Laiton indeksi " + i);
    return alkiot[i];
  }





  /**
   * Lukee jäsenistön tiedostosta.  Kesken.
   * @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");

    try {
      koko_nimi = fi.readLine();
      if ( koko_nimi == null ) throw new SailoException("xxxxx");
      String rivi = fi.readLine();
      if ( rivi == null ) throw new SailoException("xxxxx");
      int max_koko = Mjonot.erotaInt(rivi,10); // tehdään jotakin

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


    } catch ( IOException e ) {


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

  /**
   * Tallentaa jäsenistön tiedostoon.  Kesken.
   * Tiedoston muoto:
   * <pre>
   * Kelmien kerho
   * 20
   * ; kommenttirivi
   * 2|Ankka Aku|121103-706Y|Ankkakuja 6|12345|ANKKALINNA|12-1234|||1996|50.0|30.0|Velkaa Roopelle
   * 3|Ankka Tupu|121153-706Y|Ankkakuja 6|12345|ANKKALINNA|12-1234|||1996|50.0|30.0|Velkaa Roopelle
   * </pre>
   * @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 {
      fo.println(getKoko_nimi());
      fo.println(alkiot.length);
      for (Iterator i=iterator(); i.hasNext(); ) {
        Jasen jasen = (Jasen)i.next();
        fo.println(jasen.toString());
      }
//    } catch ( IOException e ) {
    } finally {
      fo.close();
    }

    muutettu = false;
  }

  /**
   * Palauttaa Kerhon koko nimen
   * @return Kerhon koko nimi merkkijononna
   */
  public String getKoko_nimi()           { return koko_nimi;                   }

  /**
   * Palauttaa kerhon jäsenten lukumäärän
   * @return jäsenten lukumäärä
   */
  public int getLkm()                    { return lkm;                         }

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

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

  /**
   * Iteraattorin implementointi.
   * @author Vesa Lappalainen
   * @version 1.0, 20.03.2003
   */
  public class JasenetIterator implements Iterator {
    private int kohdalla = -1;

    public boolean hasNext() {
//     if ( kohdalla + 1 >= lkm )  return false;
//     return true;
      return kohdalla + 1 < lkm;
    }

    public Object next() throws NoSuchElementException {
      if ( !hasNext() ) throw new NoSuchElementException("Ei oo");
      kohdalla++;
      return alkiot[kohdalla];
    }

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

  /**
   * Palauttaa iteraattorin jolla kaikki jäsenet voidaan käydä lävitse
   * @return iteraattori kaikkien läpikäymiseen
   */
  public Iterator iterator() {
    return new JasenetIterator();
  }



  /**
   * Testiohjelma jäsenistölle
   * @param args ei käytössä
   */
  public static void main(String args[]) {
    Jasenet jasenet = new Jasenet();
    try {
      jasenet.lue_tiedostosta("kelmit");
    } catch ( SailoException ex ) {
      System.out.println("Virhe: " + ex.getMessage());
    }

    Jasen aku = new Jasen(), aku2 = new Jasen();
    aku.rekisteroi();    aku.vastaa_aku_ankka();
    aku2.rekisteroi();   aku2.vastaa_aku_ankka();

    try {
      jasenet.lisaa(aku);
      jasenet.lisaa(aku2);

      System.out.println("============= Jäsenet testi =================");

//      for (int i=0; i<jasenet.getLkm(); i++) {
      for (Iterator  i=jasenet.iterator(); i.hasNext(); ) {
//        Jasen jasen = jasenet.anna(i);
        Jasen jasen = (Jasen)i.next();
        System.out.println("Jäsen nro: " + jasen.getTunnus_nro());
        jasen.tulosta(System.out);
      }

    } catch ( SailoException ex ) {
      System.out.println(ex.getMessage());
    }

    try {
      jasenet.talleta();
    } catch ( SailoException e ) {
      System.out.println("Virhe: " + e.getMessage());
    }

  }

}