// mglifve g-1 o-4 k-inf1000/v08.

import easyIO.*;
import java.util.*;

/**
* Omsluttende klasse for problemet, tar opp parametre
* fra kommandolinja og starter kommandoløkka. Feilmelding
* hvis ikke minst to parametere.
*****************************************************/




class Oblig4 {
/**
* Sjekker parametere, starter opp ordreløkka etter at
* filene er lest via konstruktoren til 'MetInst'
*****************************************************/

    public static void main(String[] args) { // main metoden


        if (args.length >= 2) {
            MetInst m = new MetInst(args[0],args[1]);
            m.ordreløkke();

        }else{

            System.out.println("Bruk: >java Oblig4 <fil med Stasjonsdata> < fil med Observasjonsdata>"); // Må skrive System.out pga skjerm ikke deklareres før i class MetInst
        }
    }

}
/**Class MetInst*/
class MetInst{

    In tastatur = new In();
    Out skjerm = new Out();


    // Deklarere hashmappen her
    /**Her blit hashmapen deklarert. NB! Den ene er i integer for å slippe å gjøre om fra string til int senere i oppgaven*/

    HashMap <String,Stasjon> stasjonNavn = new HashMap <String,Stasjon>(); // Nøkkelen vil her være navnet
    HashMap <Integer,Stasjon> stasjonNumr = new HashMap <Integer,Stasjon>(); // Nøkkelen vil her være nummeret, og hashmapen er gjort om til en Integer






/**Konstruktøren*/
    MetInst(String stasjonsfil, String vaerdatafil) {            // Konstruktør


        //stasjonsfil = args[0]; // Dette er ikke nødvendig fordi args lastes automatisk inn i MetInst(String stasjonsfil(args[0]), String vaerdatafil(args[1]))
        //vaerdatafil = args[1];



        In sf = new In(stasjonsfil);
        In vf = new In(vaerdatafil);


        while (!sf.endOfFile()) {                                              //Kan man bruke en for løkke for å gå igjennom fila?!
            int nr = sf.inInt();            //  skjerm.out(nr+" ");
            String navn = sf.inWord();      //  skjerm.out(navn+" ");
            int moh = sf.inInt();           //  skjerm.out(moh+" ");
            String kommune = sf.inWord();   //  skjerm.out(kommune+" ");
            String fylke = sf.inWord();     //  skjerm.outln(fylke+" ");

            Stasjon værstasj = new Stasjon(nr, navn, moh, kommune, fylke);
            stasjonNavn.put(navn, værstasj);
            stasjonNumr.put(nr, værstasj);

            }




        while (!vf.endOfFile()) {
            int nr = vf.inInt();              //   skjerm.out(nr+" ");
            int dMnd = vf.inInt();            //   skjerm.out(dMnd+" ");
            int mnd = vf.inInt();             //   skjerm.out(mnd+" ");
            double maxVind = vf.inDouble();   //   skjerm.out(maxVind+" ");
            double nedbør = vf.inDouble();    //   skjerm.outln(nedbør+" ");
            double minTemp = vf.inDouble();   //   skjerm.out(minTemp+" ");
            double maxTemp = vf.inDouble();   //   skjerm.out(maxTemp+" ");

            Stasjon st = stasjonNumr.get(nr);
            st.settInn(dMnd, mnd, maxVind, nedbør, minTemp, maxTemp);

        }



   sf.close();
   vf.close();


   } // end MetInst (konstruktør)


/**Skriver ut meny til skjerm*/

    void skrivMeny() {
        skjerm.outln("");
        skjerm.outln("");
        skjerm.outln("*** Værdatasystem versjon 1.0 ***");
        skjerm.outln("");
        skjerm.outln("Du har følgende valgmuligheter:");
        skjerm.outln("");
        skjerm.outln("1 - Finn antall uværsdager");
        skjerm.outln("2 - Finn kommune med lavest temperatur");
        skjerm.outln("3 - Finn stasjon med mest nedbør");
        skjerm.outln("4 - avslutt");
        skjerm.outln("");
        skjerm.outln("");
    } // end void skriv meny




    void ordreløkke() {
        skrivMeny();
        int kommando = 0;

        while (kommando != 4){
            kommando = velgOperasjon();

            switch (kommando) {
                case 1: finnAntallUværsDager();             break;
                case 2: finnKommuneMedLavestTemperatur();   break;
                case 3: finnStasjonMedMestNedbør();         break;
                case 4: avslutt();                          break;
                default: skjerm.out("Du har tastet feil");  break;
            } // end switch
        } // end while

        skjerm.outln("Værdatasystemet avsluttes");

    }// end void ordreløkke

