package de.duehl.basics.text.html;

/*
 * 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 java.util.List;

import de.duehl.basics.text.html.generation.HtmlBuilder;

/**
 * Diese Klasse erstellt aus einer Liste mit den Texten einer Reihe eine HTML-Tabelle.
 *
 * @version 1.01     2024-04-24
 * @author Christian Dühl
 */

public class HtmlTableCreator {

    private static final boolean SHOW_EMPTY_TABLE_HEAD = false;


    /** Die Liste mit den Inhalten der Zellen der Tabelle aus je einer Zeile. */
    private final List<List<String>> tableRowCellTexts;

    /** Der erzeugte HTML-Code mit der Tabelle. */
    private HtmlBuilder html;

    /** Die Anzahl der Zeilen der Tabelle. */
    private int numberOfRows;

    /** Die Anzahl der Spalten der Tabelle. */
    private int numberOfColumns;

    /** Gibt an, ob individuelle Farben für die Texte verwendet werden sollen. */
    private boolean useColors;

    /**
     * Die Liste der individuellen Farben. Gibt es mehr Texte als Farben, werden die Farben
     * zyklisch verwendet.
     */
    private List<String> colorHexcodes;

    /** Der nächste zu verwendende Index der Farben. */
    private int nextColorIndex;

    /**
     * Konstruktor.
     *
     * @param tableRowCellTexts
     *            Die Liste mit den Inhalten der Zellen der Tabelle aus je einer Zeile.
     */
    public HtmlTableCreator(List<List<String>> tableRowCellTexts) {
        this.tableRowCellTexts = tableRowCellTexts;

        useColors = false;
    }

    /** Übergibt eine Liste der zu verwendenden Farbcodes. */
    public void setColorHexcodes(List<String> colorHexcodes) {
        useColors = true;
        this.colorHexcodes = colorHexcodes;
        nextColorIndex = 0;
    }


    /** Erzeugt den HTML-Code mit der Tabelle. */
    public void create() {
        checkStartConstraints();
        init();
        createHtmlTable();
        finaliseHtml();
    }

    private void checkStartConstraints() {
        checkWeHaveTheSameAmountOfTextsInEachRow();
    }

    private void checkWeHaveTheSameAmountOfTextsInEachRow() {
        if (tableRowCellTexts.isEmpty()) {
            throw new RuntimeException("Die Liste der Texte der Zeilen ist leer.");
        }

        List<String> textsOfFirstRow = tableRowCellTexts.get(0);
        int wantedNumberOfTextsPerRow = textsOfFirstRow.size();
        for (int index = 0; index < tableRowCellTexts.size(); ++index) {
             List<String> textsOfRow = tableRowCellTexts.get(index);
            int numberOfTextsInRow = textsOfRow.size();
            if (numberOfTextsInRow != wantedNumberOfTextsPerRow) {
                throw new RuntimeException("Zwei Zeilen haben unterschiedlich viele Texte: "
                        + wantedNumberOfTextsPerRow + " in der ersten Zeile und "
                        + numberOfTextsInRow + " in der " + (index + 1) + ". Zeile.");
            }
        }
    }

    private void init() {
        initHtml();
        initNumberOfRows();
        initNumberOfColumns();
    }

    private void initHtml() {
        html = new HtmlBuilder();
        html.appendHtml5HeadWithOwnCssUtf8("Die extrahierte Tabelle");
    }

    private void initNumberOfRows() {
        numberOfRows = tableRowCellTexts.size();
    }

    private void initNumberOfColumns() {
        List<String> textsOfFirstRow = tableRowCellTexts.get(0);
        numberOfColumns = textsOfFirstRow.size();
    }

    private void createHtmlTable() {
        html.appendOpeningTableWithBorderWidth(2);

        if (SHOW_EMPTY_TABLE_HEAD) {
            html.appendOpeningTr();
            for (int columnIndex = 0; columnIndex < numberOfColumns; ++columnIndex) {
                html.appendLeftAlignedTh("");
            }
            html.appendClosingTr();
        }

        for (int rowIndex = 0; rowIndex < numberOfRows; ++rowIndex) {
            List<String> textsOfRow = tableRowCellTexts.get(rowIndex);

            html.appendOpeningTr();
            for (int columnIndex = 0; columnIndex < numberOfColumns; ++columnIndex) {
                String text = textsOfRow.get(columnIndex);
                appendCellText(text);
            }
            html.appendClosingTr();
        }

        html.appendClosingTable();
    }

    private void appendCellText(String text) {
        html.appendOpeningTd();
        if (useColors) {
            String color = colorHexcodes.get(nextColorIndex);
            html.append("<span style=\"font-family: monospace; color: #" + color + "\">" + text
                    + "</span>");
            switchToNextColorIndex();
        }
        else {
            html.appendPTT(text);
        }
        html.appendClosingTd();
    }

    private void switchToNextColorIndex() {
        ++nextColorIndex;
        if (nextColorIndex >= colorHexcodes.size()) {
            nextColorIndex = 0;
        }
    }

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

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

}
