package de.duehl.swing.ui.highlightingeditor;

import java.awt.Color;

import javax.swing.SwingUtilities;
import javax.swing.event.DocumentListener;

import de.duehl.swing.ui.highlightingeditor.contextmenu.EditorPopupMenu;
import de.duehl.swing.ui.highlightingeditor.multiplereactor.MultipleChangeReactor;
import de.duehl.swing.ui.highlightingeditor.syntax.SyntaxHighlighting;
import de.duehl.swing.ui.highlightingeditor.textcomponent.NotEditableScrollingSuppressingTextPane;
import de.duehl.swing.ui.highlightingeditor.textcomponent.ScrollingSuppressingTextPane;
import de.duehl.swing.ui.highlightingeditor.userinput.ReactAfterUserInput;
import de.duehl.swing.ui.tabs.ChangeStateDisplayer;

/**
 * Diese Klasse stellt einen bearbeitbaren Viewer mit Syntax-Highlighting dar.
 *
 * @version 1.01     2017-12-18
 * @author Christian Dühl
 */

public class HighlightingViewer extends HighlightingEditorWithoutButtonBar {

    public static final Color INACTIVE_TEXT_PANE_BACKGROUND = new Color(230, 230, 230);

    public HighlightingViewer() {
        disableWatchFileOnDiskChange(); // wollen wir das wirklich?
    }

    @Override
    protected ScrollingSuppressingTextPane createEditor() {
        ScrollingSuppressingTextPane editor = super.createEditor();
        editor.setEditable(false);
        editor.setBackground(INACTIVE_TEXT_PANE_BACKGROUND);
        return editor;
    }

    @Override
    protected ScrollingSuppressingTextPane createScrollingSuppressingTextPane() {
        return new NotEditableScrollingSuppressingTextPane();
    }

    @Override
    protected ReactAfterUserInput createHighlightAfterUserInput() {
        return null;
    }

    @Override
    protected MultipleChangeReactor createMultipleChangeReactor() {
        MultipleChangeReactor multipleChangeReactor = new MultipleChangeReactor();

        // kein highlighting
        multipleChangeReactor.addChangeReactor(editor);                  // scrolling
        // kein track change state

        return multipleChangeReactor;
    }

    @Override
    protected void createPopupMenu() {
        EditorPopupMenu popupMenu = new EditorPopupMenu(this);
        popupMenu.deactivateInsertMenuItem(); // Kontextmenü : insert ausgrauen
        editor.setComponentPopupMenu(popupMenu);
    }

    /**
     * Gibt an, ob der Inhalt des Editors geändert wurde.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public boolean isContentChanged() {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

    /**
     * Fügt dem Editor einen DocumentListener hinzu.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void addDocumentListener(DocumentListener listener) {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

    /** Setzt die zu verwendende Syntax-Hervorhebung, falls eine gewünscht wird. */
    @Override
    public void useSyntaxHighlighting(SyntaxHighlighting sytaxHighlighting) {
        say("VIEWER - useSyntaxHighlighting" + sytaxHighlighting);
        super.initSyntaxHighlighting(sytaxHighlighting);
        SwingUtilities.invokeLater(() -> super.highlightTextInEdt());
    }

    /**
     * Führt die Auszeichnung der Syntax des Textes durch.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void highlightText() {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

    /**
     * Zeigt an, dass das Dokument geändert worden ist.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void signChangedState() {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

    /**
     * Zeigt an, dass das Dokument im Originalzustand vorliegt.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    protected void signUnchangedState() {
        //throw new RuntimeException("Nicht bei Viewer verwenden!");
        // da es von open() aufgerufen wird, tun wir hier einfach nichts.
    }

    /**
     * Fügt einen Beobachter des Editor-Status hinzu, der anzeigen kann, ob ein Dokument geändert
     * worden ist oder im Originalzustand ist.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void addChangeStateDisplayer(ChangeStateDisplayer changeStateDisplayer) {
        //throw new RuntimeException("Nicht bei Viewer verwenden!");
        // Da es im Konstruktor aufgerufen wird, tun wir hier einfach nichts.
    }

    /**
     * Inhalt der Zwischenablage einfügen.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void insertSelection() {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

    /**
     * Erstellt ein neues, leeres Dokument.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void newFile() {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

//    @Override
//    protected void updateDisplayName() {
//        throw new RuntimeException("Nicht bei Viewer verwenden!");
//    }
    // wird nach dem öffnen des Textes benötigt...

    /**
     * Lädt ein Dokument.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void openFile() {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

//    /**
//     * Öffnet ein Dokument im Default-Charset.
//     *
//     * Hierbei wird davon aufgerufen, dass sich die aufrufende Seite darum kümmert, die grafische
//     * Oberfläche vor dem Aufruf zu sperren, diese Methode in einem eigenen Thread aufzurufen, und
//     * die grafische Oberfläche hinterher wieder freizugeben.
//     *
//     * Nicht beim Viewer zu verwenden!
//     */
//    @Override
//    public void openFile(String filename) {
//        throw new RuntimeException("Nicht bei Viewer verwenden!");
//    }
//
//    /**
//     * Öffnet ein Dokument.
//     *
//     * Hierbei wird davon aufgerufen, dass sich die aufrufende Seite darum kümmert, die grafische
//     * Oberfläche vor dem Aufruf zu sperren, diese Methode in einem eigenen Thread aufzurufen, und
//     * die grafische Oberfläche hinterher wieder freizugeben.
//     *
//     * Nicht beim Viewer zu verwenden!
//     */
//    @Override
//    public void openFile(String filename, Charset charset) {
//        throw new RuntimeException("Nicht bei Viewer verwenden!");
//    }

    /**
     * Speichert das Dokument.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void saveFile() {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

    /**
     * Speichert das Dokument unter einem anderen Namen.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void saveFileAs() {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

    /**
     * Beendet den Timer der auf Eingaben des Benutzers wartet.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void cancelTimer() {
        // nichts zu tun, da der gar nicht erst eingerichtet wurde!
    }

//    /**
//     * Name der Datei, die im Editor angezeigt wird. Der leere String, wenn die Datei bislang
//     * keinen Namen hat.
//     *
//     * Nicht beim Viewer zu verwenden!
//     */
//    @Override
//    public String getFilename() {
//        throw new RuntimeException("Nicht bei Viewer verwenden!");
//    }
    // wird in TabBarWithEditorTabs#createNewTabElements() benötigt.

//    @Override
//    public void setFilenameButDoNotDoAnythingElse(String filename) {
//        throw new RuntimeException("Nicht bei Viewer verwenden!");
//    }
    // wird zum Anzeigen des Titels gebraucht.

    /**
     * Getter für den aktuellen Text des Editors.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public String getText() {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

    /**
     * Setter für den aktuellen Text des Editors.
     *
     * Nicht beim Viewer zu verwenden!
     */
    @Override
    public void setText(String text) {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

    @Override
    public void showEnd() {
        throw new RuntimeException("Nicht bei Viewer verwenden!");
    }

    @Override
    public String toString() {
        return "HighlightingViewer [filename=" + super.getFilename() + "]";
    }

}
