// espemyk g-3 o-3 k-inf1000/h04

/*
 * Oblig 3
 * Av Espen Myklevoll
 * Created on 13 October 2004, 18:35
 */

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

class Hybel {
    public String navn = null;
    public double saldo = 0;
    public String hybelnavn;
    public double totForskudd = 0;
    
    Hybel(String navn, double saldo, String hybelnavn, double totForskudd) {
        this.navn = navn;
        this.saldo = saldo;
        this.hybelnavn = hybelnavn;
        this.totForskudd = totForskudd;
    }
    
    void betaling(double bet) {
        saldo += bet;
    }
    
    void okTotForskudd(double forskudd) {
        totForskudd += forskudd;
    }
} // end hybel

class HybelHus {
    In tast = new In();
    Out print = new Out();
    String hybelhus;
    Hybel [][] hybler = new Hybel [4][8];
    int mnd = 0;
    double totInn = 0;
    double stromSum = 0; // total stromregning
    int tommeHybler = 0;
    
    HybelHus(String filnavn) {
        this.hybelhus = hybelhus;
        
        for (int i = 0; i < hybler.length; i++) { // lager objekter i alle plassene i hybelarrayen som kun inneholder hybelnavn
            for (int j = 1; j < hybler[i].length; j++) { // j = 1 fordi 0 er fellesareal, disse lagres i registrerFellesareal
                double saldo = 0;
                double totForskudd = 0;
                String navn = null;
                int k = i + 1;
                char l = nrtilb(j);
                String hybelnavn = (k + "" + l);
                Hybel h = new Hybel(navn, saldo, hybelnavn, totForskudd);
                hybler[i][j] = h;
            }
        }
        
        lesInn(filnavn);
    } // end konstruktor hybelhys
    
    void registrerFellesAreal() {
        for (int i = 0; i < hybler.length; i++) {
            String student = "Fellesareal";
            double saldo = 0;
            double totForskudd = 0;
            int nr = i + 1;
            String hybelnavn = (nr + "A");
            Hybel h = new Hybel(student, saldo, hybelnavn, totForskudd);
            int k = 0;
            hybler[i][k] = h;
        }
    } // end registrerfellesareal | setter alle fellesarealene (1A, 2A osv) til a vre opptatt, med navn Fellesareal og saldo 0
    
    char nrtilb(int j) {
        char k = '0';
        if (j == 0) {
            k = 'A';
        } else if (j == 1) {
            k = 'B';
        } else if (j == 2) {
            k = 'C';
        } else if (j == 3) {
            k = 'D';
        } else if (j == 4) {
            k = 'E';
        } else if (j == 5) {
            k = 'F';
        } else if (j == 6) {
            k = 'G';
        } else if (j == 7) {
            k = 'H';
        }
        return k;
    } // end nrtilb | gjor om fra arraynr til hybelbokstav
    
    int btilnr(String bokstnr) {
        int k = 0;
        if (bokstnr.equalsIgnoreCase("A")) {
            k = 0;
        } else if (bokstnr.equalsIgnoreCase("B")) {
            k = 1;
        } else if (bokstnr.equalsIgnoreCase("C")) {
            k = 2;
        } else if (bokstnr.equalsIgnoreCase("D")) {
            k = 3;
        } else if (bokstnr.equalsIgnoreCase("E")) {
            k = 4;
        } else if (bokstnr.equalsIgnoreCase("F")) {
            k = 5;
        } else if (bokstnr.equalsIgnoreCase("G")) {
            k = 6;
        } else if (bokstnr.equalsIgnoreCase("H")) {
            k = 7;
        }
        return k;
    } // end btilnr | gjor om fra hybelbokstav til arraynr
    
    void lagreTilFil(String filnavn) {
        Out utfil = new Out(filnavn);
        utfil.outln(totInn);
        utfil.outln(stromSum);
        utfil.outln(mnd);
        utfil.outln(tommeHybler);
        for (int i = 0; i < hybler.length; i++){
            for (int j = 1; j < hybler[i].length; j++) { // j = 1 fordi 0 er fellesareal, unodvendig a lagre, lastes nar prog kjores
                if (hybler[i][j].navn != null) {
                    utfil.outln(hybler[i][j].navn);
                    utfil.outln(hybler[i][j].saldo);
                    utfil.outln(hybler[i][j].totForskudd);
                    utfil.outln(hybler[i][j].hybelnavn);
                }
            }
        }
        utfil.close();
    } // end lagretilfil | leser inn til haihus.data nar programmet avsluttes
    
