/******************************************************************************
 ** $Id: Willkommen.java 1591 2018-11-15 21:21:38Z wmh $
 ** Diese Datei ist Bestandteil der Java-Quelltexte des Würfelspiels JaFuffy.
 ** Lauffähig ab Java 7.
 ******************************************************************************
 ** 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 java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URL;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.WindowConstants;
import javax.swing.border.TitledBorder;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

import jafuffy.Eigenschaften;
import jafuffy.Ressource;

/** Einführungsdialog beim erstmaligen Programmstart. */
@SuppressWarnings("serial")
public class Willkommen extends JDialog {

    /** ID des erstens Icons zur Wechselgrafik. */
    private static final String ID1 = "1";
    /** ID des zweiten Icons zur Wechselgrafik. */
    private static final String ID2 = "2";
    /** Installationsseite (Name) aus der Hilfe. */
    private static final String INSTALLATION = "Installation.html";
    /** Installationsseite (URL) aus der Hilfe. */
    private static final URL HINWEISE = Ressource.LIESMICH.url(INSTALLATION);
    /** Font, der im Willkommendialog verwendet wird. */
    private static final Font TITELSCHRIFTART = new Font("Dialog", Font.BOLD, 18);
    /** Periode, mit der zwischen den Ziergrafiken umgeschaltet wird. */
    private static final int WECHSELPERIODE = 5000;
    /** Erstes Icon zur Wechselgrafik beim Willkommendialog. */
    private static final ImageIcon WILLKOMMEN1 = Grafik.icon("Willkommen1.gif");
    /** Zweites Icon zur Wechselgrafik beim Willkommendialog. */
    private static final ImageIcon WILLKOMMEN2 = Grafik.icon("Willkommen2.gif");
    /** Abstand vom Dialograhmen zum Inhalt. */
    private static final int DIALOGRAHMENABSTAND = 8;
    /** Abstand vom Feldrahmen zum Inhalt. */
    private static final int FELDRAHMENABSTAND = 4;
    /** Breite für die Installationshinweise. */
    private static final int BREITE = 600;
    /** Höhe für die Installationshinweise. */
    private static final int HOEHE = 275;
    /** Spaltenanzahl der Textfelder. */
    private static final int SPALTEN = 45;
    /** Zeilenanzahl der Textfelder. */
    private static final int ZEILEN = 3;