    int velgOperasjon() {
    skjerm.out("Velg en kommando: ");
    int kommando = tastatur.inInt();
    return kommando;
} // end velgOperasjon





/**Metode for å finne antall uværsdager*/

    void finnAntallUværsDager() {


        // Forsøker her å gå igjennom alle navnene i hashmapen og skrive det ut på skjerm...
    /*  Iterator it = stasjonNavn.keySet().iterator();
        while (it.hasNext()) {
            String Navn = (String) it.next();
            Stasjon st = (Stasjon) stasjonNavn.get(stasjonNavn);
            skjerm.outln(stasjonNavn);
        }

    */


      for ( Stasjon s : stasjonNavn.values() ) {
          skjerm.outln( s.stasjonNavn );
      }
    //    for ( Stasjon t : stasjonNumr.values() ) { // Blir ikke skrevet ut i riktig rekkefølge slik som i en array
    //      skjerm.outln(  t.stasjonNumr );          // Derfor fungerer det ikke å koble navn med nummer fra hashmapen
    //  }



        skjerm.outln("Finn antall uværsdager i en bestemt måned:");
        skjerm.outln("");
        skjerm.outln("For hvilken måned ønsker du å telle antall uværsdager: ");
        int tastMåned = tastatur.inInt();
        skjerm.outln("Velg om du vil identifisere stasjon med navn eller nummer ");
        skjerm.outln("Trykk '1' for navn eller '2' for nummer: ");
        int valg = tastatur.inInt();


        if(valg == 1) {

        skjerm.outln("For hvilken stasjon ønsker du å telle antall uværsdager: (bruk STORE bokstaver) ");
        String stasjon = tastatur.inWord(); // Bruker string for å slå opp etter navn, og ikke nummer

        Stasjon st = stasjonNavn.get(stasjon);

        if(st != null){

            if(tastMåned>=1 || tastMåned<=6){
            int antall = st.måned[tastMåned-1].telleUværsdager(); //har laget en egen metode for å telle uværsdager class maaned
            skjerm.outln("I måned nr " + tastMåned + " var det totalt " + antall + " uværsdager");
            skjerm.outln("");

        }
        }else{
                skjerm.outln("Finner ikke stasjon, eller så finnes det ikke data for denne stasjonen!");
            }
        }

        if(valg == 2) {

                skjerm.outln("For hvilken stasjon ønsker du å telle antall uværsdager: (bruk stasjonens nummer) ");
                int stasjon = tastatur.inInt(); // Bruker int for å slå opp etter nummer

                Stasjon st = stasjonNumr.get(stasjon);

                if(st != null){

                    if(tastMåned>=1 || tastMåned<=6){
                    int antall = st.måned[tastMåned-1].telleUværsdager(); //har laget en egen metode for å telle uværsdager class maaned
                    skjerm.outln("I måned nr " + tastMåned + " var det totalt " + antall + " uværsdager");
                    skjerm.outln("");

                }
                }else{
                        skjerm.outln("Finner ikke stasjon, eller så finnes det ikke data for denne stasjonen!");
                    }
        }

        else{
            skjerm.outln("");
        }



        } // end finnAntallUværsDager










/**Metode for å finne lavest temperatur i en kommune*/
    void finnKommuneMedLavestTemperatur() {

/*
        Iterator it = stasjonNavn.values().iterator();
        while(it.hasNext()){
            Stasjon st = (Stasjon) it.next();

            while(it.hasNext()){
                Maaned mn = (Maaned) it.next();

                while(it.hasNext()){
                    Dag dg = (Dag) it.next();


            Double a = st.mn.dg.finneMinTemp(); // Metode finneMinTemp ligger i class Stasjon

            skjerm.out(st.stasjonNavn);
            skjerm.outln(a);

        }
    }
}
*/
          double lavest = 0.0;
          String komLavest = null;


          for (Stasjon s : stasjonNavn.values()) { // blar gjennom stasjoner
             for (int i = 0; i < 6; i++) { // blar gjennom måneder
                if (s.måned[i] != null) { // sjekker om måneden eksisterer



                     double a = s.måned[i].finneMinTemp(); // Metode finneMinTemp ligger i class Stasjon

                     if(a < lavest){
                         lavest = a;
                         komLavest = s.stasjonsKommune;
                     }
                 }
             }
         }
         skjerm.out(komLavest + " ");
         skjerm.outln(lavest);

}// end lavestTemperatur



/**Metode for å finne stasjon med mest nedbør i en angitt måned*/
    void finnStasjonMedMestNedbør() {

        skjerm.outln("Finn stasjon med mest nedbør i en gitt måned:");
        skjerm.outln("");
        skjerm.outln("For hvilken måned ønsker du å finne hvilken stasjon som hadde mest nedbør: ");
        int tastMåned = tastatur.inInt();

        double maks = 0.0;
        String stMaks = null;




        if(tastMåned>=1 || tastMåned<=6){
            Iterator it = stasjonNavn.values().iterator();
            while(it.hasNext()){
                Stasjon st = (Stasjon) it.next();


            Double a = st.måned[tastMåned-1].telleMestNedbør(); // telleMestNedbør kaller på en metode i class maaned

            if( a > maks) {
                maks = a;
                stMaks = st.stasjonNavn;
            }

        }


            skjerm.out(stMaks + " ");
            skjerm.outln( maks );



            }else{
                skjerm.outln("Du har ikke tastet en måned mellom 1 og 6");
            }


        } // end mestNedbør