    void lesInn(String filnavn) {
        In innfil = new In(filnavn);
        totInn = innfil.inDouble();
        innfil.inLine();
        stromSum = innfil.inDouble();
        mnd = innfil.inInt();
        tommeHybler = innfil.inInt();
        innfil.inLine();
        
        while (!innfil.endOfFile()) {
            String student = innfil.inLine();
            double saldo = innfil.inDouble();
            double totForskudd = innfil.inDouble();
            innfil.inLine();
            String hybelnavn = innfil.inLine();
            Hybel h = new Hybel(student, saldo, hybelnavn, totForskudd);
            int gangnr = Integer.parseInt(hybelnavn.substring(0,1));
            String bokstnr = hybelnavn.substring(1,2);
            int k = btilnr(bokstnr);
            hybler[gangnr-1][k] = h;
        }
        innfil.close();
    } // end lesinn | leser inn fra haihus.data ved oppstart
    
    void skrivListe() {
        print.outln();
        print.outln(":: Liste over ledige hybler ::");
        for (int i = 0; i < hybler.length; i++){
            for (int j = 1; j < hybler[i].length; j++) { // j = 1 fordi 0 er fellesareal
                if (hybler[i][j].navn == null) {
                    char k = nrtilb(j);
                    i++;
                    print.outln(i + " , " + k);
                    i--;
                }
            }
            print.outln();
        }
    } // end liste | skriver ut liste over ledige hybler
    
    // okonomidata
    
    void nyLeietaker() {
        print.outln(":: Registrere ny leietaker ::");
        print.out("Navn: ");
        String student = tast.inWord("\n");
        print.out("Har vedkommende betalt depositum (ja/nei) ? ");
        String svar = tast.inWord();
        double saldo = 0;
        double totForskudd = 0;
        if (svar.equalsIgnoreCase("ja")) { // legger til 8000 i saldo hvis personen har betalt forskuddet
            saldo = 8000;
            totForskudd = 8000;
        }
        print.out("Hybelnavn: ");
        String hybelnavn = tast.inWord();
        Hybel h = new Hybel(student, saldo, hybelnavn, totForskudd);
        int gangnr = Integer.parseInt(hybelnavn.substring(0,1));
        String bokstnr = hybelnavn.substring(1,2);
        int k = btilnr(bokstnr);
        if (k == 0){
            print.outln("Du prover a registrere pa et fellesareal, vennligst prov igjen.");
            print.outln();
        } else if (hybler[gangnr-1][k].navn != null){
            print.outln("Beklager, hybelen er allerede opptatt");
            print.outln();
        } else {
            hybler[gangnr-1][k] = h;
            print.outln(student + " ble plassert i hybel " + gangnr + " , " + bokstnr);
        }
    } //end nyleietaker | legger inn ny leietaker
    
    void frivilligFlytting() {
        print.outln(":: Frivillig utflytting av leietaker ::");
        print.out("Angi hvem som skal flytte: ");
        tast.inLine();
        String navn = tast.inLine();
        print.out("Angi hybelnavnet til vedkommende: ");
        String hybelnavn = tast.inLine();
        int gangnr = Integer.parseInt(hybelnavn.substring(0,1));
        String bokstnr = hybelnavn.substring(1,2);
        int bnr = btilnr(bokstnr);
        int i = 0;
        int j = 0;
        int k = 0;
        int l = 0;
        boolean funnet = false;
        for (i = 0; i < hybler.length; i++) { // sjekker om den oppgitte personen bor i den oppgitte hybelen
            for (j = 1; j < hybler[i].length; j++) { // j = 1 fordi 0 er fellesareal
                if (hybler[i][j].navn != null && (gangnr-1) == i && bnr == j && hybler[i][j].navn.equalsIgnoreCase(navn)) {
                    funnet = true;
                    k = i;
                    l = j;
                }
            }
        }
        if (funnet) {
            double tilgode = hybler[k][l].saldo - 800;
            print.outln(navn + " er fjernet fra registeret, og har " + tilgode + " kr tilgode.");
            print.outln();
            hybler[k][l].navn = null;
            hybler[k][l].totForskudd = 0;
            hybler[k][l].saldo = 0;
        } else {
            print.outln("Denne personen eier ikke denne leiligheten, ingen endringer er utfort");
        }
        
        
    } // end friflytting | fjerner folk som flytter, og regner ut hvor mye av depositumet de har tilgode etter at gebyret er trukket fra
    