    /**
     * Fragt nach, ob automatisch bei Programmstart nach Updates gesucht werden soll.
     * 
     * @param eigenschaften
     *            Eigenschaften, welche dauerhaft abgelegt werden
     * @return Das Feld mit der Nachfrage
     */
    private static JPanel aktualisierungspruefungsfrage(Eigenschaften eigenschaften) {
        JCheckBox nachschauen = new JCheckBox();
        nachschauen.setSelected(eigenschaften.aktiv("Nachschauen"));
        nachschauen.setBorderPainted(true);
        nachschauen.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(),
                BorderFactory.createEmptyBorder(0, 2 * FELDRAHMENABSTAND, 0, 2 * FELDRAHMENABSTAND)));
        nachschauen.setBackground(Color.ORANGE);
        nachschauen.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                eigenschaften.wechsle("Nachschauen");
            }
        });
        JPanel nachschauenrahmen = new JPanel(new BorderLayout());
        nachschauenrahmen.setBorder(BorderFactory.createEmptyBorder(FELDRAHMENABSTAND, FELDRAHMENABSTAND,
                FELDRAHMENABSTAND, FELDRAHMENABSTAND));
        nachschauenrahmen.add(nachschauen, BorderLayout.CENTER);
        JTextArea suchverhalten =
                new JTextArea(
                        "Automatisch bei jedem Programmstart " + "nach neuerer Version auf JaFuffys Homepage suchen. "
                                + "Das Verhalten kann nachträglich im Menüpunkt "
                                + "\"Einstellungen - Nachschauen\" festgelegt werden. "
                                + "Der Menüpunkt \"Hilfe - Aktualisieren...\" stößt die Suche explizit an.",
                        ZEILEN, SPALTEN);
        suchverhalten.setLineWrap(true);
        suchverhalten.setWrapStyleWord(true);
        suchverhalten.setEditable(false);
        suchverhalten.setOpaque(false);
        JPanel aktualiserungsfeld = new JPanel(new BorderLayout(FELDRAHMENABSTAND, 0));
        aktualiserungsfeld.setBorder(BorderFactory.createTitledBorder(null,
                "Auf Homepage automatisch nach neuerer Version suchen?", TitledBorder.LEFT, TitledBorder.ABOVE_TOP));
        aktualiserungsfeld.add(nachschauenrahmen, BorderLayout.EAST);
        aktualiserungsfeld.add(suchverhalten, BorderLayout.CENTER);
        return aktualiserungsfeld;
    }

    /**
     * Erstellt das Feld, welches Hinweise zur Installation enthält.
     * 
     * @param wechselgrafik
     *            Die Wechselgrafik mit den Ziergrafiken
     * @return Hinweisfeld
     */
    private static JPanel hinweise(JPanel wechselgrafik) {
        JEditorPane hilfe;
        try {
            hilfe = new JEditorPane(HINWEISE);
        } catch (IOException e) {
            e.printStackTrace();
            Signal.WARNUNG.play();
            JOptionPane.showMessageDialog(null,
                    "(De)Installationshinweise \"" + INSTALLATION + "\" können nicht geladen werden!",
                    "JaFuffy (Warnung)", JOptionPane.WARNING_MESSAGE);
            hilfe = new JEditorPane("text",
                    "(De)Installationshinweise \"" + INSTALLATION + "\" können nicht geladen werden!");
        }
        hilfe.setEditable(false);
        hilfe.addHyperlinkListener(new HyperlinkListener() {
            @Override
            public void hyperlinkUpdate(HyperlinkEvent he) {
                if (he.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
                    try {
                        Desktop.getDesktop().browse(he.getURL().toURI());
                    } catch (Exception ex) {
                        System.out.println(ex);
                    }
                }
            }
        });
        JScrollPane hilfescroll = new JScrollPane(hilfe);
        JPanel hilfefeld = new JPanel(new BorderLayout(FELDRAHMENABSTAND, 0));
        hilfefeld.setPreferredSize(new Dimension(BREITE, HOEHE));
        hilfefeld.setBorder(BorderFactory.createTitledBorder(null, "Hinweise zur (De)Installation", TitledBorder.LEFT,
                TitledBorder.ABOVE_TOP));
        hilfefeld.add(wechselgrafik, BorderLayout.WEST);
        hilfefeld.add(hilfescroll, BorderLayout.CENTER);
        return hilfefeld;
    }

    /**
     * Erstellt die Inhalte des Willkommendialogs.
     * 
     * @param titel
     *            Titel
     * @param textbereiche
     *            Alle Textbereiche
     * @param aktionsleiste
     *            Die Leiste mit den Elementen, welche Aktionen anstoßen
     * @return Feld mit allen Inhalten
     */
    private static JPanel inhalte(JLabel titel, JPanel textbereiche, JPanel aktionsleiste) {
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.setBorder(BorderFactory.createEmptyBorder(DIALOGRAHMENABSTAND, DIALOGRAHMENABSTAND, DIALOGRAHMENABSTAND,
                DIALOGRAHMENABSTAND));
        titel.setAlignmentX(Component.CENTER_ALIGNMENT);
        panel.add(titel);
        panel.add(Box.createVerticalStrut(DIALOGRAHMENABSTAND));
        panel.add(textbereiche);
        panel.add(Box.createVerticalStrut(DIALOGRAHMENABSTAND));
        panel.add(aktionsleiste);
        return panel;
    }

    /** @return Das Textfeld mit einer Kurzbeschreibung von JaFuffy */
    private static JTextArea kurzbeschreibung() {
        JTextArea beschreibung = new JTextArea(
                "JaFuffy ist ein Würfelspiel mit drei Spielregelvarianten, "
                        + "ähnlich zu Kniffel, Yahtzee oder Fuffy. " + "Spiele können zu Turnieren zusammengefasst, "
                        + "gespeichert und geladen werden. " + "Die besten Punktzahlen werden in Listen eingetragen. "
                        + "Bis zu vier Mitspieler sind möglich, wobei JaFuffy deren Rollen übernehmen kann.",
                ZEILEN, SPALTEN);
        beschreibung.setLineWrap(true);
        beschreibung.setWrapStyleWord(true);
        beschreibung.setEditable(false);
        beschreibung.setOpaque(false);
        beschreibung.setBorder(
                BorderFactory.createTitledBorder(null, "Kurzbeschreibung", TitledBorder.LEFT, TitledBorder.ABOVE_TOP));
        return beschreibung;
    }

    /**
     * Erstellt die Textbereiche für den Willkomendialog.
     * 
     * @param eigenschaften
     *            Eigenschaften, welche dauerhaft abgelegt werden.
     * @param wechselgrafik
     *            Die Wechselgrafik mit den Ziergrafiken
     * @return Die Textbereiche
     */
    private static JPanel textbereiche(final Eigenschaften eigenschaften, JPanel wechselgrafik) {
        JPanel texte = new JPanel(new BorderLayout(0, FELDRAHMENABSTAND));
        texte.add(kurzbeschreibung(), BorderLayout.NORTH);
        texte.add(hinweise(wechselgrafik), BorderLayout.CENTER);
        texte.add(aktualisierungspruefungsfrage(eigenschaften), BorderLayout.SOUTH);
        return texte;
    }

    /** @return Titel des Willkommendialogs */
    private static JLabel titel() {
        JLabel titel = new JLabel("Willkommen zu JaFuffy!", SwingConstants.CENTER);
        titel.setFont(TITELSCHRIFTART);
        return titel;
    }

    /** @return Wechselgrafik mit den umschaltbaren Ziergrafiken. */
    private static JPanel wechselgrafik() {
        JPanel grafik = new JPanel(new CardLayout());
        grafik.add(new JLabel(WILLKOMMEN1), ID1);
        grafik.add(new JLabel(WILLKOMMEN2), ID2);
        return grafik;
    }

    /**
     * Erstellt den Wechsler, welche zwischen den Ziergrafiken umschaltet.
     * 
     * @param wechselgrafik
     *            Enthält die Wechselgrafik
     * @return Timer, welcher den Wechsler anstößt.
     */
    private static Timer wechsler(JPanel wechselgrafik) {
        Timer timer = new Timer(WECHSELPERIODE, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                ((CardLayout) wechselgrafik.getLayout()).next(wechselgrafik);
            }
        });
        return timer;
    }

    /** Speichert, ob Installation abgebrochen wurde. */
    private boolean abgebrochen;

    /**
     * Konstruktor.
     * 
     * @param eigenschaften
     *            Die Eigenschaften, welche persistent abgelegt werden.
     */
    public Willkommen(Eigenschaften eigenschaften) {
        JPanel wechselgrafik = wechselgrafik();
        Timer wechsler = wechsler(wechselgrafik);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent event) {
                if (event.getID() == WindowEvent.WINDOW_CLOSED) {
                    wechsler.stop();
                }
            }
        });
        wechsler.start();
        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("JaFuffy (Eröffnungsmeldung)");
        setIconImages(Oberflaeche.LOGOS);
        setModal(true);
        setContentPane(inhalte(titel(), textbereiche(eigenschaften, wechselgrafik), aktionsleiste(eigenschaften)));
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    /** @return Gibt an, ob Installation abgebrochen wurde. */
    public boolean abgebrochen() {
        return abgebrochen;
    }

    /**
     * Erstellt die Aktionsleiste mit den Elemente, welche Aktionen anstoßen
     * 
     * @param eigenschaften
     *            Eigenschaften, welche dauerhaft abgelegt werden
     * @return Aktionsleiste
     */
    private JPanel aktionsleiste(Eigenschaften eigenschaften) {
        JButton abbruch = new JButton("Abbruch");
        abbruch.setToolTipText("Programm beenden");
        abbruch.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                abgebrochen = true;
                setVisible(false);
            }
        });
        JButton weiter = new JButton("Weiter");
        weiter.setToolTipText("Einstellungspfad wählen und Programm beginnen");
        weiter.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                new Pfad(eigenschaften, Willkommen.this);
                setVisible(false);
            }
        });
        JPanel leiste = new JPanel(new GridLayout(1, 2, DIALOGRAHMENABSTAND, 0));
        leiste.add(weiter);
        leiste.add(abbruch);
        getRootPane().setDefaultButton(weiter);
        return leiste;
    }
}
