package de.duehl.vocabulary.japanese.logic.symbol.kana.html;

import de.duehl.basics.text.html.generation.HtmlBuilder;
import de.duehl.vocabulary.japanese.data.symbol.Kana;
import de.duehl.vocabulary.japanese.logic.symbol.kana.html.data.KanaStructure;

/**
 * Diese Klasse erzeugt aus einer Struktur von Hiragana- oder Katakana-Zeichen eine Übersicht in
 * HTML.
 *
 * @version 1.01     2024-10-03
 * @author Christian Dühl
 */

public class KanaHtmlCreator {

    private static final String HTML_STYLE = """
                body {
                    font-size:14pt;
                    background-color:white;
                    color:black;
                }
                p {
                    background-color:white;
                    color:black;
                }
                table {
                    border: 1px solid;
                }
                th {
                    background-color:#DDD;
                    border: 1px solid;
                    margin:3px;
                    padding:5px;
                }
                td {
                    border: 1px solid;
                    margin:3px;
                    padding:5px;
                }
                .pronunciationChangedCell {
                    background-color:#FFFFE6;
                }
                .exceptionCell {
                    background-color:#FFE6E6;
                }
                .emptyCell, td.emptyCell {
                    border: 0px solid;
                }
                """;

    /** Die Struktur mit den darzustellenden Zeichen. */
    private final KanaStructure structure;

    /** Die anzuzeigende Bezeichnung der Schrift, also "Hiragana" oder "Katakana". */
    private final String kanaName;

    /** Das Objekt in dem das HTML aufgebaut wird. */
    private HtmlBuilder html;

    /**
     * Konstruktor.
     *
     * @param structure
     *            Die Struktur mit den darzustellenden Zeichen.
     * @param kanaName
     *            Die anzuzeigende Bezeichnung der Schrift, also "Hiragana" oder "Katakana".
     */
    public KanaHtmlCreator(KanaStructure structure, String kanaName) {
        this.structure = structure;
        this.kanaName = kanaName;
    }

    /** Erzeugt den HTML-Code. */
    public void create() {
        init();
        appendPageHead();
        appendMainTable();
        appendLehnwortTable();
        appendOtherKanaPart();
        appendLegend();
        appendFoot();
    }

    private void init() {
        html = new HtmlBuilder();
        html.appendHtml5HeadWithOwnExtendedCss(kanaName, HTML_STYLE);
    }

    private void appendPageHead() {
        html.append("<p style=\"font-size:28pt;\">"
                + kanaName + " Tabelle"
                + "</p>");
    }

    private void appendMainTable() {
        html.appendOpeningTable();


        appendMainTableHeadRow();

        appendMainTableARow();
        appendMainTableIRow();
        appendMainTableURow();
        appendMainTableERow();
        appendMainTableORow();

        appendSpaceRow();

        appendMainTableYaRow();
        appendMainTableYuRow();
        appendMainTableYoRow();

        html.appendClosingTable();
    }

    private void appendMainTableHeadRow() {
        html.appendOpeningTr();
        html.appendTh("p");
        html.appendTh("b");
        html.appendTh("d");
        html.appendTh("z");
        html.appendTh("g");
        html.appendTh("");
        html.appendTh("w");
        html.appendTh("r");
        html.appendTh("y");
        html.appendTh("m");
        html.appendTh("h");
        html.appendTh("n");
        html.appendTh("t");
        html.appendTh("s");
        html.appendTh("k");
        html.appendTh("");
        html.appendTh("");
        html.appendClosingTr();
    }

    private void appendMainTableARow() {
        html.appendOpeningTr();
        html.appendTd(createKanaCell(structure.getKanaPaPiPuPePo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaBaBiBuBeBo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaDaJiZuDeDo().get(0)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaZaJiZuZeZo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaGaGiGuGeGo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaN()));
        html.appendTd(createKanaCell(structure.getKanaWaWo().get(0)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaRaRiRuReRo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaYaYuYo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaMaMiMuMeMo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaHaHiFuHeHo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaNaNiNuNeNo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaTaChiTsuTeTo().get(0)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaSaShiSuSeSo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaKaKiKuKeKo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaAIUEO().get(0)));
        html.appendTh("a");
        html.appendClosingTr();
    }

