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.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

/**
 * Diese Klasse stellt die abstrakte Basis für die projektspezifischen Klassen, die alle Karten
 * definieren, dar.
 *
 * @version 1.01     2016-12-07
 * @author Christian Dühl
 */

public abstract class Cards {

    /** Liste aller Karten. */
    private final List<Card> cards;

    /** Konstruktor. */
    protected Cards() {
        cards = new ArrayList<>();
    }

    /**
     * Fügt eine neue Karte hinzu. Die Nummer des Schrittes wird aus der Reihenfolge des
     * Hinzufügens berechnet.
     *
     * @param name
     *            Eindeutiger Name der Karte zur Verwendung im CardLayout.
     * @param gui
     *            Zur Karte gehörige grafische Oberfläche.
     * @param logic
     *            Zur Karte gehörige Logik.
     * @param nameForGui
     *            Name des Schrittes, wie er in der Oberfläche angezeigt werden soll.
     */
    protected final void addCard(String name, CardGui gui, CardLogic logic, String nameForGui) {
        int stepNumber = cards.size() + 1;
        Card card = new Card(name, gui, logic, stepNumber, nameForGui);
        card.setCards(this);
        cards.add(card);
    }

    /** Getter für die erste Karte. */
    Card getFirstCard() {
        return cards.get(0);
    }

    /**
     * Getter für die nächste Karte.
     *
     * @param currentCard
     *            Aktuell angezeigte Karte.
     * @return Nächste Karte.
     */
    Card getNext(Card currentCard) {
        int currentIndex = cards.indexOf(currentCard);
        int nextIndex = currentIndex + 1;
        if (nextIndex >= cards.size()) {
            throw new RuntimeException("Keine weitere Karte vorhanden.");
        }
        Card card = cards.get(nextIndex);
        return card;
    }

    /**
     * Fügt alle Karten zum Panel, das die Karten darstellt, hinzu.
     *
     * @param panel
     *            Das Panel, das die Karten darstellt.
     * @param switcher
     *            Objekt zum Weiterschalten auf die nächste Karte bzw. zum Beenden des Programms.
     */
    void addAllCardsToPanel(JPanel panel, CardSwitcher switcher) {
        for (Card card : cards) {
            panel.add(card.createCardGui(switcher), card.getName());
        }
    }

    /**
     * Überprüft die übergebene Schrittnummer und wirft eine Ausnahme, wenn diese nicht im
     * erlaubten Bereich ist.
     *
     * @param stepNumber
     *            Nummer des Schritts (1-basiert).
     */
    public void checkStepNumber(int stepNumber) {
        if (stepNumber < 1) {
            throw new IllegalArgumentException("Die Schrittnummer " + stepNumber
                    + " ist zu klein, sie muss mindestens 1 betragen.");
        }
        if (stepNumber > cards.size()) {
            throw new IllegalArgumentException("Die Schrittnummer " + stepNumber
                    + " ist zu groß, sie darf höchstens " + cards.size() + " betragen.");
        }
    }

    /** Getter für die Anzahl der Schritte. */
    public int getNumberOfSteps() {
        return cards.size();
    }

    /**
     * Getter für die Karte zur übergebenen Schrittnummer.
     *
     * @param stepNumber
     *            Nummer des Schritts (1-basiert).
     */
    public Card getCard(int stepNumber) {
        checkStepNumber(stepNumber);
        int index = stepNumber - 1;
        return cards.get(index);
    }

//    public List<Card> getCards() {
//        List<Card> copiedList = new ArrayList<>(cards);
//        return copiedList;
//    }

}
