package app.controller;

import app.view.*;
import app.model.*;

import java.awt.event.*;
import java.awt.Color;
import javax.swing.event.*;
import javax.swing.*;
import javax.swing.ImageIcon;
import java.sql.SQLException;


/**
 * LoanApp.java
 *
 * <p>Selve applikasjonen. Fungerer som controller.
 * Inneholder alle typer lyttere. Klassen oppretter ett lån, og ett vindu.</p>
 * <p><em>Tanken er at denne skal mest mulig skape et
 * skarpt skille mellom modell og view (selv om jeg tror kanskje
 * jeg innimellom bryter mvc prinsippet litt) </em> </p>
 *
 * @author Hilde Vestøl (106288)
 * @version 0.9
 */


public class LoanApp implements ActionListener, KeyListener,
                                WindowListener, InternalFrameListener {
    private Vindu vinduet;
    private ImageIcon icon = new ImageIcon("images/finance.gif");

    /**
     * Konstruktør. Tar ingen parameter.
     * Oppretter ett nytt Vindu, og sender seg selv inn som lytter.
     * Oppretter ett InterntVindu
     */

    public LoanApp () {
        vinduet = new Vindu("Låneapplikasjon", this );
        opprettNyttIndreVindu();
        vinduet.setVisible(true);
        DatabaseTilkobling.openDB();
    }
    
    //finalize kalles automatisk av Java selv når det ikke lenger
    //finnes en referanse til LoanApp
    //garbage collector
    /**
     *
     * @throws Throwable
     */

    @Override
    protected void finalize() throws Throwable {
        DatabaseTilkobling.closeDB();
        super.finalize();
    }
    
        
  /************************************************************************
   * Hjelpemetoder                                                        *
   * **********************************************************************/

    
    private void opprettNyttIndreVindu() {
        vinduet.opprettInterntVindu(new Loan(), "Lån #");
    }
    
    private void opprettNyttIndreVindu(Loan lån) {
        vinduet.opprettInterntVindu(lån, "Lån #");
    }
    
    private void resetLån()  {
        /* Resetter også selve lånet.. må kanskje endre dette når
         * jeg kommer til databasen.
         * Hele denne burde egentlig revurderes litt også i Loan-klassen
         * for der resettes også verdiene i lånet...
         */

        Loan lån = vinduet.getLån();
        lån.resetLån();
        lån.fireTableDataChanged();

        vinduet.setBeløp("");
        vinduet.setLøpetid("");
        vinduet.setRentesats("");
        vinduet.setInfoTxt(Color.BLACK);
        vinduet.setInfoTxt("");
    } //end resetLån()
    
    
    private void lukkProgram() {
        if (vinduet.getDesktop().getAllFrames().length == 0) {
            vinduet.dispose();
        } else {
            vinduet.lukkInterneVinduer();
            vinduet.dispose();
        }        
        
    } // end lukkProgram()
    

    private boolean lukkVindu() {
        boolean ok = true;
        
        /* Spør brukeren om de vil lagre før ev. lukking av vinduet.
         * Hvis ikke det er gjort noen endringer i vinduet, blir
         * de ikke spurt.
         * Per nå står lånetErEndret() alltid til true, dette skal
         * forhåpentligvis endres/forbedres til neste versjon.
         *
         */

        
        if (vinduet.getLån().lånetErEndret() ) {
            /* Forbedringspotensiale: Kan la brukeren velge å discarde
             * alle vinduene uten å lagre noen ting.
             */

            Object[] valg = {"Lagre ", "Ikke lagre ", "Avbryt"};
            int n = JOptionPane.showOptionDialog(vinduet,
                                "Vil du lagre?", "",
                                JOptionPane.YES_NO_CANCEL_OPTION,
                                JOptionPane.QUESTION_MESSAGE,
                                null, valg, valg[2]);
        
            if (n == JOptionPane.YES_OPTION) {
                lagreLån();
                vinduet.getAktivtVindu().dispose();
                ok = true;
            } else if (n == JOptionPane.NO_OPTION){
                vinduet.getAktivtVindu().dispose();
                ok = true;
            } else {
                vinduet.setInfoTxt(Color.RED);
                vinduet.setInfoTxt("Du valgte å avbryte");
                ok = false;
            }
        }
        return ok;
    } // end lukkVindu()
    
    private void hjelp() {
        vinduet.setInfoTxt(Color.BLUE);
        vinduet.setInfoTxt("Hjelp menyen skal ikke gjøre noe enda");
    }
        
    private void lagreLån (/*Loan lån*/) {
        Loan lån = vinduet.getLån();
        //oppdaterLåneObjekt();
        vinduet.setInfoTxt(Color.BLUE);
        vinduet.setInfoTxt("Lånet skal lagres i databasen i oppgave C");
        
        
        //System.out.println(vinduet.getLån());
        
        //lagre lånet i databasen
        if (oppdaterLåneObjekt()){
            //dbCtrl.lagreDB(vinduet.getLån());
            lån.save();
            //vinduet.setID(vinduet.getLån().getLåneNR());
            vinduet.oppdaterAlleFelt(lån);
        }
        
    }
        
    
    private void søkEtterLån( int lånenr) throws Exception {
        Loan lån = new Loan(lånenr);
        opprettNyttIndreVindu(lån);
        
        //Skal ikke gjøre noe i denne oppgaven
        vinduet.setInfoTxt(Color.BLUE);
        vinduet.setInfoTxt("Søk fra database i oppg c");
        //lån.find(lån);
        vinduet.oppdaterAlleFelt(lån);
//        vinduet.setID(lån.getLåneNR());
//        vinduet.setBeløp(lån.getLånebeløp());
    }
    
    private void beregnPlan() {
        Loan lån = vinduet.getLån();

        /* Hvis oppdaterLåneObjekt() returnerer ok, så lager jeg plan
         * og oppdaterer tabellen.
         * NB! Lånet lagres ikke før man trykker lagre
         */

        if (oppdaterLåneObjekt()) {
            lån.lagPlan();
            lån.fireTableDataChanged();
        }
    }
    
    private void omProgrammet() {
        String about = "Versjon: 0.9.1 ";
        about += "\nCopyright Hilde Vestøl";
        about += "\nStudentnr: 106288";
        about += "\nnov. 2011";
    
        JOptionPane.showMessageDialog(
                null, about, "Om programmet",
                JOptionPane.INFORMATION_MESSAGE, icon
        );
    }
    
    private boolean oppdaterLåneObjekt() {
        boolean ok = true;
        String feilmelding = "";
        Loan lån = vinduet.getLån();
        
        /* Henter txt fra txt-felt i det aktive vinduet.
         * Setter verdiene i lån.
         * Har egen try/catch rundt hver set-er for å få opp alle feilmeldinger
         * og individuelle feilmeldinger.
         * Kunne satt try rundt hele og samlet alle catch til slutt, men
         * da ville det kun kommet beskje om første feil som oppstår.
         * Jeg ønsker å hente inn alle feil, og gi bruker beskjed om alle feil
         * med en gang.
         */

        
        try {
            lån.setLånebeløp( vinduet.getLånebeløp() );
        } catch (NumberFormatException nfe) {
            feilmelding += "Ulovlig(e) tegn i lånebeløp\n";
            ok = false;
        } catch (LoanException le) {
            feilmelding += le + "\n";
            ok = false;
        }
        
        try {
            lån.setLøpetid( vinduet.getLøpetid() );
        } catch (NumberFormatException nfe) {
            feilmelding += "Ulovlig(e) tegn i løpetid\n";
            ok = false;
        } catch (LoanException le) {
            feilmelding += le + "\n";
            ok = false;
        }
        
        try {
            lån.setÅrligeTerminer( vinduet.getÅrligeTerminer() );
        } catch (LoanException le) {
            feilmelding += le + "\n";
            ok = false;
        }
        
        try {
            lån.setRentesats( vinduet.getRentesats() );
        } catch (NumberFormatException nfe) {
            feilmelding += "Ulovlig(e) tegn i rentesats\n";
            ok = false;
        } catch (LoanException le) {
            feilmelding += le + "\n";
            ok = false;
        }
        
        try {
            lån.setLånetype( vinduet.getLånetype() );
        } catch (LoanException le) {
            feilmelding += le + "\n";
            ok = false;
        }
        
        vinduet.setInfoTxt(Color.RED);
        vinduet.setInfoTxt(feilmelding);
        
        return ok;
    } // end oppdaterProgram()

    
    //Test-metoder
    private void testLån() {
        vinduet.setBeløp(20000);
        vinduet.setLøpetid(20);
        vinduet.setRentesats(2.4);
    }
    
    private void testExceptionLån() {
        vinduet.setBeløp(-1);
        vinduet.setLøpetid(-2);
        vinduet.setRentesats(50);
    }
    
    private void testExceptionLån2() {
        vinduet.setBeløp("a");
        vinduet.setLøpetid("a");
        vinduet.setRentesats("a");
    }
    
    
  /* **********************************************************************
   * ActionListener                                                       *
   * **********************************************************************/

 
    /**
     * En ActionListener som lytter på diverse hendeleser.
     * @param event ActionEvent
     */

    @Override
    public void actionPerformed( ActionEvent event ) {
        //System.out.println(event.getActionCommand());
            
        if (event.getActionCommand().equals("reset")) {
            if (vinduet.harAktivtVindu())
                resetLån();
        }
        else if (event.getActionCommand().equals("save")) {
            lagreLån();
        }
        else if (event.getActionCommand().equals("find")) {
            try {
                int lånenr = Integer.parseInt(JOptionPane.showInputDialog(null, "Skriv lånenr"));
                søkEtterLån(lånenr);
            } catch (LoanException e) {
                JOptionPane.showMessageDialog(null, e);
            } catch (NumberFormatException nfe) {
                JOptionPane.showMessageDialog(null, "Ugyldig inntast. Skriv kun tall");
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(null, "Exception");
            }
        }
        else if (event.getActionCommand().equals("delete")){
            try {
                int lånenr = Integer.parseInt(JOptionPane.showInputDialog(null, "Skriv lånenr"));
                Loan.delete(lånenr);
                JOptionPane.showMessageDialog(null, "Lån med id: " + lånenr + "ble slettet");
            } catch (SQLException sqle) {
                JOptionPane.showMessageDialog(null, "Fant ikke lånenr");
            }
        }
        else if (event.getActionCommand().equals("closeWindow")) {
            //Det er kun det indre aktive vinduet som skal lukkes
            if (vinduet.harAktivtVindu())
                lukkVindu();
        }
        else if (event.getActionCommand().equals("newWindow")) {
            opprettNyttIndreVindu();
        }
        else if (event.getActionCommand().equals("beregn")) {
            /* Sjekker om det finnes et aktivt indre vindu,
             * slik at man ikke får NullPointerException ved å bruke
             * menyen hvis det ikke finnes et aktivt vindu
             * Senere vil jeg gråe ut menyvalget slik at de ikke kan
             * trykke beregn hvis det ikke er noe aktivt vindu.
             */

            if (vinduet.harAktivtVindu()) {
                beregnPlan();
            }
            else
                JOptionPane.showMessageDialog(null,
                        "Ingen aktive vinduer",
                        "Obs! Feil....",
                        JOptionPane.WARNING_MESSAGE);
        }
        else if (event.getActionCommand().equals("quit")) {
            lukkProgram();            
        }
        else if (event.getActionCommand().equals("about")) {
            omProgrammet();
        }
        else if (event.getActionCommand().equals("help")) {
            hjelp();
        }
        
        //TEST EVENTES
        else if (event.getActionCommand().equals("test")){
            if (vinduet.harAktivtVindu())
                testLån();
        }
        else if (event.getActionCommand().equals("testExceptionLån")) {
            if (vinduet.harAktivtVindu())
                testExceptionLån();
        }
        else if (event.getActionCommand().equals("testExceptionLån2")) {
            if (vinduet.harAktivtVindu())
                testExceptionLån2();
        }
    }
    
    
  /* ***********************************************************************
   * KeyListener                                                           *
   * Slik at beregnPlan(); kjøres når man trykker enter                    *
   * ***********************************************************************/

    
    /**
     * Trigges når man trykker en tast
     * @param e KeyEvent
     */

    @Override
    public void keyPressed(KeyEvent e) {
        if (vinduet.harAktivtVindu())
            vinduet.getLån().setLånetErEndret();

        if (e.getKeyCode() == KeyEvent.VK_ENTER ) {
            beregnPlan();
        }
    }
    
    /**
     *
     * @param e
     */

    @Override
    public void keyReleased(KeyEvent e) {}
    
    /**
     *
     * @param e
     */

    @Override
    public void keyTyped(KeyEvent e) {}
    
    
  /* **********************************************************************
   * WindowListener                                                       *
   * **********************************************************************/

    /**
     *
     * @param e
     */

    @Override
    public void windowActivated(WindowEvent e) {}
    
    /**
     *
     * @param e
     */

    @Override
    public void windowClosed(WindowEvent e) {}    
    
    /**
     *
     * @param e
     */

    @Override
    public void windowDeactivated(WindowEvent e) {}
    
    /**
     * Trigges når man lukker et vindu
     * @param e WindowEvent
     */

    @Override
    public void windowClosing(WindowEvent e)  {
        lukkProgram();
    }
    
    /**
     *
     * @param e
     */

    @Override
    public void windowIconified(WindowEvent e) {}
    
    /**
     *
     * @param e
     */

    @Override
    public void windowOpened(WindowEvent e) {}
    
    /**
     *
     * @param e
     */

    @Override
    public void windowDeiconified(WindowEvent e) {}
    
    
  /* ***********************************************************************
   * InternalFrameListener                                                 *
   * ***********************************************************************/

    /**
     *
     * @param e
     */

    @Override
    public void internalFrameActivated(InternalFrameEvent e) {
        vinduet.enableMeny();
//        MenyApp meny = (MenyApp)vinduet.getJMenuBar();
//        meny.finnMenyValg("save").setEnabled(true);
//        meny.finnMenyValg("closeWindow").setEnabled(true);
//        meny.finnMenyValg("beregn").setEnabled(true);
    }
    
    /**
     *
     * @param e
     */

    @Override
    public void internalFrameClosed(InternalFrameEvent e) {}
    
    /**
     * Trigges når man lukker ett internt vindu
     * @param e InternalFrameEvent
     */

    @Override
    public void internalFrameClosing(InternalFrameEvent e)  {
        lukkVindu();
    }
    
    /**
     *
     * @param e
     */

    @Override
    public void internalFrameDeactivated(InternalFrameEvent e) {
         vinduet.disableMeny();
    }
    
    /**
     *
     * @param e
     */

    @Override
    public void internalFrameIconified(InternalFrameEvent e)  {}
    
    /**
     *
     * @param e
     */

    @Override
    public void internalFrameOpened(InternalFrameEvent e) {}
    
    /**
     *
     * @param e
     */

    @Override
    public void internalFrameDeiconified(InternalFrameEvent e) {}

} // end class Låneapplikasjon

Kontaktinfo

Hilde Vestøl
98883064
hilde@vestol.net

kart