package de.duehl.swing.ui.elements.fontsize;

/*
 * Copyright 2017 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.GridLayout;

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

import de.duehl.basics.collections.CollectionsHelper;
import de.duehl.basics.text.NumberString;
import de.duehl.swing.ui.GuiTools;
import de.duehl.swing.ui.buttons.painted.MinusButton;
import de.duehl.swing.ui.buttons.painted.PlusButton;
import de.duehl.swing.ui.elements.box.ObservableComboBox;

/**
 * Diese Klasse stellt die Auswahl und Anzeige der Schriftgröße zur Verfügung.
 *
 * @version 1.01     2017-11-17
 * @author Christian Dühl
 */

public class FontSizeSelection {

    private static final Dimension BUTTON_DIMENSION = new Dimension(20, 20);

    private static boolean WITH_LABEL = false;

    private final FontSizeInteraction fontSizeInteraction;

    private final JLabel fontSizeLabel;
    private final ObservableComboBox<String> fontSizeBox;
    private final JPanel panel;

    /**
     * Konstruktor.
     *
     * @param fontSizeInteraction
     *            Objekt, das mit der ausgewählten Schriftgröße interagiert.
     */
    public FontSizeSelection(FontSizeInteraction fontSizeInteraction) {
        this.fontSizeInteraction = fontSizeInteraction;

        panel = new JPanel();
        fontSizeLabel = new JLabel();
        fontSizeBox = new ObservableComboBox<>();
        initFontSizeComboBox();

        populatePanel();
    }

    private void initFontSizeComboBox() {
        fontSizeBox.setEditable(true);
        fontSizeBox.addBoxSelectionChangeObserver(s -> boxSelectionChanged(s));
        fontSizeBox.setValues(CollectionsHelper.buildListFrom("8", "9", "10", "11", "12", "13",
                "14", "15", "16", "17", "18", "20", "24", "32", "38", "44"));
        fontSizeBox.showValue(Integer.toString(getActualFontSize()));
        fontSizeBox.setPreferredSize(new Dimension(50, 25));
    }

    private void boxSelectionChanged(String selected) {
        if (NumberString.isDigitSequence(selected)) {
            int fontSize = NumberString.parseIntIgnore(selected, getActualFontSize());
            fontSizeInteraction.setFontSize(fontSize);
        }
    }

    private int getActualFontSize() {
        return fontSizeInteraction.getFontSize();
    }

    private void populatePanel() {
        panel.setLayout(new BorderLayout());

        if (WITH_LABEL) {
            panel.add(createFontSizePanelWithLabel(), BorderLayout.WEST);
            panel.add(fontSizeBox.getBox(), BorderLayout.CENTER);
        }
        else {
            panel.add(createFontSizePanelWithFontSizeBox(), BorderLayout.WEST);
        }
    }

    private Component createFontSizePanelWithLabel() {
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(1, 0, 2, 2));

        panel.add(createPlusFontSizeButton());
        panel.add(createFontSizeLabel());
        panel.add(createMinusFontSizeButton());

        return panel;
    }

    private Component createFontSizePanelWithFontSizeBox() {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        panel.add(createPlusFontSizeButton(), BorderLayout.WEST);
        panel.add(fontSizeBox.getBox(), BorderLayout.CENTER);
        panel.add(createMinusFontSizeButton(), BorderLayout.EAST);

        return panel;
    }

    private Component createPlusFontSizeButton() {
        JButton button = new PlusButton();
        button.setPreferredSize(BUTTON_DIMENSION);
        button.addActionListener(e -> incrementFontSize());
        return button;
    }

    private void incrementFontSize() {
        fontSizeInteraction.incrementFontSize();
        refreshFontSize();
    }

    private Component createFontSizeLabel() {
        GuiTools.biggerFont(fontSizeLabel, 3);
        refreshFontSize();
        return fontSizeLabel;
    }

    /** Erneuert die Anzeige der Schriftgröße aufgrund der im Editor hinterlegten Schriftgröße. */
    public void refreshFontSize() {
        String fontSize = Integer.toString(getActualFontSize());
        fontSizeLabel.setText(fontSize);
        fontSizeBox.showValue(fontSize);
        fontSizeBox.validate();
    }

    private Component createMinusFontSizeButton() {
        JButton button = new MinusButton();
        button.setPreferredSize(BUTTON_DIMENSION);
        button.addActionListener(e -> decrementFontSize());
        return button;
    }

    private void decrementFontSize() {
        fontSizeInteraction.decrementFontSize();
        refreshFontSize();
    }

    /** Erzeugt einen Rahmen um die Komponente der Schriftgrößen-Auswahl. */
    public void createBorder() {
        GuiTools.createTitle(panel);
    }

    /** Gibt die Komponente der Schriftgrößen-Auswahl zurück, um sie in die Gui einzufügen. */
    public Component getComponent() {
        return panel;
    }

}
