package de.duehl.basics.text.html.generation;

/*
 * Copyright 2024 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 static de.duehl.basics.text.html.generation.HtmlHeaderType.*;

import de.duehl.basics.text.html.generation.tools.Utf8MetaExchanger;

/**
 * Diese Klasse stellt einen StringBuilder zum Erstellen von HTML-Seiten dar, welcher die
 * Einrücktiefe selbst verwaltet.
 *
 * Hier sind nur solche Methoden enthalten, die lokales CSS in der erzeugten HTML-Datei generieren.
 *
 * Die Local- und deprecated-Funktionen wurden aus dem HtmlBuilder in diese Klasse ausgelagert.
 *
 * Weitere Ideen:
 *
 *     - CssConstants
 *     - CreateBaseCssFile
 *     - Alle Klartext Css-Klassen (oder IDs) nach CssConstants verschieben und in
 *       CreateBaseCssFile berücksichtigen.
 *     - Artikel, wenn alles fertig, Sourcen als Zip im gleichen Verzeichnis zum
 *       Download anbieten.
 *     - Deprectaed Methoden suchen und verbessern
 *     - HtmlTool - Methoden im Zusammenhang mit HtmlBuilder suchen...
 *     - Die Methode irgendwann umbenennen und aus den richtigen das html5 entfernen?
 *
 * @version 1.01     2024-07-10
 * @author Christian Dühl
 */

public class SwingHtmlBuilder extends HtmlBuilder {

    private static final String GREEN = "00A000";

    private static final String ORANGE = "ff6600";

    private static final String RED = "ff0000";

    /** Konstruktor. */
    public SwingHtmlBuilder() {
        super();
        createContentWithNames();
    }

    /**
     * Schreibt einen Paragraphen mit dem übergebenen Text in die Ausgabe, dabei wird dieser ohne
     * die Verwendung von global definiertem CSS über den style-Parameter rot eingefärbt.
     *
     * @param text
     *            Text innerhalb des p-Tags.
     */
    public SwingHtmlBuilder appendLocalColoredRedP(String text) {
        return appendLocalColoredP(text, RED);
    }

    /**
     * Schreibt einen Paragraphen mit dem übergebenen Text in die Ausgabe, dabei wird dieser ohne
     * die Verwendung von global definiertem CSS über den style-Parameter orange eingefärbt.
     *
     * @param text
     *            Text innerhalb des p-Tags.
     */
    public SwingHtmlBuilder appendLocalColoredOrangeP(String text) {
        return appendLocalColoredP(text, ORANGE);
    }

    /**
     * Schreibt einen Paragraphen mit dem übergebenen Text in die Ausgabe, dabei wird dieser ohne
     * die Verwendung von global definiertem CSS über den style-Parameter grün eingefärbt.
     *
     * @param text
     *            Text innerhalb des p-Tags.
     */
    public SwingHtmlBuilder appendLocalColoredGreenP(String text) {
        return appendLocalColoredP(text, GREEN);
    }

    /**
     * Schreibt einen Paragraphen mit dem übergebenen Text in die Ausgabe, dabei wird dieser ohne
     * die Verwendung von global definiertem CSS über den style-Parameter eingefärbt.
     *
     * @param text
     *            Text innerhalb des p-Tags.
     * @param hexColor
     *            Farbe des Paragraphen.
     */
    public SwingHtmlBuilder appendLocalColoredP(String text, String hexColor) {
        return appendLocalColoredTag("p", text, hexColor);
    }

    /**
     * Schreibt einen Paragraphen mit dem übergebenen Text in die Ausgabe, dabei wird dieser ohne
     * die Verwendung von global definiertem CSS über den style-Parameter eingefärbt.
     *
     * @param tag
     *            Name des Tags.
     * @param text
     *            Text innerhalb des Tags.
     * @param hexColor
     *            Farbe des Tags.
     */
    private SwingHtmlBuilder appendLocalColoredTag(String tag, String text, String hexColor) {
        String style = "style=\"" + createColorStylePart(hexColor) + "\"";
        appendInTagWithParameters(tag, text, style);
        return this;
    }

    private String createColorStylePart(String hexColor) {
        return "color:#" + hexColor;
    }

    private String createBackgroundColorStylePart(String hexColor) {
        return "background:#" + hexColor;
    }