    private void appendMainTableIRow() {
        html.appendOpeningTr();
        html.appendTd(createKanaCell(structure.getKanaPaPiPuPePo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaBaBiBuBeBo().get(1)));
        html.appendTd(createExceptionKanaCell(structure.getKanaDaJiZuDeDo().get(1)));
        html.appendTd(createExceptionKanaCell(structure.getKanaZaJiZuZeZo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaGaGiGuGeGo().get(1)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaRaRiRuReRo().get(1)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createKanaCell(structure.getKanaMaMiMuMeMo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaHaHiFuHeHo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaNaNiNuNeNo().get(1)));
        html.appendTd(createExceptionKanaCell(structure.getKanaTaChiTsuTeTo().get(1)));
        html.appendTd(createExceptionKanaCell(structure.getKanaSaShiSuSeSo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaKaKiKuKeKo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaAIUEO().get(1)));
        html.appendTh("i");
        html.appendClosingTr();
    }

    private void appendMainTableURow() {
        html.appendOpeningTr();
        html.appendTd(createKanaCell(structure.getKanaPaPiPuPePo().get(2)));
        html.appendTd(createKanaCell(structure.getKanaBaBiBuBeBo().get(2)));
        html.appendTd(createExceptionKanaCell(structure.getKanaDaJiZuDeDo().get(2)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaZaJiZuZeZo().get(2)));
        html.appendTd(createKanaCell(structure.getKanaGaGiGuGeGo().get(2)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaRaRiRuReRo().get(2)));
        html.appendTd(createKanaCell(structure.getKanaYaYuYo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaMaMiMuMeMo().get(2)));
        html.appendTd(createExceptionKanaCell(structure.getKanaHaHiFuHeHo().get(2)));
        html.appendTd(createKanaCell(structure.getKanaNaNiNuNeNo().get(2)));
        html.appendTd(createExceptionKanaCell(structure.getKanaTaChiTsuTeTo().get(2)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaSaShiSuSeSo().get(2)));
        html.appendTd(createKanaCell(structure.getKanaKaKiKuKeKo().get(2)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaAIUEO().get(2)));
        html.appendTh("u");
        html.appendClosingTr();
    }

    private void appendMainTableERow() {
        html.appendOpeningTr();
        html.appendTd(createKanaCell(structure.getKanaPaPiPuPePo().get(3)));
        html.appendTd(createKanaCell(structure.getKanaBaBiBuBeBo().get(3)));
        html.appendTd(createKanaCell(structure.getKanaDaJiZuDeDo().get(3)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaZaJiZuZeZo().get(3)));
        html.appendTd(createKanaCell(structure.getKanaGaGiGuGeGo().get(3)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaRaRiRuReRo().get(3)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createKanaCell(structure.getKanaMaMiMuMeMo().get(3)));
        html.appendTd(createKanaCell(structure.getKanaHaHiFuHeHo().get(3)));
        html.appendTd(createKanaCell(structure.getKanaNaNiNuNeNo().get(3)));
        html.appendTd(createKanaCell(structure.getKanaTaChiTsuTeTo().get(3)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaSaShiSuSeSo().get(3)));
        html.appendTd(createKanaCell(structure.getKanaKaKiKuKeKo().get(3)));
        html.appendTd(createKanaCell(structure.getKanaAIUEO().get(3)));
        html.appendTh("e");
        html.appendClosingTr();
    }

    private void appendMainTableORow() {
        html.appendOpeningTr();
        html.appendTd(createKanaCell(structure.getKanaPaPiPuPePo().get(4)));
        html.appendTd(createKanaCell(structure.getKanaBaBiBuBeBo().get(4)));
        html.appendTd(createKanaCell(structure.getKanaDaJiZuDeDo().get(4)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaZaJiZuZeZo().get(4)));
        html.appendTd(createKanaCell(structure.getKanaGaGiGuGeGo().get(4)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createKanaCell(structure.getKanaWaWo().get(1)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaRaRiRuReRo().get(4)));
        html.appendTd(createKanaCell(structure.getKanaYaYuYo().get(2)));
        html.appendTd(createKanaCell(structure.getKanaMaMiMuMeMo().get(4)));
        html.appendTd(createKanaCell(structure.getKanaHaHiFuHeHo().get(4)));
        html.appendTd(createKanaCell(structure.getKanaNaNiNuNeNo().get(4)));
        html.appendTd(createKanaCell(structure.getKanaTaChiTsuTeTo().get(4)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaSaShiSuSeSo().get(4)));
        html.appendTd(createKanaCell(structure.getKanaKaKiKuKeKo().get(4)));
        html.appendTd(createKanaCell(structure.getKanaAIUEO().get(4)));
        html.appendTh("o");
        html.appendClosingTr();
    }

    private void appendSpaceRow() {
        html.appendOpeningTr();
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTh("");
        html.appendClosingTr();
    }

    private void appendMainTableYaRow() {
        html.appendOpeningTr();
        html.appendTd(createKanaCell(structure.getKanaPyaPyuPyo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaByaByuByo().get(0)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaJaJuJo2().get(0)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaJaJuJo1().get(0)));
        html.appendTd(createKanaCell(structure.getKanaGyaGyuGyo().get(0)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaRyaRyuRyo().get(0)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createKanaCell(structure.getKanaMyaMyuMyo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaHyaHyuHyo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaNyaNyuNyo().get(0)));
        html.appendTd(createKanaCell(structure.getKanaChaChuCho().get(0)));
        html.appendTd(createKanaCell(structure.getKanaShaShuSho().get(0)));
        html.appendTd(createKanaCell(structure.getKanaKyaKyuKyo().get(0)));
        html.appendTd(createEmptyKanaCell());
        html.appendTh("ya");
        html.appendClosingTr();
    }

    private void appendMainTableYuRow() {
        html.appendOpeningTr();
        html.appendTd(createKanaCell(structure.getKanaPyaPyuPyo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaByaByuByo().get(1)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaJaJuJo2().get(1)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaJaJuJo1().get(1)));
        html.appendTd(createKanaCell(structure.getKanaGyaGyuGyo().get(1)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaRyaRyuRyo().get(1)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createKanaCell(structure.getKanaMyaMyuMyo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaHyaHyuHyo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaNyaNyuNyo().get(1)));
        html.appendTd(createKanaCell(structure.getKanaChaChuCho().get(1)));
        html.appendTd(createKanaCell(structure.getKanaShaShuSho().get(1)));
        html.appendTd(createKanaCell(structure.getKanaKyaKyuKyo().get(1)));
        html.appendTd(createEmptyKanaCell());
        html.appendTh("yu");
        html.appendClosingTr();
    }

    private void appendMainTableYoRow() {
        html.appendOpeningTr();
        html.appendTd(createKanaCell(structure.getKanaPyaPyuPyo().get(2)));
        html.appendTd(createKanaCell(structure.getKanaByaByuByo().get(2)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaJaJuJo2().get(2)));
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaJaJuJo1().get(2)));
        html.appendTd(createKanaCell(structure.getKanaGyaGyuGyo().get(2)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createPronunciationChangedKanaCell(structure.getKanaRyaRyuRyo().get(2)));
        html.appendTd(createEmptyKanaCell());
        html.appendTd(createKanaCell(structure.getKanaMyaMyuMyo().get(2)));
        html.appendTd(createKanaCell(structure.getKanaHyaHyuHyo().get(2)));
        html.appendTd(createKanaCell(structure.getKanaNyaNyuNyo().get(2)));
        html.appendTd(createKanaCell(structure.getKanaChaChuCho().get(2)));
        html.appendTd(createKanaCell(structure.getKanaShaShuSho().get(2)));
        html.appendTd(createKanaCell(structure.getKanaKyaKyuKyo().get(2)));
        html.appendTd(createEmptyKanaCell());
        html.appendTh("yo");
        html.appendClosingTr();
    }

    private void appendLehnwortTable() {
        html.appendP("Zusätzliche Kana für Lehnwörter");

        html.appendOpeningTable();
        html.appendOpeningTr();

        for (Kana kana : structure.getKanaLehnworte()) {
            html.appendTd(createKanaCell(kana));
        }

        html.appendClosingTr();

        html.appendClosingTable();
    }

    private void appendOtherKanaPart() {
        html.appendP("Sonstige Zeichen");

        html.appendOpeningTable();
        html.appendOpeningTr();

        html.appendTd(createKanaCell(structure.getKanaKleinesTsu()));
        for (Kana kana : structure.getKanaKleinesYaYuYo()) {
            html.appendTd(createKanaCell(kana));
        }

        html.appendClosingTr();

        html.appendClosingTable();
    }

    private void appendLegend() {
        html.appendP("Legende");

        html.appendOpeningTable();

        html.appendOpeningTr();
        html.appendTd(createPronunciationChangedKanaCell(new Kana("Aussprache anders", "")));
        html.appendTd(createExceptionKanaCell(new Kana("Ausnahme", "")));
        html.appendClosingTr();

        html.appendClosingTable();

    }

    private String createKanaCell(Kana kana) {
        return createKanaCell(kana, "");
    }

    private String createPronunciationChangedKanaCell(Kana kana) {
        return createKanaCell(kana, "pronunciationChangedCell");
    }

    private String createExceptionKanaCell(Kana kana) {
        return createKanaCell(kana, "exceptionCell");
    }

    private String createEmptyKanaCell() {
        //Kana emptyKana = new Kana("&nbsp;", "&nbsp;&nbsp;");
        //Kana emptyKana = new Kana(" ", "  ");
        Kana emptyKana = new Kana("", "");
        return createKanaCell(emptyKana, "emptyCell");
    }

    private String createKanaCell(Kana kana, String cssClass) {
        String openingP;
        if (cssClass.isBlank()) {
            openingP = "<p>";
        }
        else {
            openingP = "<p class=\"" + cssClass + "\">";
        }
        return "<center>" + openingP
                + "<span style=\"font-size:18pt;\">" + kana.getCharacter() + "</span>"
                + "<br />"
                + "<span style=\"font-size:12pt;\">" + kana.getHepburn() + "</span>"
                + "</p></center>";
    }

    private void appendFoot() {
        html.appendFoot();
    }

    /** Getter für den erzeugten HTML-Code. */
    public String getHtml() {
        return html.toString();
    }

}
