/******************************************************************************
 ** $Id: Eigenschaften.java 718 2015-02-14 23:25:54Z 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;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

/**
 * Umfasst Programm- und Turniereigenschaften; inklusive erstmalige Pfadeinstellung.
 */
@SuppressWarnings("serial")
final class Eigenschaften extends Properties {

    /** Name der Einstellungsdatei. */
    private static final String INI = "JaFuffy.ini";
    /** Hinweiszeile in der Einstellungsdatei. */
    private static final String HINWEIS = "JaFuffy-Einstellungen (bitte nicht von Hand ändern)";

    /** Die globalen Eigenschaften für ganz JaFuffy. */
    static final Eigenschaften GLOBAL;
    static {
        SecurityManager sicherheit = System.getSecurityManager();
        Eigenschaften global;
        if (sicherheit == null) {
            String pfad = System.getProperty("user.home") + File.separator + INI;
            global = new Eigenschaften(new File(pfad));
        } else {
            try {
                sicherheit.checkPropertyAccess("user.home");
                String pfad = System.getProperty("user.home") + File.separator + INI;
                sicherheit.checkRead(pfad);
                sicherheit.checkWrite(pfad);
                global = new Eigenschaften(new File(pfad));
            } catch (SecurityException e) {
                global = new Eigenschaften();
            }
        }
        GLOBAL = global;
    }

    /** Einstellungsdatei. */
    private File datei;

    /** Applet-Konstruktor. */
    private Eigenschaften() {
        // Kein Soundsystem vorhanden?
        if (!Ressource.soundsystem()) {
            setProperty("Geraeusche", "passiv");
        }
        // Standardbelegung
        setzeStandard("LookAndFeel", Oberflaeche.standardLookAndFeel());
        setzeStandard("Variante", Variante.KLASSISCH.name());
        setzeStandard("Beginnmodus", Turnier.Beginner.VERLIERER.name());
        setzeStandard("Anzahl", "0");
        setzeStandard("Einfachklick", "passiv");
        setzeStandard("Hinweis", "aktiv");
        setzeStandard("Spicker", "aktiv");
        setzeStandard("Erinnerung", "aktiv");
        setzeStandard("Intro", "aktiv");
        setzeStandard("Geraeusche", "aktiv");
        setzeStandard("X", "0");
        setzeStandard("Y", "0");
        setzeStandard("Breite", "640");
        setzeStandard("Hoehe", "480");
        setzeStandard("Nachschauen", "passiv");
        setzeStandard("Starts", "0");
        setzeStandard("Zwischenstand", "passiv");
        setzeStandard("Neustart", "passiv");
    }

    /**
     * Konstruktor für Applikation.
     *
     * @param datei
     *            Eigenschaftendatei
     */
    private Eigenschaften(File datei) {
        // Standardeigenschaften
        this();
        if (datei.exists()) {
            try {
                FileInputStream reader = new FileInputStream(datei);
                // Auslesen der Einstellungsdatei
                load(reader);
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // Merken der Einstellungdatei
        this.datei = datei;
    }

    /**
     * Setzt Standardeigenschaft eines Schlüssels.
     *
     * @param schluessel
     *            Schlüssel der Eigenschaft.
     * @param wert
     *            Standardwert der Eigenschaft.
     */
    private void setzeStandard(String schluessel, String wert) {
        if (getProperty(schluessel) == null) {
            setProperty(schluessel, wert);
        }
    }

    /**
     * Zustand eines Schlüssels erfragen.
     *
     * @param schluessel
     *            Schlüssel der Eigenschaft.
     * @return Gibt an, ob der Wert des Schlüssels aktiv ist.
     */
    boolean aktiv(String schluessel) {
        return getProperty(schluessel).equals("aktiv");
    }

    /**
     * Erststart erfragen.
     *
     * @return Gibt an, ob Erststart erfolgt ist.
     */
    boolean erststart() {
        return getProperty("Starts").equals("0");
    }

    /**
     * @return Gibt an ob im vohergehenden Programmlauf ein Neustart angefordert wurde,
     *         allerdings kein Turnier am laufen war.
     */
    boolean kaltstart() {
        return getProperty("Neustart").equals("kalt");
    }

    /**
     * Merkt in den Einstellungen, ob ein Neustart angefordert wurde.
     *
     * @param warm
     *            Ein Turnier ist am laufen.
     */
    void merkeNeustartAnforderung(boolean warm) {
        setProperty("Neustart", warm ? "warm" : "kalt");
    }

    /** @return Gibt an ob im vohergehenden Programmlauf ein Neustart angefordert wurde. */
    boolean neustart() {
        return kaltstart() || warmstart();
    }

    /**
     * Ein Neustart wurde durchgeführt, braucht also beim nächsten Programmstart nicht mehr
     * berücksichtigt werden.
     */
    void quittiereNeustartAnforderung() {
        setProperty("Neustart", "passiv");
    }

    /**
     * Speichern der Eigenschaften in Datei.
     *
     * @param x
     *            X-Koordinate der linken oberen Ecke des Programmfensters.
     * @param y
     *            Y-Koordinate der linken oberen Ecke des Programmfensters.
     * @param b
     *            Breite des Programmfensters.
     * @param h
     *            Höhe des Programmfensters.
     * @throws IOException
     *             Geworfen, falls Einstellungen nicht gespeichert werden können.
     */
    void speichere(int x, int y, int b, int h) throws IOException {
        setProperty("X", String.valueOf(x));
        setProperty("Y", String.valueOf(y));
        setProperty("Breite", String.valueOf(b));
        setProperty("Hoehe", String.valueOf(h));
        setProperty("Starts", String.valueOf(Integer.parseInt(getProperty("Starts")) + 1));
        FileOutputStream writer = new FileOutputStream(datei);
        store(writer, HINWEIS);
        writer.close();
    }

    /**
     * @return Gibt an ob im vohergehenden Programmlauf ein Neustart angefordert wurde,
     *         allerdings ein Turnier am laufen war.
     */
    boolean warmstart() {
        return getProperty("Neustart").equals("warm");
    }

    /**
     * Eigenschaften umschalten (aktiv <-> passiv).
     *
     * @param schluessel
     *            Der Schlüssel, dessen boolescher Wert gewechselt werden soll.
     */
    void wechsle(String schluessel) {
        setProperty(schluessel, aktiv(schluessel) ? "passiv" : "aktiv");
    }

}
