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

/*
 * Copyright 2021 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.Dimension;
import java.awt.event.ActionListener;

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

import de.duehl.swing.ui.GuiTools;
import de.duehl.swing.ui.buttons.painted.FirstButton;
import de.duehl.swing.ui.buttons.painted.LastButton;
import de.duehl.swing.ui.buttons.painted.NextButton;
import de.duehl.swing.ui.buttons.painted.PreviousButton;
import de.duehl.swing.ui.layout.ExtendedFlowLayout;

/**
 * Diese Klasse stellt eine Navigation mit vier Schaltern dar, um zum ersten, zum vorigen, zum
 * nächsten und zum letzten Element zu gelangen.
 *
 * Der Benutzer muss nach der Objekterstellung noch fillNavigator() aufrufen!
 *
 * Lieber den ListNavigator benutzen!
 *
 * @version 1.02     2021-07-12
 * @author Christian Dühl
 */

public class NavigatorPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    protected static final Dimension DEFAULT_BUTTON_SIZE = new Dimension(30, 40);
    protected static final int HORIZONTAL_GAP = 5;
    protected static final int VERTICAL_GAP = 0;

    /** Die Größe der Schaltflächen zur Navigation. */
    protected final Dimension buttonSize;

    /** Der Schalter um zum ersten Listenelement zu navigieren. */
    private final JButton firstButton;

    /** Der Schalter um zum vorigen Listenelement zu navigieren. */
    private final JButton previousButton;

    /** Der Schalter um zum nächsten Listenelement zu navigieren. */
    private final JButton nextButton;

    /** Der Schalter um zum letzten Listenelement zu navigieren. */
    private final JButton lastButton;

    /** Konstruktor mit der Standard-Buttongröße. */
    public NavigatorPanel() {
        this(DEFAULT_BUTTON_SIZE);
    }

    /** Konstruktor mit individueller Buttongröße. */
    public NavigatorPanel(Dimension buttonSize) {
        this.buttonSize = buttonSize;

        setLayoutAndPreferredSize();

        firstButton = new FirstButton();
        previousButton = new PreviousButton();
        nextButton = new NextButton();
        lastButton = new LastButton();
    }

    private void setLayoutAndPreferredSize() {
        //setLayout(new GridLayout(1, 0, 3, 3));
        setLayout(new ExtendedFlowLayout(ExtendedFlowLayout.CENTER, HORIZONTAL_GAP, VERTICAL_GAP));
        setPreferredSize(calculatePreferredSize());
    }

    private Dimension calculatePreferredSize() {
        int width = calculatePreferredWidth();
        int height = calculatePreferredHeight();

        return new Dimension(width, height);
    }

    protected int calculatePreferredWidth() {
        int numberOfHorizontalElements = 4;
        int elementWidth = buttonSize.width;
        int width = numberOfHorizontalElements * elementWidth
                + (numberOfHorizontalElements + 1) * HORIZONTAL_GAP;
                // + 1, falls das auch links und rechts angefügt wird, sonst -1
                // mit -1 ist es zu kurz, daher wird es wohl auch außen eingefügt.

        width += elementWidth; // reichte in manchen Anwendungen sonst nicht
                               // SelectionVerificationDialog

        return width;
    }

    protected int calculatePreferredHeight() {
        int numberOfVerticalElements = 1;
        int elementHeight = buttonSize.height;
        int height = numberOfVerticalElements * elementHeight
                + (numberOfVerticalElements + 1) * VERTICAL_GAP;
                // + 1, falls das auch oben und unten angefügt wird, sonst -1

        return height;
    }

    /** Initialisiert die Anzeigeelemente im Navigator. */
    public final void fillNavigator() {
        addElements();
        initElelents();
    }

    protected void addElements() {
        addLeftNavigationElements();
        addRightNavigationElements();
    }

    protected final void addLeftNavigationElements() {
        add(firstButton);
        add(previousButton);
    }

    protected final void addRightNavigationElements() {
        add(nextButton);
        add(lastButton);
    }

    protected void initElelents() {
        setButtonDimensions();
        setButtonToolTips();
    }

    private void setButtonDimensions() {
        firstButton.setPreferredSize(buttonSize);
        previousButton.setPreferredSize(buttonSize);
        nextButton.setPreferredSize(buttonSize);
        lastButton.setPreferredSize(buttonSize);
    }

    private void setButtonToolTips() {
        firstButton.setToolTipText("Zeige ersten Datensatz an.");
        previousButton.setToolTipText("Zeige vorigen Datensatz an.");
        nextButton.setToolTipText("Zeige nächsten Datensatz an.");
        lastButton.setToolTipText("Zeige letzten Datensatz an.");
    }

    public void addFirstActionListener(ActionListener actionListener) {
        firstButton.addActionListener(actionListener);
    }

    public void addPreviousActionListener(ActionListener actionListener) {
        previousButton.addActionListener(actionListener);
    }

    public void addNextActionListener(ActionListener actionListener) {
        nextButton.addActionListener(actionListener);
    }

    public void addLastActionListener(ActionListener actionListener) {
        lastButton.addActionListener(actionListener);
    }

    /** Weist dem Button, der das erste Element anzeigt, einen Tooltip zu. */
    public void setFirstToolTip(String toolTip) {
        firstButton.setToolTipText(toolTip);
    }

    /** Weist dem Button, der das vorige Element anzeigt, einen Tooltip zu. */
    public void setPreviousToolTip(String toolTip) {
        previousButton.setToolTipText(toolTip);
    }

    /** Weist dem Button, der das nächste Element anzeigt, einen Tooltip zu. */
    public void setNextToolTip(String toolTip) {
        nextButton.setToolTipText(toolTip);
    }

    /** Weist dem Button, der das letzte Element anzeigt, einen Tooltip zu. */
    public void setLastToolTip(String toolTip) {
        lastButton.setToolTipText(toolTip);
    }

    public JPanel centerHorizontal() {
        return GuiTools.centerHorizontal(this);
    }

    public JPanel centerVertical() {
        return GuiTools.centerVertical(this);
    }

    public JPanel center() {
        return GuiTools.center(this);
    }

    /** Drückt den Button, der das erste Element anzeigt. */
    public void doClickOnFirstButton() {
        firstButton.doClick();
    }

    /** Drückt den Button, der das vorige Element anzeigt. */
    public void doClickOnPreviousButton() {
        previousButton.doClick();
    }

    /** Drückt den Button, der das nächste Element anzeigt. */
    public void doClickOnNextButton() {
        nextButton.doClick();
    }

    /** Drückt den Button, der das letzte Element anzeigt. */
    public void doClickOnLastButton() {
        lastButton.doClick();
    }

}
