package de.duehl.swing.ui.text;

/*
 * Copyright 2025 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.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;

import javax.swing.JButton;
import javax.swing.JPanel;

import de.duehl.swing.ui.colors.Colorizer;
import de.duehl.swing.ui.dialogs.base.ModalDialogBase;

/**
 * Diese Klasse stellt den Dialog zum Anzeigen eines Textes im Editor dar.
 *
 * @version 1.01     2025-05-28
 * @author Christian Dühl
 */

public class TextViewer extends ModalDialogBase {

    private static final Dimension DIALOG_DIMENSION = new Dimension(850, 650);

    /** Die Komponente mit dem Text, der angezeigt (oder im Editor editiert) wird. */
    private final TextPanel textPanel;

    /** Der OK-Button. */
    private final JButton okButton;

    /** Das Panel mit den Buttons. */
    private final JPanel buttonPanel;

    /** Gibt an, ob der Dialog mit OK beendet wurde. */
    private boolean applied;

    /** Gibt an, ob ein Button zum Abbrechen angezeigt werden soll. */
    private boolean showQuitButton;

    /** Der Text für den Button zum Abbrechen. */
    private String quitButtonText;

    /**
     * Konstruktor.
     *
     * @param dialogTitle
     *            Titel des Dialogs.
     */
    public TextViewer(String dialogTitle) {
        this(dialogTitle, new Point(0, 0), null, null, DIALOG_DIMENSION);
    }

    /**
     * Konstruktor als Viewer.
     *
     * @param dialogTitle
     *            Titel des Dialogs.
     * @param parentLocation
     *            Position des Rahmens des Aufrufers.
     */
    public TextViewer(String dialogTitle, Point parentLocation) {
        this(dialogTitle, parentLocation, null, null, DIALOG_DIMENSION);
    }

    /**
     * Konstruktor als Viewer.
     *
     * @param dialogTitle
     *            Titel des Dialogs.
     * @param parentLocation
     *            Position des Rahmens des Aufrufers.
     * @param dimension
     *            Die Dimension des Dialogs.
     */
    public TextViewer(String dialogTitle, Point parentLocation, Dimension dimension) {
        this(dialogTitle, parentLocation, null, null, dimension);
    }

    /**
     * Konstruktor.
     *
     * @param dialogTitle
     *            Titel des Dialogs.
     * @param parentLocation
     *            Position des Rahmens des Aufrufers.
     * @param colorizer
     *            Farbverwaltung für die Gui.
     * @param programImage
     *            Bild des Programms.
     */
    public TextViewer(String dialogTitle, Point parentLocation, Colorizer colorizer,
            Image programImage) {
        this(dialogTitle, parentLocation, colorizer, programImage, DIALOG_DIMENSION);
    }

    /**
     * Konstruktor.
     *
     * @param dialogTitle
     *            Titel des Dialogs.
     * @param parentLocation
     *            Position des Rahmens des Aufrufers.
     * @param colorizer
     *            Farbverwaltung für die Gui.
     * @param programImage
     *            Bild des Programms.
     * @param dimension
     *            Die Dimension des Dialogs.
     */
    public TextViewer(String dialogTitle, Point parentLocation, Colorizer colorizer,
            Image programImage, Dimension dimension) {
        super(parentLocation, programImage, dialogTitle, dimension, colorizer);
        addEscapeBehaviour();

        textPanel = new TextPanel();
        initTextComponent();

        okButton = new JButton("OK");
        initOkButton();

        buttonPanel = new JPanel();
        initButtonPanel();

        showQuitButton = false;
        quitButtonText = "";
        applied = false;

        fillDialog();
        setKeyBindings();
    }

    public void addQuitButton(String quitButtonText) {
        this.quitButtonText = quitButtonText;
        showQuitButton = true;
        initButtonPanel();
    }

    protected void initTextComponent() {
        textPanel.setColors(getColorizer());
    }

    protected final void switchToEditable() {
        textPanel.setEditable(true);
    }