    void maanedskjoring() {
        print.outln(":: Manedlig okonomikjoring ::");
        String sep = ":";
        String husnr = null;
        double inntekt = 0;
        double stromr = 0;
        double stromf = 0;
        double stroms = 0;
        print.outln("Denne kan kun kjores en gang i maneden, og endringene kan ikke tilbakestilles. Vil du fortsette? (ja/nei)");
        String svar = tast.inWord();
        
        if (svar.equalsIgnoreCase("ja")) {
            for (int i = 0; i < hybler.length; i++) {
                for (int j = 1; j < hybler[i].length; j++) { // j = 1 fordi 0 er fellesareal
                    inntekt -= 1000; // avskrivning og andre utgifter, trekkes fra for alle hyblene
                    if (hybler[i][j].navn != null) {
                        hybler[i][j].saldo -= 3000; // trekker fra husleie
                        inntekt += 3000; // legger til husleie i denne mnds totale inntekt
                        
                        In innfil = new In("Lysregning.data");
                        while (!innfil.endOfFile()) { // leser av lysregning.data, regner ut stromregningen, trekker fra saldo til leietakeren, og legger til 2 kr pr kwh til inntekt
                            husnr = innfil.inWord(sep);
                            int gangnr = innfil.inInt(sep);
                            char bokst = innfil.inChar(sep);
                            int kwh = innfil.inInt(sep);
                            String hybelnavn = (gangnr + "" + bokst);
                            if (hybelnavn.equalsIgnoreCase(hybler[i][j].hybelnavn)) {
                                stromf = kwh * 1.2;
                                stromr = kwh * 2;
                                stroms = kwh * 0.8;
                                hybler[i][j].saldo -= stromr;
                                inntekt += stromf;
                                stromSum += stroms;
                            }
                        }
                        innfil.close();
                    } else { // regner ut stromregningen for den tomme hybelen, trekker det fra total inntekt, og oker antall hybler gulbrand har gatt glipp av leie fra
                        tommeHybler++;
                        In innfil = new In("Lysregning.data");
                        while (!innfil.endOfFile()) {
                            husnr = innfil.inWord(sep);
                            int gangnr = innfil.inInt(sep);
                            char bokst = innfil.inChar(sep);
                            int kwh = innfil.inInt(sep);
                            innfil.inLine();
                            String hybelnavn = (gangnr + "" + bokst);
                            if (hybelnavn.equalsIgnoreCase(hybler[i][j].hybelnavn)) {
                                stromr = kwh * 0.8;
                                inntekt -= stromr;
                                stromSum += stromr;
                            }
                        }
                        innfil.close();
                    }
                }
            }
            for (int i = 0; i < hybler.length; i++) { // regner ut og trekker stromregningene til fellesarealene fra inntekt
                In innfil = new In("Lysregning.data");
                while (!innfil.endOfFile()) {
                    husnr = innfil.inWord(sep);
                    int gangnr = innfil.inInt(sep);
                    char bokst = innfil.inChar(sep);
                    int kwh = innfil.inInt(sep);
                    innfil.inLine();
                    String hybelnavn = (gangnr + "" + bokst);
                    if (hybelnavn.equalsIgnoreCase(hybler[i][0].hybelnavn)) {
                        stromr = kwh * 0.8;
                        inntekt -= stromr;
                    }
                }
                innfil.close();
            }
            mnd++; // legger til en maned
            totInn += inntekt; // legger til denne manedens inntekt til total inntekt
            int rundInn = (int) Math.round(inntekt);
            int rundTot = (int) Math.round(totInn);
            print.outln("Denne manedens inntekt var " + rundInn + " kr");
            print.outln("Den totale inntekten hittil er " + rundTot + " kr");
        }
    } // end maanedskjoring |
    
    void registrerBetaling() {
        print.outln(":: Registere betaling fra leietaker ::");
        tast.inLine();
        print.out("Angi hybelnavn: ");
        String hybelnavn = tast.inLine();
        int gangnr = Integer.parseInt(hybelnavn.substring(0,1));
        String bokstnr = hybelnavn.substring(1,2);
        int k = btilnr(bokstnr);
        if (hybler[gangnr-1][k].navn != null) {
            print.out("Angi betalt belop i kr: ");
            double betalt = tast.inInt();
            hybler[gangnr-1][k].okTotForskudd(betalt);
            hybler[gangnr-1][k].betaling(betalt);
            print.outln("Ny saldo for " + hybler[gangnr-1][k].navn + " er " + hybler[gangnr-1][k].saldo + " kr.");
        }
    } // end registrerbetaling | registrerer ny betaling av husleie fra leietakerne
    
