package de.duehl.swing.text.html;

/*
 * Copyright 2022 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 de.duehl.basics.collections.CollectionsHelper;
import de.duehl.swing.text.html.characteristic.OpticalTextPartCharacteristic;
import de.duehl.swing.text.html.data.HiddenMarkedHtmlPart;

import static de.duehl.swing.ui.colors.ColorTool.getHexColorByName;
import static de.duehl.swing.ui.colors.NamedColorListFabric.*;

import java.util.List;

public class TestText2Html extends Text2HtmlBase {

    private static final int STANDARD_FONT_SIZE = 20;

    private static final List<String> FRUITS = CollectionsHelper.buildListFrom(
            "Apfel", "Banane", "Orange", "Kirsche", "Erdbeere", "Kiwi", "Pampelmuse",
            "Birne", "Blaubeere");

    private static final List<String> VEGETABLES = CollectionsHelper.buildListFrom(
            "Gurke", "Tomate", "Erbse", "Bohne", "Erdbeere", "Kiwi", "Pampelmuse");

    private static final List<String> CHESS_PIECES = CollectionsHelper.buildListFrom(
            "König", "Dame", "Turm", "Läufer", "Springer", "Bauer");

    private static final List<String> CHESS_PHRASES = CollectionsHelper.buildListFrom(
            "Königsflügel", "Damenflügel", "Qualität", "Figur", "Gabel", "Spieß",
            "Schach", "Abzugsschach", "Doppelschach");

    private static final List<String> STREETS = CollectionsHelper.buildListFrom(
            "Deciusstraße", "Apfelstraße", "Beckhausstraße", "Detmolder Straße");

    private static final List<String> SENTENCES = CollectionsHelper.buildListFrom(
            "Der Apfel hängt am Birnbaum.",
            "Der Läufer zieht von c1 nach g5.");

    private final OpticalTextPartCharacteristic fruitsCharacteristics;
    private final OpticalTextPartCharacteristic vegetablesCharacteristics;
    private final OpticalTextPartCharacteristic chessPiecesCharacteristic;
    private final OpticalTextPartCharacteristic chessPhrasesCharacteristic;
    private final OpticalTextPartCharacteristic streetsCharacteristic;
    private final OpticalTextPartCharacteristic sentenceCharacteristic;

    private boolean hideOtherHighlightsInSentences;

    private List<HiddenMarkedHtmlPart> hiddenSentences;

    public TestText2Html() {
        super(STANDARD_FONT_SIZE);
        expandHighlightedToWholeWord();

        fruitsCharacteristics = new OpticalTextPartCharacteristic();
        fruitsCharacteristics.setForegroundHexColor(getHexColorByName(RED));
        fruitsCharacteristics.setBold(true);

        vegetablesCharacteristics = new OpticalTextPartCharacteristic();
        vegetablesCharacteristics.setForegroundHexColor(getHexColorByName(DARKGREEN));
        vegetablesCharacteristics.setItalic(true);

        chessPiecesCharacteristic = new OpticalTextPartCharacteristic();
        chessPiecesCharacteristic.setForegroundHexColor(getHexColorByName(PALEVIOLETRED));
        chessPiecesCharacteristic.setBackgroundHexColor(getHexColorByName(LIGHTRED));
        chessPiecesCharacteristic.setUseBackgroundColor(true);
        chessPiecesCharacteristic.setBold(true);

        chessPhrasesCharacteristic = new OpticalTextPartCharacteristic();
        chessPhrasesCharacteristic.setForegroundHexColor(getHexColorByName(DEEPPINK));
        chessPhrasesCharacteristic.setBackgroundHexColor(getHexColorByName(LIGHTYELLOW));
        chessPhrasesCharacteristic.setUseBackgroundColor(true);
        chessPhrasesCharacteristic.setBold(true);

        streetsCharacteristic = new OpticalTextPartCharacteristic();
        streetsCharacteristic.setForegroundHexColor(getHexColorByName(BLUEVIOLET));
        streetsCharacteristic.setBold(true);

        sentenceCharacteristic = new OpticalTextPartCharacteristic();
        sentenceCharacteristic.setForegroundHexColor(getHexColorByName(PALEGOLDENROD));
        sentenceCharacteristic.setBold(true);

        hideOtherHighlightsInSentences = false;
    }

    public void hideOtherHighlightsInSentences() {
        hideOtherHighlightsInSentences = true;
    }

    public String colorText(String text) {
        setText(text);
        colorIntern();
        return getText();
    }

    private void colorIntern() {
        highlightSentencesStart();
        highlightSpecialWords();
        highlightSentencesEnd();
        finalizeHtmlText();
    }

    private void highlightSentencesStart() {
        if (hideOtherHighlightsInSentences) {
            startMarkChanges("Satz-Markierung");
        }

        highlightSentences();

        if (hideOtherHighlightsInSentences) {
            hiddenSentences = hideMarkedParts("Satz-Platzhalter");
            endMarkChanges();
        }
    }

    private void highlightSentences() {
        replaceInTextWithCharacteristics(SENTENCES, sentenceCharacteristic);
    }

    private void highlightSentencesEnd() {
        if (hideOtherHighlightsInSentences) {
            reinsertHiddenMarkedParts(hiddenSentences);
        }
    }

    private void highlightSpecialWords() {
        replaceInTextWithCharacteristics(FRUITS, fruitsCharacteristics);
        replaceInTextWithCharacteristics(VEGETABLES, vegetablesCharacteristics);
        replaceInTextWithCharacteristics(CHESS_PIECES, chessPiecesCharacteristic);
        replaceInTextWithCharacteristics(CHESS_PHRASES, chessPhrasesCharacteristic);
        replaceInTextWithCharacteristics(STREETS, streetsCharacteristic);
    }

    /** Erzeugt eine Liste mit ähnlichen Suchbegriffen, die dann alle hervorgehoben werden. */
    @Override
    protected List<String> createFuzzyListOfSearchStrings(String searchString) {
        List<String> searchStringsWithFuzziness = CollectionsHelper.buildListFrom(searchString);

        for (String search : CollectionsHelper.copyList(searchStringsWithFuzziness)) {
            if (search.contains("str.")) {
                searchStringsWithFuzziness.add(search.replace("str.", "straße"));
                searchStringsWithFuzziness.add(search.replace("str.", "strasse"));
                searchStringsWithFuzziness.add(search.replace("str. ", "str "));
            }
            else if (search.contains("straße")) {
                searchStringsWithFuzziness.add(search.replace("straße", "str."));
            }
            else if (search.contains("strasse")) {
                searchStringsWithFuzziness.add(search.replace("strasse", "str."));
                searchStringsWithFuzziness.add(search.replace("strasse", "straße"));
            }
            else if (search.contains("str ")) {
                searchStringsWithFuzziness.add(search.replace("str ", "str. "));
                searchStringsWithFuzziness.add(search.replace("str ", "straße "));
            }
        }

        CollectionsHelper.makeListDisjunct(searchStringsWithFuzziness);

        return searchStringsWithFuzziness;
    }

}