    private void initOkButton() {
        setColors(okButton);
        okButton.addActionListener(e -> okPressed());
    }

    protected void okPressed() {
        applied = true;
        closeDialog();
    }

    /**
     * Erzeugt den unteren Bereich mit den Buttons.
     *
     * @return Erzeugtes Panel.
     */
    private void initButtonPanel() {
        setColors(buttonPanel);
        buttonPanel.setLayout(new BorderLayout());

        buttonPanel.add(okButton, BorderLayout.EAST);
        buttonPanel.add(createLeftButtonPart(), BorderLayout.WEST);
    }

    protected final Component getOkButton() {
        return okButton;
    }

    protected final JPanel getButtonPanel() {
        return buttonPanel;
    }

    protected Component createLeftButtonPart() {
        JPanel panel = new JPanel();
        setColors(panel);
        panel.setLayout(new BorderLayout());

        // Hier normalerweise mit nichts gefüllt.

        if (showQuitButton) {
            panel.add(createQuitButton(), BorderLayout.CENTER);
        }

        return panel;
    }

    private Component createQuitButton() {
        JButton button = new JButton(quitButtonText);
        button.addActionListener(e -> closeDialog());
        return button;
    }

    /** Verwendet einen Font, der für Sourcecode und Daten geeignet ist. */
    public final void useMonoscpacedText() {
        textPanel.useMonoscpacedText();
    }

    /** Legt die Größe der Schriftart fest. */
    public final void setFontSize(int fontSize) {
        textPanel.setFontSize(fontSize);
    }

    /** Vergrößert die Größe der Schriftart. */
    public final void biggerFont(int size) {
        textPanel.biggerFont(size);
    }

    /** Schaltet das Umbrechen der Zeilen ab. */
    public final void useNoWordWrap() {
        textPanel.useNoWordWrap();
    }

    /** Scrollt die Scrollbar zum Ende des angezeigten Textes. Dies wird automatisch aufgerufen. */
    public final void scrollScrollbarToMaximumLater() {
        textPanel.scrollScrollbarToMaximumLater();
    }

    /** Scrollt die Scrollbar zum Anfang des angezeigten Textes. */
    public final void scrollScrollbarToMinimumLater() {
        textPanel.scrollScrollbarToMinimumLater();
    }

    /** Zeigt den übergebenen Text an. */
    public final void setText(String text) {
        textPanel.setText(text);
    }

    /** Erstellt die Dialog-Gui. */
    @Override
    protected final void populateDialog() {
        add(textPanel.getComponent(), BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);
    }

    protected final String getText() {
        return textPanel.getText();
    }

    /** Setzt den angezeigten Text auf dem Button zum OK oder Bearbeiten. */
    public final void setOkButtonText(String buttonText) {
        okButton.setText(buttonText);
    }

    /** Erstellt Tastenkombinationen. */
    private void setKeyBindings() {
        //setKeyBindingHome(() -> textComponent.scrollScrollbarToMinimum());
        //setKeyBindingEnd(() -> textComponent.scrollScrollbarToMaximum());
        setKeyBindingCtrlHome(() -> textPanel.scrollScrollbarToMinimumLater());
        setKeyBindingCtrlEnd(() -> textPanel.scrollScrollbarToMaximumLater());
        setKeyBindingPageUp(() -> textPanel.scrollScrollbarToPreviousSectionLater());
        setKeyBindingPageDown(() -> textPanel.scrollScrollbarToNextSectionLater());
    }

    /** Setzt die Anzahl Zeilen des Textfeldes. */
    public void setRows(int numberOfRows) {
        textPanel.setRows(numberOfRows);
    }

    /** Setzt die Anzahl Spalten des Textfeldes. */
    public void setColumns(int numberOfColumns) {
        textPanel.setColumns(numberOfColumns);
    }

    /** Gibt an, ob der Dialog mit OK beendet wurde. */
    public boolean isApplied() {
        return applied;
    }

}
