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

/*
 * Copyright 2024 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.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.util.HashMap;
import java.util.Map;

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

import de.duehl.swing.ui.GuiTools;
import de.duehl.swing.ui.elements.sidelist.data.ButtonAndComponent;
import de.duehl.swing.ui.layout.VerticalLayout;

/**
 * Diese Klasse stellt ein Organisationselement mit einer Seitenliste und zugehörigen
 * Anzeigelementen dar.
 *
 * @version 1.01     2024-07-30
 * @author Christian Dühl
 */

public class SideListOrganiserPanel {

    private static final Color ACTIVE_COLOR = new Color(0, 0, 255);
    private static final Color INACTIVE_COLOR = new Color(80, 80, 80);

    /**
     * Das Verzeichnis der Schalter (links) und der Anzeigeelemente (rechts) nach den Texten der
     * Liste (links).
     */
    private final Map<String, ButtonAndComponent> buttonAndComponentByListText;

    /** Der Text des zuerst hinzugefügten Elements. */
    private String firstElementText;

    /** Der Panel mit dem Listenbereich links und den zugehörigen Anzeigelementen rechts. */
    private final JPanel mainPanel;

    /** Der Panel mit den anklickbaren Einträgen links. */
    private final JPanel listPanel;

    /** Der Panel mit den zugehörigen anzuzeigenden Inhalten rechts. */
    private final JPanel contentPanel;

    /** Konstruktor. */
    public SideListOrganiserPanel() {
        mainPanel = new JPanel();
        listPanel = new JPanel();
        contentPanel = new JPanel();

        buttonAndComponentByListText = new HashMap<>();
        firstElementText = "";

        initElements();
    }

    private void initElements() {
        initListPanel();
        initContentPanel();
        initMainPanel();
    }

    private void initListPanel() {
        listPanel.setLayout(new VerticalLayout(5, VerticalLayout.BOTH, VerticalLayout.TOP));
        setListPanelWidth(200);
        GuiTools.createTitle(listPanel);
    }

    private void initContentPanel() {
        contentPanel.setLayout(new BorderLayout());
        GuiTools.createTitle(contentPanel);
    }

    private void initMainPanel() {
        mainPanel.setLayout(new BorderLayout());

        mainPanel.add(listPanel, BorderLayout.WEST);
        mainPanel.add(GuiTools.createScrollPane(contentPanel), BorderLayout.CENTER);
    }

    /** Legt die Breite des linken Elements mit den Buttons fest. */
    public void setListPanelWidth(int width) {
        listPanel.setPreferredSize(new Dimension(width, 100));
    }

    /**
     * Fügt einen Eintrag in die Liste samt zugehörigem Anzeigelement hinzu.
     *
     * @param text
     *            Der Text der links in der Liste angezeigt wird.
     * @param component
     *            Das zugehörige Anzeigelement.
     */
    public void addElement(String text, Component component) {
        if (buttonAndComponentByListText.containsKey(text)) {
            throw new IllegalArgumentException("Es ist bereits ein Element mit dem übergebenen "
                    + "Text '" + text + "' vorhanden.");
        }

        if (firstElementText.isEmpty()) {
            firstElementText = text;
        }

        JButton button = createListEntryButton(text);
        ButtonAndComponent buttonAndComponent = new ButtonAndComponent(component, button);
        buttonAndComponentByListText.put(text, buttonAndComponent);
        listPanel.add(button);
    }

    private JButton createListEntryButton(String text) {
        JButton button = new JButton(text);
        GuiTools.biggerFont(button, 5);
        button.addActionListener(e -> buttonPressed(text));
        return button;
    }

    private void buttonPressed(String text) {
        ButtonAndComponent buttonAndComponent = buttonAndComponentByListText.get(text);
        Component component = buttonAndComponent.getComponent();
        contentPanel.removeAll();
        contentPanel.add(component, BorderLayout.CENTER);
        changeTextColors(text);

        mainPanel.repaint();
        mainPanel.revalidate();
        mainPanel.invalidate();
    }

    private void changeTextColors(String text) {
        for (String buttonText : buttonAndComponentByListText.keySet()) {
            Color color;
            if (text.equals(buttonText)) {
                color = ACTIVE_COLOR;
            }
            else {
                color = INACTIVE_COLOR;
            }
            ButtonAndComponent buttonAndComponent = buttonAndComponentByListText.get(buttonText);
            JButton button = buttonAndComponent.getButton();
            button.setForeground(color);
        }
    }

    /** Zeigt den Inhalt zum gewünschten Text an. */
    public void showContent(String text) {
        if (!buttonAndComponentByListText.containsKey(text)) {
            throw new IllegalArgumentException("Unbekannter Text '" + text + "'.");
        }
        buttonPressed(text);
    }

    /** Zeigt den Inhalt des zuerst hinzugefügten Textes an. */
    public void showFirstAddedContent() {
        showContent(firstElementText);
    }

    /**
     * Getter für den Panel mit dem Listenbereich links und den zugehörigen Anzeigelementen rechts.
     */
    public JPanel getPanel() {
        return mainPanel;
    }

}
