package de.duehl.swing.ui.layout.card;

/*
 * Copyright 2016 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import java.awt.CardLayout;

import javax.swing.JPanel;

import static de.duehl.swing.ui.layout.card.CardDebug.say;

/**
 * Diese Klasse enthält die Teile, die normalerweise im Rahmenprogramm stehen, das die Oberfläche,
 * in die die Karten eingebettet werden, erstellt. Es kümmert sich um das Zusammenspiel der Karten
 * mit der Gui des Programms.
 *
 * @version 1.01     2016-12-07
 * @author Christian Dühl
 */

public class CardHandling {

    /** Das Layout für den Panel mit den Karten. */
    private final CardLayout cardLayout;

    /** Das Panel, das die Karten darstellt. */
    private final JPanel cardPanel;

    /** Die Karten. */
    private final Cards cards;

    /** Aktuell angezeigte Karte. */
    private Card currentCard;

    /** Gibt an, ob die Bearbeitung abgebrochen wurde. */
    private boolean interrupted;

    /** Gibt an, ob der Dialog zum Beenden des Programms geöffnet wurde. */
    private boolean quitDialogStarted;

    /**
     * Gibt an, ob später (nachdem der Benutzer den Dialog zum Beenden des Programms abgebrochen
     * hat, ein Kartenwechsel erfolgen soll.
     */
    private boolean switchCardLater;

    /**
     * Konstruktor.
     *
     * @param cards
     *            Die Karten.
     */
    public CardHandling(Cards cards) {
        this.cards = cards;
        cardPanel = new JPanel();
        cardLayout = new CardLayout();
        cardPanel.setLayout(cardLayout);
        currentCard = cards.getFirstCard();
        interrupted = false;
        quitDialogStarted = false;
        switchCardLater = false;
        say("currentCard: " + currentCard.getName());
    }

    /** Getter für das Panel, das die Karten darstellt. */
    public JPanel getCardPanel() {
        return cardPanel;
    }

    /**
     * Fügt alle Karten zum Panel, das die Karten darstellt, hinzu.
     *
     * @param switcher
     *            Objekt zum Weiterschalten auf die nächste Karte bzw. zum Beenden des Programms.
     */
    public void addAllCardsToPanel(CardSwitcher switcher) {
        cards.addAllCardsToPanel(cardPanel, switcher);
    }

    /** Schaltet auf die nächste Karte um. */
    synchronized public void switchCard() {
        say("called. interrupted = " + interrupted + ", quitDialogStarted = " + quitDialogStarted
                + ", switchCardLater = " + switchCardLater);

        if (interrupted) {
            say("aborted because interrupted");
            return;
        }
        if (quitDialogStarted) {
            say("aborted because quit dialog was started");
            switchCardLater = true;
            return;
        }
        switchCardLater = false;

        say("Räume Karte " + currentCard.getName() + " auf...");
        Card previousCard = currentCard;
        previousCard.cleanUp();

        say("Ermittle nächste Karte ...");
        currentCard = cards.getNext(previousCard);
        say("Nächste Karte: " + currentCard.getName());
        cardLayout.show(cardPanel, currentCard.getName());
        currentCard.runWhenShown(previousCard);
        cardPanel.validate();
    }

    /** Wird aufgerufen, wenn der Benutzer das Programm im laufenden Betrieb beendet. */
    synchronized public void quit() {
        say("called");
        interrupted = true;
        currentCard.quit();
        System.exit(1); // TODO sehr unschön, aber im Moment die einzige Möglichkeit die laufenden
                        // Threads zu unterbrechen.
    }

    /**
     * Wird aufgerufen, wenn der Benutzer auf das kleine x oben rechts klickt und sich der Dialog
     * zum Beenden des Programms öffnet.
     */
    synchronized public void quitDialogStarted() {
        say("called");
        quitDialogStarted = true;
    }

    /**
     * Wird aufgerufen, wenn der Benutzer den Dialog zum Beenden des Programms abbricht (also das
     * Programm doch nicht beendet).
     */
    synchronized public void quitDialogAborted() {
        say("called");
        quitDialogStarted = false;
        if (switchCardLater) {
            switchCard();
        }
    }

}
