1   package kerho;
2   import java.io.OutputStream;
3   import java.util.Collection;
4   import java.util.Iterator;
5   import java.util.List;
6   
7   import fi.jyu.mit.ohj2.IO;
8   import fi.jyu.mit.ohj2.Mjonot;
9   import fi.jyu.mit.ohj2.Syotto;
10  /**
11   * Käyttöliittymäluokka Kerho-ohjelmaan
12   * Kerho-ohjelman menujen testaus.  Vain Lisää jäsen toimii jotenkin.<br>
13   * Tarvitsee avukseen JAR-paketin:
14   * <a href="http://www.mit.jyu.fi/vesal/kurssit/ohj2/ali/Ali.jar">Ali.jar</a><br>
15   * Aliohjelmien dokumentaatio on:
16   * <a href="http://www.mit.jyu.fi/vesal/kurssit/ohj2/ali/index.html">\kurssit\ohj2\ali</a><br>
17   * <br>
18   *
19   * @author  Vesa Lappalainen
20   * @version 1.0, 09.02.2003
21   * @version 1.1, 17.02.2008
22   */
23  public class Naytto {
24  
25    /**
26     * Viite kerhoon, jota tämä käyttöliittymä käyttää
27     */
28    private final Kerho kerho;
29  
30    private static enum Rivinvaihto {
31       /** Ei tulosteta rivinvaihtoa */ 
32       EITULE,
33       /** Tulostetaan rivinvaihto   */ 
34       TULEE
35    };
36    
37    
38    /**
39     * Käyttöliittymän alustus.  Käyttöliittymälle PITÄÄ kerto mitä
40     * Kerho se käsittelee.
41     * @param kerho jota käsitellään
42     * @throws SailoException jos kerhoa ei ole tuotu parametrina
43     */
44    public Naytto(Kerho kerho) throws SailoException {
45      if ( kerho == null ) throw new SailoException("Kerho täytyy antaa!");
46      this.kerho = kerho;
47    }
48  
49    
50    /**
51     * Tulostaa merkkijonon ja rivinvaihdon jos printlf on tosi
52     * @param s tulostettava merkkijono
53     * @param printlf tulostetaanko (TULEE) rivinvaihto vai ei (EITULE)
54     */
55    private static void tulosta(String s, Rivinvaihto printlf) {
56      System.out.print(s);
57      if ( printlf == Rivinvaihto.TULEE ) System.out.println();
58    }
59  
60    
61    /**
62     * Tulostaa merkkijonon ja rivinvaihdon
63     * @param s Tulostettava rivi
64     */
65    private static void tulosta(String s) {
66      tulosta(s,Rivinvaihto.TULEE);
67    }
68  
69    
70    /**
71     * Tulostaa merkkijonon mutt ei rivinvaihtoa
72     * @param s Tulostettava rivi
73     */
74    private static void tulostaEiRV(String s) {
75      tulosta(s,Rivinvaihto.EITULE);
76    }
77  
78    
79    /**
80     * Tulostaa n kappaletta tyhjiä rivejä
81     * @param n tulostettavien tyhjien rivien lukumäärä
82     */
83    private static void tulostaRivinvaihtoja(int n) {
84      for (int i=0; i<n; i++) tulosta("");
85    }
86  
87    
88    /**
89     * Tulostaa kirjaimen ja tekstin alleviivattuna sekä tyhjää ympärille.
90     * <pre>
91     * Kutsu: otsikko('1',"Kissa istuu puussa");
92     * tulostaa:
93     * --- 4 tyhjää riviä
94     * 1. Kissa istuu puussa
95     * =====================
96     * --- 2 tyhjää riviä
97     * </pre>
98     * @param kirjain alkuun tulostettava kirjain
99     * @param teksti kirjaimen perään tulostettava. teksti
100    */
101   private static void otsikko(char kirjain, String teksti) {
102     tulostaRivinvaihtoja(4);
103     tulosta("" + kirjain + ". " + teksti);
104     tulosta(Mjonot.tayta("=",1+2+teksti.length()));
105     tulostaRivinvaihtoja(2);
106   }
107 
108   
109   /**
110    * Tulostaa "Ei toimi vielä" ja jää odottamaan näppäimen painallusta
111    */
112   private void eiToimi()  {
113     tulosta("Ei toimi vielä!");
114     IO.odota_jotakin();
115   }
116 
117   
118   /**
119    * Avustustoiminto
120    * @param valinta kirjain jolla toiminto aktivoitiin
121    */
122   private void avustus(char valinta) {
123     otsikko(valinta, "Avustus");
124     eiToimi();
125   }
126 
127   
128   /**
129    * Tulostaa jäsenen tiedot
130    * @param os tietovirta johon tulostetaan
131    * @param jasen tulostettava jäsen
132    */
133   private void tulosta(OutputStream os, final Jasen jasen) {
134     jasen.tulosta(os);
135     /*    
136     int jid = jasen.getTunnusnro();
137     for (Iterator<Harrastus> i=kerho.harrastusIterator(jid); i.hasNext(); ) {
138       Harrastus har = i.next();
139       har.tulosta(os);
140     }
141    */   
142     List<Harrastus> harrastukset = kerho.annaHarrastukset(jasen);
143     for (Harrastus har: harrastukset ) {
144         har.tulosta(os);
145     }
146   }
147 
148 
149   /**
150    * Kystään tiedot yhdelle jäsenelle.  Muutetaan suoraan jäsenen tietoja.
151    * @param jasen muutettava jäsen
152    * @return halusiko käyttäjä pois muutoksesta (false) vai onnistuiko muutos (true)
153    */
154   private boolean kysyTiedot(Jasen jasen) {
155     int kenttia = jasen.getKenttia(); 
156     int eka = jasen.ekaKentta();
157     for (int k=eka; k<kenttia; k++ ) {
158       while ( true ) { // Kysyy yhden kentän tietoja
159         String oletus = jasen.anna(k);  
160         // if ( jasen.kysytaanko(k) )
161         String vastaus = Syotto.kysy(jasen.getKysymys(k),oletus);
162         vastaus = Mjonot.poista_2_tyhjat(vastaus).trim();
163         if ( k == eka && "".equals(vastaus) ) return false;
164         if ( ".".equals(vastaus) ) return true;
165         if ( "q".equals(vastaus) ) return false;
166         String virhe = jasen.aseta(k,vastaus);
167         if ( virhe == null ) break;
168         System.out.println(virhe);
169         System.out.println("Annatko tiedon uudelleen.");
170       }  
171     }      
172     return true;
173   } 
174 
175 
176   /**
177    * Kysy tiedot uudelle jäsenelle.  Luodaan uusi jäsen ja rekisteröidään.
178    * Jos jäsentä ei halutakkaan lisätä, niin mahdolliset häneen liittyvät
179    * tiedot tulee poistaa.
180    * @return halutaanko vielä jatkaa (true) vai lopettaa kyseleminen (false)
181    */
182   private boolean kysyUusiJasen() {
183     Jasen jasen = new Jasen();
184     jasen.rekisteroi();
185     while ( kysyTiedot(jasen) ) {
186       tulosta("Lisätäänkö");
187       tulosta(System.out,jasen);
188       tulostaEiRV(":");
189       if ( IO.kylla_vastaus() ) {
190         try {
191           kerho.lisaa(jasen);
192           return true;
193         } catch ( SailoException ex ) {
194           tulosta(ex.getMessage());
195         }
196       }
197     }
198     kerho.poista(jasen.getTunnusnro());
199     return false;
200   }
201 
202   
203   /**
204    * Uuden jäsenen lisäys
205    * @param valinta kirjain jolla toiminto aktivoitiin
206    */
207   private void lisaaUusiJasen(char valinta) {
208     otsikko(valinta,"Uuden jäsenen lisäys");
209     while ( kysyUusiJasen() ); // NOPMD
210   }
211 
212   private static final Jasen apujasen = new Jasen();  
213   
214   /**
215    * Jäsenen tietojen etsiminen
216    * @param valinta kirjain jolla toiminto aktivoitiin
217    */
218   private void etsiJasenenTiedot(char valinta) {
219     
220     String sallitut = "?123456789ABCDEFGHIJKL";
221     char c;
222     
223     while ( true ) {
224         System.out.print("Valitse kenttä jonka mukaan etsitään: ");
225         c = IO.odota_nappain(sallitut, 'q', IO.MERKKI_ISOKSI);
226         if ( c == 'q') return;
227         if ( c != '?') break;
228         for (int k=apujasen.ekaKentta(); k<apujasen.getKenttia(); k++)
229             System.out.println("   " + sallitut.charAt(k) + ": " + apujasen.getKysymys(k));
230     }
231     
232     int k = sallitut.indexOf(c);
233     otsikko(valinta,"Etsi jäsenen tiedot");
234     String vastaus = Syotto.kysy("Anna etsittävä " + apujasen.getKysymys(k));
235     Collection<Jasen> loytyneet = kerho.etsi("*"+vastaus+"*",k);
236     
237     for (Jasen jasen:loytyneet) {
238         tulosta(System.out, jasen);
239         IO.odota_jotakin();
240     }    
241     
242   }
243 
244 
245   /**
246    * Ohjelman tulosteet, pitäisi tulla alimenu
247    * @param valinta kirjain jolla toiminto aktivoitiin
248    */
249   private void tulosteet(char valinta) {
250     otsikko(valinta,"Tulosteet");
251     tulosta("Toimii toistaiseksi vain näytölle");
252     tulosta("---------------------------------------------------------");
253 
254     int i = 0;
255      for ( Iterator<Jasen> it = kerho.iterator(); it.hasNext(); ) {
256       Jasen jasen = it.next();  
257     //for (Jasen jasen : kerho ) {
258       //Jasen jasen = kerho.annaJasen(i);
259       tulosta("Jäsen nro: " + i++);
260       tulosta(System.out,jasen);
261       tulosta("");
262     }
263 
264     tulosta("---------------------------------------------------------");
265     IO.odota_jotakin();
266   }
267   
268   
269   /**
270    * Tietojen korjailu
271    * @param valinta kirjain jolla toiminto aktivoitiin
272    */
273   private void tietojenKorjailu(char valinta) {
274     otsikko(valinta,"Tietojen korjailu");
275     eiToimi();
276   }
277 
278 
279   /**
280    * Jäsenmaksujen päivitys
281    * @param valinta kirjain jolla toiminto aktivoitiin
282    */
283   private void paivitaJasenmaksuja(char valinta) {
284     otsikko(valinta,"Päivitä jäsenmaksuja");
285     eiToimi();
286   }
287 
288 
289   /**
290    * Tulostaa ohjelman päämenun
291    */
292   private void paamenu() {
293     tulosta("\n\n\n\n");
294     tulosta("Jäsenrekisteri");
295     tulosta("==============");
296     tulosta("");
297     tulosta("Kerhossa " + kerho.getNimi()+ " on " +
298              kerho.getJasenia() + " jäsentä.");
299     tulosta("");
300     tulosta("Valitse:");
301     tulosta("   ?  = avustus");
302     tulosta("   0  = lopetus");
303     tulosta("   1  = lisää uusi jäsen");
304     tulosta("   2  = etsi jäsenen tiedot");
305     tulosta("   3  = tulosteet");
306     tulosta("   4  = tietojen korjailu");
307     tulosta("   5  = päivitä jäsenmaksuja");
308     tulostaEiRV("   :");
309   }
310 
311   
312   /**
313    * Silmukka jossa odotetaan näppäintä ja suoritetaan vastaava toiminto.
314    * 0:n painaminen lopettaa silmukan ja palaa kutsuvaan ohjelmaan.
315    * @return palauttaa 0 jos kaikki meni hyvin, 1 jos tuli virhe
316    */
317   public int paavalinta() {
318     char nappain;
319 
320     while ( true ) {
321 
322       paamenu();
323 
324       nappain = IO.odota_nappain("?012345",IO.EI_OLETUSTA,IO.MERKKI_ISOKSI);
325 
326       switch (nappain) {
327         case '?': avustus(nappain);               break;
328         case '0': return 0;
329         case '1': lisaaUusiJasen(nappain);        break;
330         case '2': etsiJasenenTiedot(nappain);     break;
331         case '3': tulosteet(nappain);             break;
332         case '4': tietojenKorjailu(nappain);      break;
333         case '5': paivitaJasenmaksuja(nappain);   break;
334         default : tulosta("Näin ei voi käydä!");  return 1;
335       }
336 
337     }
338   }
339 
340   
341   /**
342    * Tulostaa ohjelman logon
343    */
344   private void logo() {
345     tulosta("");
346     tulosta("      ###################################");
347     tulosta("      #   J Ä S E N R E K I S T E R I   #");
348     tulosta("      #     versio 9.95                 #");
349     tulosta("      #     Hannu Hanhi                 #");
350     tulosta("      ###################################");
351   }
352 
353 
354   /**
355    * Tulostaa ohjelman alkuohjeet
356    */
357   public void ohjeet() {
358     logo();
359     tulosta("");
360     tulosta("Tällä ohjelmalla ylläpidetään kerhon jäsenrekisteriä.");
361   }
362 
363 
364   /**
365    * Tulostaa loppukiitokset
366    */
367   public void kiitokset() {
368     tulosta("");
369     tulosta("KIITOS KÄYTÖSTÄ JA TERVETULOA UUDELLEEN");
370     tulosta("");
371     tulosta("");
372   }
373 
374 
375   /**
376    * Lukee kerhon tiedot levyltä.  Kysyy ensin käyttäjältä tiedoson nimen.
377    * @return palauttaa tyhjän merkkijonon jos kaikki menee hyvin, muuten
378    * virhetekstin
379    */
380   public String lueKerho() {
381     tulosta("Anna kerhon nimi>");
382     eiToimi();
383     try {
384       kerho.lueTiedostosta("kelmit");
385     } catch ( SailoException ex ) {
386       System.out.println(ex.getMessage());
387       return ex.getMessage();
388     }
389 
390     return "";
391   }
392 
393 
394   /**
395    * Tallentaa kerhon tiedot levylle.
396    * @return palauttaa tyhjän merkkijonon jos kaikki menee hyvin, muuten
397    * virhetekstin
398    */
399   public String talletaKerho() {
400     logo();
401 
402     tulosta("");
403 
404     tulosta("Talletus...");
405     try {
406       kerho.talleta();
407     } catch ( SailoException ex ) {
408       System.out.println(ex.getMessage());
409       return ex.getMessage();
410     }
411 
412     return "";
413   }
414 
415 
416   /**
417    * Ohjelman pääohjelma
418    * @param args komentorivin parametrit, ei käytössä vielä
419    */
420   public static void main(String[] args) {
421     Kerho kerho = new Kerho();
422 
423     try {
424       Naytto naytto = new Naytto(kerho);
425 
426       naytto.ohjeet();
427 
428       naytto.lueKerho();
429 
430       naytto.paavalinta();
431 
432       naytto.talletaKerho();
433 
434       naytto.kiitokset();
435     }
436     catch (Exception ex) {
437       System.out.println("VIRHE: " + ex.getMessage());
438     }
439   }
440 
441 }
442 
443