    /**
     * Fügt einen Text umgeben von einem Tag (öffnender Tag vorn, schließender Tag hinten) ein, dabei
     * wird dieser ohne die Verwendung von global definiertem CSS über den style-Parameter
     * eingefärbt.
     * @param tag
     *            Name des Tags.
     * @param text
     *            Text innerhalb des Tags.
     * @param cssId
     *            CSS-ID.
     * @param hexColor
     *            Farbe des Tags.
     */
    private SwingHtmlBuilder appendLocalColoredTagWithId(String tag, String text, String cssId,
            String hexColor) {
        String style = "style=\"" + createColorStylePart(hexColor) + "\"";
        appendInTagWithParameters(tag, text, "id=\"" + cssId + "\"", style);
        return this;
    }

    /**
     * Schreibt eine Überschrift erster Ordnung mit dem übergebenen Text in die Ausgabe, dabei wird
     * dieser ohne die Verwendung von global definiertem CSS über den style-Parameter eingefärbt.
     *
     * @param text
     *            Text innerhalb der Überschrift.
     * @param hexColor
     *            Farbe der Überschrift.
     */
    public SwingHtmlBuilder appendLocalColoredH1(String text, String hexColor) {
        ++numberOfH1;
        return appendLocalColoredHeader(H1, text, hexColor);
    }

    /**
     * Schreibt eine Überschrift zweiter Ordnung mit dem übergebenen Text in die Ausgabe, dabei
     * wird dieser ohne die Verwendung von global definiertem CSS über den style-Parameter
     * eingefärbt.
     *
     * @param text
     *            Text innerhalb der Überschrift.
     * @param hexColor
     *            Farbe der Überschrift.
     */
    public SwingHtmlBuilder appendLocalColoredH2(String text, String hexColor) {
        ++numberOfH2;
        return appendLocalColoredHeader(H2, text, hexColor);
    }

    /**
     * Schreibt eine Überschrift dritter Ordnung mit dem übergebenen Text in die Ausgabe, dabei
     * wird dieser ohne die Verwendung von global definiertem CSS über den style-Parameter
     * eingefärbt.
     *
     * @param text
     *            Text innerhalb der Überschrift.
     * @param hexColor
     *            Farbe der Überschrift.
     */
    public SwingHtmlBuilder appendLocalColoredH3(String text, String hexColor) {
        ++numberOfH3;
        return appendLocalColoredHeader(H3, text, hexColor);
    }

    /**
     * Schreibt eine Überschrift vierter Ordnung mit dem übergebenen Text in die Ausgabe, dabei
     * wird dieser ohne die Verwendung von global definiertem CSS über den style-Parameter
     * eingefärbt.
     *
     * @param text
     *            Text innerhalb der Überschrift.
     * @param hexColor
     *            Farbe der Überschrift.
     */
    public SwingHtmlBuilder appendLocalColoredH4(String text, String hexColor) {
        ++numberOfH4;
        return appendLocalColoredHeader(H4, text, hexColor);
    }

    /**
     * Schreibt eine Überschrift fünfter Ordnung mit dem übergebenen Text in die Ausgabe, dabei
     * wird dieser ohne die Verwendung von global definiertem CSS über den style-Parameter
     * eingefärbt.
     *
     * @param text
     *            Text innerhalb der Überschrift.
     * @param hexColor
     *            Farbe der Überschrift.
     */
    public SwingHtmlBuilder appendLocalColoredH5(String text, String hexColor) {
        ++numberOfH5;
        return appendLocalColoredHeader(H5, text, hexColor);
    }

    /**
     * Schreibt eine Überschrift sechster Ordnung mit dem übergebenen Text in die Ausgabe, dabei
     * wird dieser ohne die Verwendung von global definiertem CSS über den style-Parameter
     * eingefärbt.
     *
     * @param text
     *            Text innerhalb der Überschrift.
     * @param hexColor
     *            Farbe der Überschrift.
     */
    public SwingHtmlBuilder appendLocalColoredH6(String text, String hexColor) {
        ++numberOfH6;
        return appendLocalColoredHeader(H6, text, hexColor);
    }

    private SwingHtmlBuilder appendLocalColoredHeader(HtmlHeaderType headerType, String text,
            String hexColor) {
        appendTopLinkIfNeccessary(headerType);
        String id = generateHeaderId(headerType);
        appendHeaderAndInsertLineBreakIfNotFirstContent(headerType, text, id);

        String tag = headerType.getHtmlTagName();
        appendLocalColoredTagWithId(tag, text,  id, hexColor);

        return this;
    }