    void tilkallTorpedo() {
        Out utfil = new Out("torpedo.txt");
        utfil.outln("Personer som skal hives ut av studenthyblene:");
        utfil.outln("--");
        int antallUtkastelser = 0;
        for (int i = 0; i < hybler.length; i++){
            for (int j = 1; j < hybler[i].length; j++) { // j = 1 fordi 0 er fellesareal
                if (hybler[i][j].navn != null && hybler[i][j].saldo < 0) {
                    double krav = (Math.abs(hybler[i][j].saldo))+1000;
                    utfil.out("Navn: ");
                    utfil.out(hybler[i][j].navn + "   ");
                    utfil.out("Krav: ");
                    utfil.outln(krav);
                    print.out("Navn: ");
                    print.out(hybler[i][j].navn + "   ");
                    print.out("Krav: ");
                    print.outln(krav);
                    hybler[i][j].navn = null;
                    hybler[i][j].totForskudd = 0;
                    hybler[i][j].saldo = 0;
                    antallUtkastelser++;
                }
            }
        }
        utfil.close();
        if (antallUtkastelser == 0) {
            print.outln("Det er ingen som skal kastes ut denne måneden, ingen endringer utført.");
        } else {
            print.outln("Det er " + antallUtkastelser + " som skal kastes ut, de gjeldene personene er na fjernet fra systemet.");
            print.outln("Denne listen er na skrevet ut til filen torpedo.txt.");
        }
    } // end tilkalltorpedo | finner ut om noen har negativ saldo, lagrer navnet deres i torpedo.txt hvis
    
    void okrapport() {
        int rundTot = (int) Math.round(totInn);
        print.outln(":: Okonomirapport for Guldbrand Gras husleiesystem ::");
        print.outln("Total inntekt hittil er: " + rundTot + " kr");
        print.outln("Systemet har kjort i " + mnd + " maneder");
        double snittTapteHusleier = tommeHybler/mnd;
        print.outln("I gjennomsnitt har Gulbrand gatt glipp av " + snittTapteHusleier + " husleier hver maned pga tomme hybler");
    } // end okrapport | skriver ut rapport med diverse data om guldbrans okonomi
    
    void opptattListe() {
        System.out.println(":: Opptatte hybler ::");
        for (int i = 0; i < 4; i++) {
            for (int j = 1; j < 8; j++) {
                if (hybler[i][j].navn != null) {
                    char k = nrtilb(j);
                    System.out.println((i+1) + ","+ k + " :: " + hybler[i][j].navn + ",  Saldo: " + hybler[i][j].saldo + ",  Totalt forskudd: " + hybler[i][j].totForskudd);
                }
            }
        }
    } // end opptattliste | skriver ut liste over opptatte hybler
    
    void intro() {
        print.outln("*****************************************");
        print.outln("*                                       *");
        print.outln("* Velkommen til Gulbrands husleiesystem *");
        print.outln("*                                       *");
    }
    
    void kommandoLokke() {
        intro();
        while (true) {
            print.outln("*****************************************");
            System.out.println("Du er na i maned " + mnd);
            System.out.println("0. Avslutt");
            System.out.println("1. Skriv liste over ledige hybler");
            System.out.println("2. Registrer ny leietager");
            System.out.println("3. Registrer frivillig flytting av leietager");
            System.out.println("4. Manedskjoring av husleie med strom");
            System.out.println("5. Registrer betaling fra leietager");
            System.out.println("6. Sjekk om noen leietagere skal kastes ut");
            System.out.println("7. Skriv okonomirapport");
            System.out.println("8. Skriv liste over opptatte hybler m navn og detaljer");
            
            print.out("Tast inn ditt valg: ");
            int ordre = tast.inInt();
            
            switch (ordre) {
                case 0:
                    
                    lagreTilFil("HaiHus.data");
                    System.exit(0);
                    break;
                    
                case 1:
                    
                    print.outln();
                    skrivListe();
                    print.outln();
                    break;
                    
                case 2:
                    
                    print.outln();
                    nyLeietaker();
                    print.outln();
                    break;
                    
                case 3:
                    
                    print.outln();
                    frivilligFlytting();
                    print.outln();
                    break;
                    
                case 4:
                    
                    print.outln();
                    maanedskjoring();
                    print.outln();
                    break;
                    
                case 5:
                    
                    print.outln();
                    registrerBetaling();
                    print.outln();
                    break;
                    
                case 6:
                    
                    print.outln();
                    tilkallTorpedo();
                    print.outln();
                    break;
                    
                case 7:
                    
                    print.outln();
                    okrapport();
                    print.outln();
                    break;
                    
                case 8: // ikke med i oppgaven, men laget for a lettere kunne sjekke om ting er lagret riktig
                    
                    print.outln();
                    opptattListe();
                    print.outln();
                    break;
                    
                default:
                    
                    print.outln("Du har tastet feil, vennligst prov igjen");
                    print.outln();
                    break;
                    
            } // end switch
        } // end while
    } // end kommandolokke
} // end hybelhus

public class Oblig3 {
    In tast = new In();
    
    public static void main(String args []) {
        HybelHus h = new HybelHus("HaiHus.data");
        h.registrerFellesAreal();
        h.kommandoLokke();
    } // end main
} //end oblig3