package de.duehl.vocabulary.japanese.ui.dialog.table.hiragana;

import java.awt.Color;
import java.util.List;

import javax.swing.table.AbstractTableModel;

import de.duehl.basics.datetime.date.ImmutualDate;
import de.duehl.vocabulary.japanese.common.color.VocableColors;
import de.duehl.vocabulary.japanese.common.data.InternalAdditionalKanaData;
import de.duehl.vocabulary.japanese.common.persistence.Options;
import de.duehl.vocabulary.japanese.data.FumikoDataStructures;
import de.duehl.vocabulary.japanese.data.symbol.Hiragana;
import de.duehl.vocabulary.japanese.logic.symbol.kana.internal.InternalKanaDataRequester;
import de.duehl.vocabulary.japanese.ui.dialog.table.TableHelper;

/**
 * Diese Klasse ist ein eigenes Tabellenmodell für die Ansicht der Hiragana.
 *
 * Es hält die Daten der Tabelle in Form einer Liste von Hiragana-Objekten vor und weiß diese
 * anzuzeigen.
 *
 * @version 1.01     2025-11-20
 * @author Christian Dühl
 */

public class HiraganaTableModel extends AbstractTableModel {

    private static final int NUMBER_OF_COLUMNS = 10;

    private static final long serialVersionUID = 1L;


    /** Die Liste mit den Kana der Tabelle. */
    private final List<Hiragana> hiraganaList;

    /** Die Datenstrukturen des Vokabeltrainers. */
    private final FumikoDataStructures dataStructures;

    /**
     * Konstruktor.
     *
     * @param hiraganaList
     *            Die Liste mit den Hiragana der Tabelle.
     * @param dataStructures
     *            Die Datenstrukturen des Vokabeltrainers.
     */
    public HiraganaTableModel(List<Hiragana> hiraganaList, FumikoDataStructures dataStructures) {
        super();
        this.hiraganaList = hiraganaList;
        this.dataStructures = dataStructures;
    }

    /** Ermittelt die Zeilenzahl. */
    @Override
    public int getRowCount() {
        return hiraganaList.size();
    }

    /** Ermittelt die Spaltenzahl. */
    @Override
    public int getColumnCount() {
        return NUMBER_OF_COLUMNS;
    }

    /**
     * Gibt an, ob die Zelle bearbeitbar ist. Dies muss für die Buttons der Fall sein.
     *
     * @param rowIndex
     *            Zeilenindex (die erste hat die 0)
     * @param columnIndex
     *            Spaltenindex (die erste hat die 0)
     */
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return columnIndex == 9;
    }

    /**
     * Ermittelt den Tabelleninhalt der angegebenen Zelle.
     *
     * Die Tabelle enthält die folgenden Spalten:
     *     - Die laufende Nummer.
     *     - Das Hiragana in UTF-8 Darstellung.
     *     - Die Darstellung in Hepburn.
     *     - Der Untertyp der Hiragana.
     * Außerdem die folgenden Spalten aus den internen Hiragana-Daten:
     *     - Die Anzahl, wie oft das Hiragana getestet wurde.
     *     - Die Anzahl, wie oft das Hiragana erfolgreich getestet wurde.
     *     - Das Datum des letzten Tests.
     *     - Das Datum des letzten erfolgreichen Tests.
     *     - Das Abschneiden bei den letzten Tests.
     *     - Button zum Betrachten der Hiragana mit allen internen Daten
     *
     * @param rowIndex
     *            Zeilenindex (die erste hat die 0)
     * @param columnIndex
     *            Spaltenindex (die erste hat die 0)
     */
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Hiragana hiragana = hiraganaList.get(rowIndex);
        InternalKanaDataRequester requester = dataStructures.getInternalKanaDataRequester();
        InternalAdditionalKanaData data = requester.getInternalDataForHiragana(hiragana);
        switch (columnIndex) {
            case 0:
                return rowIndex + 1;
            case 1:
                return hiragana.getCharacter();
            case 2:
                return hiragana.getHepburn();
            case 3:
                return hiragana.getSubType().getDescription();
            case 4:
                return data.getTestCount();
            case 5:
                return data.getCorrectTestCount();
            case 6:
                return TableHelper.dateOrEmpty(data.getLastTestDate(), data.getTestCount());
            case 7:
                return TableHelper.dateOrEmpty(data.getLastCorrectTestDate(),
                        data.getCorrectTestCount());
            case 8:
                return TableHelper.createMonospaceHtml(data.getLastTenTestResultsAsStorageString());
            case 9:
                return "Details";
            default:
                throw new RuntimeException("Unzuläsiger Spaltenindex '" + columnIndex + "'.");
        }
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
            case 0:
            case 4:
            case 5:
            case 8:
                return Integer.class;
            case 1:
            case 2:
            case 3:
                return String.class;
            case 6:
            case 7:
                return ImmutualDate.class;
                // 9 ist der Button zum Anzeigen der Details des Hiragana
            default:
                return String.class;
        }
    }

    /**
     * Erzeugt die Vordergrundfarbe für die Zeile mit dem übergebenen Zeilenindex.
     *
     * @param rowIndex
     *            Zeilenindex (die erste hat die 0)
     * @return Farbwert für den Vordergrund.
     */
    public Color determineRowForegroundColor(int rowIndex) {
        Hiragana hiragana = hiraganaList.get(rowIndex);
        InternalKanaDataRequester requester = dataStructures.getInternalKanaDataRequester();
        InternalAdditionalKanaData data = requester.getInternalDataForHiragana(hiragana);
        Options options = dataStructures.getOptions();
        VocableColors vocableColors = new VocableColors(options);
        return vocableColors.determineKanaForegroundColor(data, true);
    }

    /**
     * Erzeugt die Hintergrundfarbe für die Zeile mit dem übergebenen Zeilenindex.
     *
     * @param rowIndex
     *            Zeilenindex (die erste hat die 0)
     * @return Farbwert für den Hintergrund.
     */
    public Color determineRowBackgroundColor(int rowIndex) {
        Hiragana hiragana = hiraganaList.get(rowIndex);
        InternalKanaDataRequester requester = dataStructures.getInternalKanaDataRequester();
        InternalAdditionalKanaData data = requester.getInternalDataForHiragana(hiragana);
        Options options = dataStructures.getOptions();
        VocableColors vocableColors = new VocableColors(options);
        return vocableColors.determineKanaBackgroundColor(data, true);
    }

}