    /**
     * Schreibt einen einzeiligen li-Tag in die Ausgabe, dabei wird dieser ohne die Verwendung von
     * global definiertem CSS über den style-Parameter eingefärbt.
     *
     * @param text
     *            Inhalt des li-Tags.
     * @param hexColor
     *            Farbe des li-Tags.
     */
    public SwingHtmlBuilder appendLocalColoredLi(String text, String hexColor) {
        return appendLocalColoredTag("li", text, hexColor);
    }

    /**
     * Schreibt einen einzeiligen span-Tag in die Ausgabe, dabei wird dieser ohne
     * die Verwendung von global definiertem CSS über den style-Parameter rot eingefärbt.
     *
     * @param text
     *            Text innerhalb des p-Tags.
     */
    public SwingHtmlBuilder appendLocalColoredRedSpan(String text) {
        return appendLocalColoredSpan(text, RED);
    }

    /**
     * Schreibt einen einzeiligen span-Tag in die Ausgabe, dabei wird dieser ohne
     * die Verwendung von global definiertem CSS über den style-Parameter orange eingefärbt.
     *
     * @param text
     *            Text innerhalb des p-Tags.
     */
    public SwingHtmlBuilder appendLocalColoredOrangeSpan(String text) {
        return appendLocalColoredSpan(text, ORANGE);
    }

    /**
     * Schreibt einen einzeiligen span-Tag in die Ausgabe, dabei wird dieser ohne
     * die Verwendung von global definiertem CSS über den style-Parameter grün eingefärbt.
     *
     * @param text
     *            Text innerhalb des p-Tags.
     */
    public SwingHtmlBuilder appendLocalColoredGreenSpan(String text) {
        return appendLocalColoredSpan(text, GREEN);
    }

    /**
     * Schreibt einen einzeiligen span-Tag in die Ausgabe, dabei wird dieser ohne die Verwendung
     * von global definiertem CSS über den style-Parameter eingefärbt.
     *
     * @param text
     *            Inhalt des span-Tags.
     * @param hexColor
     *            Farbe des span-Tags.
     */
    public SwingHtmlBuilder appendLocalColoredSpan(String text, String hexColor) {
        return appendLocalColoredTag("span", text, hexColor);
    }

    /**
     * Schreibt einen td-Tag mit Inhalt in die Ausgabe, dabei wird dieser ohne die Verwendung von
     * global definiertem CSS über den style-Parameter rechtsbündig formatiert.
     *
     * @param dataText
     *            Text der in den td-Tag kommt.
     */
    public SwingHtmlBuilder appendTdLocalRight(String text) {
        String style = "style=\"text-align:right;\"";
        appendInTagWithParameters("td", text, style);
        return this;
    }

    /**
     * Schreibt einen Paragraphen in großer Schriftgröße mit dem übergebenen Text in die Ausgabe,
     * dabei wird dieser ohne die Verwendung von global definiertem CSS über den style-Parameter in
     * großer Schriftgröße formatiert.
     *
     * @param text
     *            Text innerhalb des p-Tags.
     */
    public SwingHtmlBuilder appendLocalLargeP(String text) {
        String style = "style=\"font-size:large\"";
        appendInTagWithParameters("p", text, style);
        return this;
    }

    /**
     * Schreibt einen Paragraphen in großer Schriftgröße mit dem übergebenen Text in die Ausgabe,
     * dabei wird dieser ohne die Verwendung von global definiertem CSS über den style-Parameter in
     * großer Schriftgröße formatiert.
     *
     * @param text
     *            Text innerhalb des p-Tags.
     */
    public SwingHtmlBuilder appendLocalSmallP(String text) {
        String style = "style=\"font-size:x-small\"";
        appendInTagWithParameters("p", text, style);
        return this;
    }

    /**
     * Schreibt einen span-Tag mit Inhalt in die Ausgabe, dabei wird dieser ohne die Verwendung von
     * global definiertem CSS über den style-Parameter als monospaced-SChriftart formatiert.
     *
     * @param dataText
     *            Text der in den span-Tag kommt.
     */
    public SwingHtmlBuilder appendLocalTtSpan(String text) {
        String style = "style=\"font-family: monospace;\"";
        appendInTagWithParameters("span", text, style);
        return this;
    }

    /**
     * Erzeugt die Inhaltsverzeichnisse mit Hilfe von Namen anstelle von IDs. Damit gab es in der
     * Darstellung innerhalb von Swing Probleme. Außerhalb funktionieren die IDs wunderbar.
     */
    @Override
    public SwingHtmlBuilder createContentWithNames() {
        super.createContentWithNames();
        return this;
    }

    /** Unterdrückt die Links zum Seitenanfang über einer neuen H1-Überschrift. */
    @Override
    public SwingHtmlBuilder hideTopLinks() {
        super.hideTopLinks();
        return this;
    }

