package kerho;
import java.io.*;
import fi.jyu.mit.ohj2.*;
/**
 * Kerhon jäsen joka osaa mm. itse huolehtia tunnus_nro:staan.
 *
 * Muutokset:  02.04.2003, kenttien indeksointi<br>
 * Muutokset:  05.04.2004, tulostus myös PrintWriterilla<br>
 *
 * @author Vesa Lappalainen
 * @version 1.0, 22.02.2003
 * @version 1.3, 02.04.2003
 * @version 1.4, 05.04.2003
 */
public class Jasen {
  private Kentta kentat[] = {
    new IntKentta("id"),                           // 0
    new JonoKentta("nimi"),
    new HetuKentta("hetu",new HetuTarkistus()),    // 2
    new JonoKentta("katuosoite"),
    new JonoKentta("postinumero"),                 // 4
    new JonoKentta("postiosoite"),
    new JonoKentta("kotipuhelin"),                 // 6
    new JonoKentta("työpuhelin"),
    new JonoKentta("autopuhelin"),                 // 8
    new IntKentta("liittymisvuosi"),               // 9
    new RahaKentta("jäsenmaksu"),                  // A
    new RahaKentta("maksettu maksu"),              // B
    new JonoKentta("lisätietoja")                  // C
  };

  private static int seuraava_nro = 1;

  public Jasen() {  }

  public int getKenttia() { return kentat.length; }
  public int ekaKentta()  { return 1;  }

  /**
   * Antaa k:n kentän sisällön merkkijonona
   * @param k monenenko kentän sisältö palautetaan
   * @return kentän sisältö merkkijonona
   */
  public String anna(int k) {
    try {
      return kentat[k].toString();
    } catch (Exception ex) {
      return "";
    }
  }

  /**
   * Antaa k:n kentän sisällön avain-merkkijonona
   * jonka perusteella vi lajitella
   * @param k monenenko kentän sisältö palautetaan
   * @return kentän sisältö merkkijonona
   */
  public String getAvain(int k) {
    try {
      return kentat[k].getAvain();
    } catch (Exception ex) {
      return "";
    }
  }

  /**
   * Asettaa k:n kentän arvoksi parametrina tuodun merkkijonon arvon
   * @param k kuinka monennen kentän arvo asetetaan
   * @param jono jonoa joka asetetaan kentän arvoksi
   * @return null jos asettaminen onnistuu, muuten vastaav virheilmoitus.
   */
  public String aseta(int k,String jono) {
    try {
      return kentat[k].aseta(jono);
    } catch (Exception ex) {
      return "Virhe: " + ex.getMessage();
    }
  }

  /**
   * Palauttaa k:tta jäsenen kenttää vastaavan kysymyksen
   * @param k kuinka monennen kentän kysymys palautetaan (0-alkuinen)
   * @return k:netta kenttää vastaava kysymys
   */
  public String getKysymys(int k) {
    try {
      return kentat[k].getKysymys();
    } catch (Exception ex) {
      return "Ääliö";
    }
  }

  /**
   * Arvotaan satunnainen kokonaisluku välille [ala,yla]
   * @param ala arvonnan alaraja
   * @param yla arvonnan yläraja
   * @return satunnainen luku väliltä [ala,yla]
   */
  public static int rand(int ala, int yla) {
    double n = (yla-ala)*Math.random() + ala;
    return (int)Math.round(n);
  }


  /**
   * Apumetodi, jolla saadaan täytettyä testiarvot jäsenelle.
   * Henkilötunnus arvotaan, jotta kahdella jäsenellä ei olisi
   * samoja tietoja.
   */
  public void vastaa_aku_ankka() {
/*
    String apuhetu = Mjonot.fmt(rand(1,31),2,'0') +
                     Mjonot.fmt(rand(1,12),2,'0') +
                     Mjonot.fmt(rand(1,99),2,'0') + "-" +
                     Mjonot.fmt(rand(1,1000),3,'0') +
                     ( (char)((int)'A'+rand(1,25)));

    nimi           = "Ankka Aku";
    hetu           = apuhetu;
    katuosoite     = "Ankkakuja 6";
    postinumero    = "12345";
    postiosoite    = "ANKKALINNA";
    kotipuhelin    = "12-1234";
    tyopuhelin     = "";
    autopuhelin    = "";
    liittymisvuosi = 1996;
    jmaksu         = 50.00;
    maksu          = 30.00;
    lisatietoja    = "Velkaa Roopelle";
*/
  }

