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

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.Katakana;
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 Katakana.
 *
 * Es hält die Daten der Tabelle in Form einer Liste von Katakana-Objekten vor und weiß diese
 * anzuzeigen.
 *
 * @version 1.01     2025-11-20
 * @author Christian Dühl
 */

public class KatakanaTableModel 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<Katakana> katakanaList;

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

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

    /** Ermittelt die Zeilenzahl. */
    @Override
    public int getRowCount() {
        return katakanaList.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 Katakana in UTF-8 Darstellung.
     *     - Die Darstellung in Hepburn.
     *     - Der Untertyp der Katakana.
     * Außerdem die folgenden Spalten aus den internen Katakana-Daten:
     *     - Die Anzahl, wie oft das Katakana getestet wurde.
     *     - Die Anzahl, wie oft das Katakana erfolgreich getestet wurde.
     *     - Das Datum des letzten Tests.
     *     - Das Datum des letzten erfolgreichen Tests.
     *     - Das Abschneiden bei den letzten Tests.
     *     - Button zum Betrachten der Katakana 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) {
        Katakana katakana = katakanaList.get(rowIndex);
        InternalKanaDataRequester requester = dataStructures.getInternalKanaDataRequester();
        InternalAdditionalKanaData data = requester.getInternalDataForKatakana(katakana);
        switch (columnIndex) {
            case 0:
                return rowIndex + 1;
            case 1:
                return katakana.getCharacter();
            case 2:
                return katakana.getHepburn();
            case 3:
                return katakana.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 Katakana
            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) {
        Katakana katakana = katakanaList.get(rowIndex);
        InternalKanaDataRequester requester = dataStructures.getInternalKanaDataRequester();
        InternalAdditionalKanaData data = requester.getInternalDataForKatakana(katakana);
        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) {
        Katakana katakana = katakanaList.get(rowIndex);
        InternalKanaDataRequester requester = dataStructures.getInternalKanaDataRequester();
        InternalAdditionalKanaData data = requester.getInternalDataForKatakana(katakana);
        Options options = dataStructures.getOptions();
        VocableColors vocableColors = new VocableColors(options);
        return vocableColors.determineKanaBackgroundColor(data, true);
    }

}