    /**
     * Fügt einen Kopf mit selbst erzeugtem CSS für body, p und die Überschriften hinzu, wobei eine
     * Metainformation ergänzt wird, dass der Inhalt in UTF-8 vorliegt.
     *
     * @param pageTitle
     *            Titel der Seite.
     * @param extendedCss
     *            Fügt diesen CSS-Abschnitt am Ende des in den Kopf der HTML-Seite einzufügenden
     *            Standard-CSS ein.
     */
    @Override
    public SwingHtmlBuilder appendHtml5HeadWithOwnExtendedCssUtf8(String pageTitle,
            String extendedCss) {
        super.appendHtml5HeadWithOwnExtendedCssUtf8(pageTitle, extendedCss);
        return this;
    }

    /** Erzeugt den Abschluss des HTML-Dokuments mit schließendem body- und html-Tag. */
    @Override
    public SwingHtmlBuilder appendFoot() {
        super.appendFoot();
        return this;
    }

    /**
     * Fügt die übergebenen Zeilen (der String wird an Zeilenumbrüchen dafür aufgetrennt) passend
     * eingerückt hinzu. Dafür sollte der übergebene Text in der kleinsten Einrückung die
     * Einrücktiefe null aufweisen, damit alles richtig aussieht.
     */
    @Override
    public SwingHtmlBuilder appendMultipleLines(String linesToSplit) {
        super.appendMultipleLines(linesToSplit);
        return this;
    }

    /** Schreibt einen öffnenden ul-Tag in die Ausgabe. */
    @Override
    public SwingHtmlBuilder appendOpeningUl() {
        super.appendOpeningUl();
        return this;
    }

    /** Schreibt einen öffnenden ul-Tag in die Ausgabe. */
    @Override
    public SwingHtmlBuilder appendClosingUl() {
        super.appendClosingUl();
        return this;
    }

    /**
     * Fügt einen öffnenden Tag der Form <tag style="..."> hinzu.
     *
     * @param tag
     *            Der zu öffnende Tag.
     * @param style
     *            CSS-Style-Angaben, die innerhalb der Anführungszeichen im style-Parameter
     *            eingefügt werden.
     */
    public SwingHtmlBuilder appendOpeningTagWithStyle(String tag, String style) {
        appendOpeningTagWithParameters(tag, "style=\"" + style + "\"");
        return this;
    }

    /**
     * Fügt einen öffnenden div-Tag der Form <div style="..."> hinzu.
     *
     * @param style
     *            CSS-Style-Angaben, die innerhalb der Anführungszeichen im style-Parameter
     *            eingefügt werden.
     */
    public SwingHtmlBuilder appendOpeningDivWithStyle(String style) {
        appendOpeningTagWithStyle("div", style);
        return this;
    }

    /**
     * Fügt einen öffnenden div-Tag der Form <div style="..."> hinzu.
     *
     * @param hexColor
     *            Hintergrundfarbe.
     */
    public SwingHtmlBuilder appendLocalBackgroundColoredDiv(String hexColor) {
        appendOpeningDivWithStyle(createBackgroundColorStylePart(hexColor));
        return this;
    }

    /**
     * Legt fest, dass auch vor dem Anfang einer neuen Überschrift vom Typ H2 ein Link zum Anfang
     * angezeigt werden soll.
     */
    @Override
    public SwingHtmlBuilder appendTopLinksToH2() {
        super.appendTopLinksToH2();
        return this;
    }

    /** Fügt einen Anker hinzu, zu dem die TopLinks springen. */
    @Override
    public SwingHtmlBuilder appendTopAnker() {
        super.appendTopAnker();
        return this;
    }

    /** Ergänzt eine Metainformation, dass der Inhalt in UTF-8 vorliegt. */
    @Override
    protected final SwingHtmlBuilder appendMetaUtf8() {
        //appendLn("<meta charset=\"utf-8\">");
        //appendLn("<meta http-equiv=\"content-Type\" content=\"text/html; charset=utf-8\">");
        appendLn(Utf8MetaExchanger.UTF8_META_LONG);

        return this;
        /*
         * Siehe auch:
         *     https://www.w3.org/International/questions/qa-html-encoding-declarations.de
         *
         * Seltsamer Weise funktioniert es auf meinem PC zu Hause unter Swing nur so, nicht
         * anders, auf dem PC bei der Arbeit geht beides.
         *
         * Es geht nicht mit
         *     appendLn("<meta charset=\"utf-8\">");
         */
    }

}