  /**
   * Tulostetaan henkilön tiedot
   * @param out tietovirta johon tulostetaan
   */
  public void tulosta(PrintWriter out) {
//    out.println(toString());
    int pisin = 0;
    for (int k=0; k<getKenttia(); k++)
      if ( kentat[k].getKysymys().length() > pisin )
        pisin = kentat[k].getKysymys().length();

    for (int k=0; k<getKenttia(); k++)
      out.println(Mjonot.fmt(kentat[k].getKysymys(),-pisin-1) +
                  ": " + kentat[k].toString());
/*
    out.println(Mjonot.fmt(tunnus_nro,3,'0')+ "  " + nimi + "  " + hetu);
    out.println("  " + katuosoite + "  " +  postinumero + " " + postiosoite);
    out.println("  k: " + kotipuhelin +
                " t: " + tyopuhelin  +
                " a: " + autopuhelin);
    out.print("  Liittynyt " + liittymisvuosi + ".");
    out.println("  Jäsenmaksu " + Mjonot.fmt(jmaksu,4,2) + " mk." +
                "  Maksettu "   + Mjonot.fmt(maksu,4,2)  + " mk.");
    out.println("  " + lisatietoja);
*/
  }

  /**
   * Tulostetaan henkilön tiedot
   * @param os tietovirta johon tulostetaan
   */
  public void tulosta(OutputStream os) {
    tulosta(new PrintStream(os));
  }

  /**
   * Tulostetaan henkilön tiedot
   * @param os tietovirta johon tulostetaan
   */
  public void tulosta(PrintStream out) {
    tulosta(new PrintWriter(out,true)); // ilman autoflushia ei mitään tulostu!
  }

  /**
   * Antaa jäsenelle seuraavan rekisterinumeron.
   * @return jäsenen uusi tunnus_nro
   */
  public int  rekisteroi() {
    ((IntKentta)(kentat[0])).setValue(seuraava_nro);
    seuraava_nro++;
    return getTunnus_nro();
  }


  /**
   * Saantimetodi jäsenen tunnusnumerolle
   * @return jäsenen tunnusnumero
   */
  public final int getTunnus_nro() { return ((IntKentta)(kentat[0])).getValue(); }


  /**
   * Muuttaa jäsenen tiedot |-erottetuksi merkkijonoksi
   * @return |-erotettu merkkijono
   */
  public String toString() {
    StringBuffer sb = new StringBuffer("");

    for (int k=0; k<getKenttia(); k++)
      sb.append(anna(k) + "|");
    return sb.toString();
  }

  /**
   * Otetaan jäsenen tiedot merkkijonosta joka on muotoa:<pre>
   * 1|Ankka Aku|130227-411J|Ankkakuja 6|12345|ANKKALINNA|12-1234|||1996|50.0|30.0|Velkaa Roopelle|
   * </pre>
   * @param rivi merkkijono josta tiedot otetaan.
   */
  public void parse(String rivi) {
    StringBuffer sb = new StringBuffer(rivi);
    for (int k = 0; k < getKenttia(); k++ )
      aseta(k,Mjonot.erota(sb,'|'));
    if ( getTunnus_nro() >= seuraava_nro ) seuraava_nro = getTunnus_nro() + 1;
  }


  /**
   * Tehdään identtinen klooni jäsenestä
   * @return Object kloonattu jäsen
   */
  public Object clone() {
    Jasen uusi = new Jasen();
    for (int k = 0; k < getKenttia(); k++ )
      uusi.aseta(k,anna(k));
    return uusi;
  }

  /**
   * Testiohjelma jäsenelle.
   * @param args ei käytössä
   */
  public static void main(String args[]) {
    Jasen aku = new Jasen(), aku2 = new Jasen();
    aku.rekisteroi();
    aku2.rekisteroi();
    aku.tulosta(System.out);
    aku.vastaa_aku_ankka();
    aku.tulosta(System.out);

    aku2.vastaa_aku_ankka();
    aku2.tulosta(System.out);

    aku2.vastaa_aku_ankka();
    aku2.tulosta(System.out);

    System.out.println(aku2.toString());
  }

}