/******************************************************************************
 ** $Id: Ende.java 826 2015-11-29 22:56:05Z wmh $
 ** Diese Datei ist Bestandteil der Java-Quelltexte des Würfelspiels JaFuffy.
 ** Lauffähig ab Java 6.
 ******************************************************************************
 ** Copyright (C) Wolfgang Hauck <wolfgang.hauck@3kelvin.de>
 ******************************************************************************
 ** This program is free software: you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
 ** the Free Software Foundation, either version 3 of the License, or
 ** (at your option) any later version.
 **
 ** This program is distributed in the hope that it will be useful,
 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 **
 ** You should have received a copy of the GNU General Public License
 ** along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************
 ** Die aktuellste Version von JaFuffy findet sich im Internet unter
 ** <http://jafuffy.3kelvin.de>.
 **
 ** Kommentare, Fehler oder Erweiterungswünsche bitte per E-Mail senden an
 ** <jafuffy@3kelvin.de>.
 ******************************************************************************/
package jafuffy.bedienung;

import jafuffy.Eigenschaften;
import jafuffy.logik.CEAblauf;
import jafuffy.logik.CEJaFuffy;
import jafuffy.logik.Statistik;
import jafuffy.logik.Turnier;

import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * Nachfrage (nur bei Applikation), ob das Spiel beendet werden soll. Sichern des Turnierstands und der Statistik bei
 * Programmende (Turnierende/abbruch).
 */
public class Ende extends WindowAdapter implements ChangeListener {

    /** Benutzt zum Sichern der Eigenschaften und der Statistik. */
    private final Eigenschaften eigenschaften;
    /** Abzuspeichernde Statistik. */
    private final Statistik statistik;
    /** Laufendes Turnier. */
    private Turnier turnier;

    /**
     * Konstruktor.
     *
     * @param eigenschaften
     *            Die Eigenschaften zur Herleitung der Datei, in der die Statistik geführt wird, und zur Speicherung der
     *            Geometrie des Fensters.
     * @param statistik
     *            Geladene Statistik
     */
    public Ende(Eigenschaften eigenschaften, Statistik statistik) {
        this.eigenschaften = eigenschaften;
        this.statistik = statistik;
    }

    /**
     * ChangeEvent eingetreten.
     *
     * @param ce
     *            Ereignis im Turnierablauf.
     */
    @Override
    public void stateChanged(ChangeEvent ce) {
        if (CEJaFuffy.adressiert(ce, CEAblauf.class)) {
            CEJaFuffy<CEAblauf> cej = CEJaFuffy.ereignisbehaelter(ce);
            switch (cej.ereignis()) {
            case START:
                this.turnier = (Turnier) ce.getSource();
                break;
            case ABBRUCH:
            case ENDE:
                turnier = null;
                break;
            default:
            }
        }
    }

    /**
     * Programm auf Anfrage beenden, und damit Fenster schließen.
     *
     * @param we
     *            Fensterereignis.
     */
    @Override
    public void windowClosing(WindowEvent we) {
        Window fenster = we.getWindow();
        if (Eigenschaften.GLOBAL.neustart() || JOptionPane.showConfirmDialog(fenster, "JaFuffy beenden?",
                "JaFuffy (Frage)", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
            sichereTurnierEigenschaften(fenster);
            sichereStatistik(fenster);
            beendeApplikation();
        }
    }

    /** Beenden der Applikation bedeutet Beenden des Turniers, Schließen des Fensters und Schließen des Programms. */
    private void beendeApplikation() {
        // Turnier abgebrochen oder beendet
        if (turnier != null) {
            turnier.beende();
        }
        System.exit(0);
    }

    /**
     * Statistik sichern.
     *
     * @param fenster
     *            Zur Ausrichtung einer möglichen Fehlermeldung.
     */
    private void sichereStatistik(Window fenster) {
        try {
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(eigenschaften.datei(Statistik.STAT)));
            out.writeObject(statistik);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            Signal.ALARM.play();
            JOptionPane.showMessageDialog(fenster,
                    "Statistik konnte nicht gesichert werden!\n" + "Java-Exception:\n" + e, "JaFuffy (Fehler)",
                    JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * Turniereigenschaften sichern.
     *
     * @param fenster
     *            Zur Ausrichtung einer möglichen Fehlermeldung.
     */
    private void sichereTurnierEigenschaften(Window fenster) {
        try {
            eigenschaften.speichere(fenster.getX(), fenster.getY(), fenster.getWidth(), fenster.getHeight());
        } catch (IOException e) {
            e.printStackTrace();
            Signal.ALARM.play();
            JOptionPane.showMessageDialog(fenster,
                    "JaFuffy-Einstellungen konnten nicht gesichert werden!\n" + "Java-Exception:\n" + e,
                    "JaFuffy (Fehler)", JOptionPane.ERROR_MESSAGE);
        }
    }

}