    void avslutt() {}





} // End class MetInst






/**Class Stasjon*/
class Stasjon{
    int stasjonNumr;
    String stasjonNavn;
    int meterOverHavet;
    String stasjonsKommune;
    String stasjonsFylke;

    Maaned[] måned = new Maaned[6]; // Array for måneder er plassert i class stasjon, og det vil registreres maks 6 måneder med data

    Stasjon(int nr, String navn, int moh, String kommune, String fylke){ // Konstruktør
        stasjonNumr = nr;
        stasjonNavn = navn;
        meterOverHavet = moh;
        stasjonsKommune = kommune;
        stasjonsFylke = fylke;

    } // end konstruktør

    void settInn(int dMnd, int mnd, double maxVind, double nedbør, double minTemp, double maxTemp) {
        if (måned[mnd-1] == null) måned[mnd-1] = new Maaned(mnd, 31);
        måned[mnd-1].settInn(dMnd, maxVind, nedbør, minTemp, maxTemp);
    }



} // End class Stasjon



/**Class Maaned*/
class Maaned{
    int maaned; // Er overflødig da stasjon objektet alltid starter på dag 1
    int DagIMaaned;
    Dag[] dager = new Dag[31]; // Array for dager


    Maaned(int mnd, int dMnd){ // Konstruktør
        maaned = mnd;
        DagIMaaned = dMnd;

    } // end Konstruktør

    void settInn(int dMnd, double maxVind, double nedbør, double minTemp, double maxTemp) {
        dager[dMnd-1] = new Dag(maxVind, nedbør, minTemp, maxTemp);
    }

/**Returnerer en int verdi som teller antall dager det har vært uvær. Boolean uvær tas i bruk*/
    int telleUværsdager(){
        int teller = 0;
        for(int i=0;i<31;i++){
            if(dager[i] != null && dager[i].mmNedbør == -99 ){} // Luker ut når observasjonsdata ikke eksisterer

            else if(dager[i] != null && dager[i].uvær()){ // har laget egen metode for å avgjøre uvær i class dag
                teller++;
            }
        }
        return teller;

        } // end telleUværsdager

/** Returnerer en double verdi som forteller hvor mye nedbør det har vært på en stasjon i en angitt måned*/
    double telleMestNedbør(){
            double mest = 0;
            for(int i=0;i<dager.length;i++){
                if(dager[i] != null && dager[i].mmNedbør == -99 ){} // Luker ut når observasjonsdata ikke eksisterer

                else if(dager[i] != null && dager[i].mmNedbør <= dager[i].mmNedbør ){
                    mest = (mest + dager[i].mmNedbør);

                }
            }
            return mest;

    } // end telleMestNedbør



    double finneMinTemp(){
        double minst = 0;
        for(int i=0;i<dager.length;i++){
            if(dager[i] != null && dager[i].minTemperatur == -99 ){} // Luker ut når observasjonsdata ikke eksisterer

            else if(dager[i] != null && dager[i].minTemperatur >= dager[i].minTemperatur ){
                minst = dager[i].minTemperatur;
                }
            }
            return minst;


        } // end finneMinTemp






} // End class Maaned



/**Class Dag*/
class Dag{
    double maksVindhastighet;
    double mmNedbør;
    double minTemperatur;
    double maksTemperatur;

    Dag(double maxVind, double nedbør, double minTemp, double maxTemp) { // Konstruktør
        maksVindhastighet = maxVind;
        mmNedbør = nedbør;
        minTemperatur = minTemp;
        maksTemperatur = maxTemp;
    } // end Konstruktør

/**Boolean for å avgjøre når værforholdene kan sies å være et uvær*/
    boolean uvær(){
        if(maksVindhastighet + mmNedbør > 10.7){
            return true;
        }else{return false;}
    } // end uvær


} // End class Dag