package de.renew.layoutwindow;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.net.URL;
import java.text.NumberFormat;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.TitledBorder;
import javax.swing.text.NumberFormatter;

import bibliothek.gui.dock.common.DefaultSingleCDockable;

import de.renew.draw.ui.api.CommandApi;
import de.renew.draw.ui.ontology.Alignment;
import de.renew.draw.ui.ontology.SpreadMode;
import de.renew.windowmanagement.Workbench;
import de.renew.windowmanagement.WorkbenchImpl;


/**
 * This window can be used to align, spread, group and ungroup figures. It
 * basically provides a window as alternative to the menu commands, but adds a
 * simple feature for aligning figures. One can select the anchor figure for the
 * alignment. One can choose between "Last selected", "First selected",
 * "Biggest object", "Smallest object", "Selection". The group/ungroup commands
 * are the default commands from the "Edit"-menu and not the NetComponents
 * commands. This window shall help with the positioning of many figures.
 *
 * @author 6hauster
 */
public class LayoutWindow extends JPanel {
    private final static String IMAGES = "/de/renew/layoutwindow/images/";
    private static DefaultSingleCDockable _dockable;

    /**
     * Creates a new instance of LayoutWindow.
     */
    public LayoutWindow() {
        super();
    }

    /**
     * Initializes the layout of this panel by adding subpanels for alignment,
     * distribution, positioning/dimensions, and grouping/ungrouping.
     * Sets maximum size constraints to ensure proper layout behavior.
     */
    public void init() {
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        Component alignPanel = createAlignPanel();
        alignPanel.setMaximumSize(
            new Dimension(Integer.MAX_VALUE, (int) alignPanel.getMinimumSize().getHeight()));
        add(alignPanel);
        Component distributePanel = createDistributePanel();
        distributePanel.setMaximumSize(
            new Dimension(Integer.MAX_VALUE, (int) distributePanel.getMinimumSize().getHeight()));
        add(distributePanel);
        Component positionDimensionsPanel = createPositionDimensionsPanel();
        positionDimensionsPanel.setMaximumSize(
            new Dimension(
                Integer.MAX_VALUE, (int) positionDimensionsPanel.getMinimumSize().getHeight()));
        add(positionDimensionsPanel);
        Component groupUngroup = createGroupUngroup();
        groupUngroup.setMaximumSize(
            new Dimension(Integer.MAX_VALUE, (int) groupUngroup.getMinimumSize().getHeight()));
        add(groupUngroup);
    }

    private JButton createButton(String label, String relativeIconPath) {
        JButton button;
        String iconPath = IMAGES + relativeIconPath;
        URL o = getClass().getResource(iconPath);
        if (o != null) {
            ImageIcon icon = new ImageIcon(o);
            button = new JButton(label, icon);
        } else {
            button = new JButton(label);
        }
        return button;
    }

    private Component createAlignPanel() {
        JPanel alignPanel = new JPanel(new BorderLayout());
        TitledBorder alignBorder = BorderFactory.createTitledBorder("Align");
        alignPanel.setBorder(alignBorder);

        JPanel relativePanel = new JPanel();
        relativePanel.setLayout(new BoxLayout(relativePanel, BoxLayout.LINE_AXIS));
        relativePanel.add(new JLabel("Relative to:"));

        String[] listElements = new String[] {
            "Last selected", "First selected", "Biggest object", "Smallest object", "Selection" };
        JComboBox<String> jComboBox = new JComboBox<>(listElements);
        relativePanel.add(jComboBox);

        alignPanel.add(relativePanel, BorderLayout.NORTH);
        JPanel alignPanelButtons = new JPanel(new GridLayout(2, 5));
        alignPanel.add(alignPanelButtons, BorderLayout.CENTER);

        JButton button;

        button = createButton("Lefts", "align/lefts.gif");
        button
            .addActionListener(new AlignCommandActionListener("LEFTS", Alignment.LEFTS, jComboBox));
        alignPanelButtons.add(button);

        button = createButton("Centers", "align/centers.gif");
        button.addActionListener(
            new AlignCommandActionListener("CENTERS", Alignment.CENTERS, jComboBox));
        alignPanelButtons.add(button);

        button = createButton("Rights", "align/rights.gif");
        button.addActionListener(
            new AlignCommandActionListener("RIGHTS", Alignment.RIGHTS, jComboBox));
        alignPanelButtons.add(button);

        button = createButton("Tops", "align/tops.gif");
        button.addActionListener(new AlignCommandActionListener("TOPS", Alignment.TOPS, jComboBox));
        alignPanelButtons.add(button);

        button = createButton("Middles", "align/middles.gif");
        button.addActionListener(
            new AlignCommandActionListener("MIDDLES", Alignment.MIDDLES, jComboBox));
        alignPanelButtons.add(button);

        button = createButton("Bottoms", "align/bottoms.gif");
        button.addActionListener(
            new AlignCommandActionListener("BOTTOMS", Alignment.BOTTOMS, jComboBox));
        alignPanelButtons.add(button);

        return alignPanel;
    }

    private Component createDistributePanel() {
        JPanel distributePanel = new JPanel();
        distributePanel.setLayout(new BoxLayout(distributePanel, BoxLayout.PAGE_AXIS));
        TitledBorder distributeBorder = BorderFactory.createTitledBorder("Spread");
        distributePanel.setBorder(distributeBorder);

        JPanel horizontal = new JPanel(new GridLayout(0, 3));
        distributePanel.add(horizontal);
        JPanel vertical = new JPanel(new GridLayout(0, 3));
        distributePanel.add(vertical);
        JPanel diagonal = new JPanel(new GridLayout(0, 3));
        distributePanel.add(diagonal);

        JButton button;

        // horizontal
        button = createButton("Lefts", "spread/lefts.gif");
        button.addActionListener(
            new CommandActionListener(CommandApi.createSpreadCommand("LEFTS", SpreadMode.LEFTS)));
        horizontal.add(button);


        button = createButton("Centers", "spread/centers.gif");
        button.addActionListener(
            new CommandActionListener(
                CommandApi.createSpreadCommand("CENTERS", SpreadMode.CENTERS)));

        horizontal.add(button);

        button = createButton("Rights", "spread/rights.gif");
        button.addActionListener(
            new CommandActionListener(CommandApi.createSpreadCommand("RIGHTS", SpreadMode.RIGHTS)));
        horizontal.add(button);

        button = createButton("Distances", "spread/distances-lr.gif");
        button.addActionListener(
            new CommandActionListener(
                CommandApi.createSpreadCommand("DISTANCES", SpreadMode.HORIZONTAL_DISTANCE)));
        horizontal.add(button);

        // vertical
        button = createButton("Tops", "spread/tops.gif");
        button.addActionListener(
            new CommandActionListener(CommandApi.createSpreadCommand("TOPS", SpreadMode.TOPS)));
        vertical.add(button);

        button = createButton("Middles", "spread/middles.gif");
        button.addActionListener(
            new CommandActionListener(
                CommandApi.createSpreadCommand("MIDDLES", SpreadMode.MIDDLES)));
        vertical.add(button);

        button = createButton("Bottoms", "spread/bottoms.gif");
        button.addActionListener(
            new CommandActionListener(
                CommandApi.createSpreadCommand("BOTTOMS", SpreadMode.BOTTOMS)));
        vertical.add(button);

        button = createButton("Distances", "spread/distances-tb.gif");
        button.addActionListener(
            new CommandActionListener(
                CommandApi.createSpreadCommand("DISTANCES", SpreadMode.VERTICAL_DISTANCE)));
        vertical.add(button);

        // diagonal
        button = createButton("Diagonal", "spread/diagonal.gif");
        button.addActionListener(
            new CommandActionListener(
                CommandApi.createSpreadCommand("DIAGONAL", SpreadMode.DIAGONAL_CENTERS)));
        diagonal.add(button);

        return distributePanel;
    }

    private Component createPositionDimensionsPanel() {
        JPanel positionDimensionsPanel = new JPanel();
        positionDimensionsPanel.setLayout(new BoxLayout(positionDimensionsPanel, BoxLayout.X_AXIS));
        TitledBorder groupUngroupBorder = BorderFactory.createTitledBorder("Position/Dimensions");
        positionDimensionsPanel.setBorder(groupUngroupBorder);

        NumberFormat intFormat = NumberFormat.getIntegerInstance();
        intFormat.setGroupingUsed(false);
        NumberFormatter numberFormatter = new NumberFormatter(intFormat);

        JLabel xLabel = new JLabel("x", SwingConstants.RIGHT);
        JFormattedTextField xTextField = new JFormattedTextField(numberFormatter);

        positionDimensionsPanel.add(xLabel);
        positionDimensionsPanel.add(xTextField);

        JLabel yLabel = new JLabel("y", SwingConstants.RIGHT);
        JFormattedTextField yTextField = new JFormattedTextField(numberFormatter);
        positionDimensionsPanel.add(yLabel);
        positionDimensionsPanel.add(yTextField);

        JLabel widthLabel = new JLabel("width", SwingConstants.RIGHT);
        JFormattedTextField widthTextField = new JFormattedTextField(numberFormatter);
        positionDimensionsPanel.add(widthLabel);
        positionDimensionsPanel.add(widthTextField);

        JLabel heightLabel = new JLabel("height", SwingConstants.RIGHT);
        JFormattedTextField heightTextField = new JFormattedTextField(numberFormatter);
        positionDimensionsPanel.add(heightLabel);
        positionDimensionsPanel.add(heightTextField);
        new PositionDimensionsTracker(xTextField, yTextField, widthTextField, heightTextField);
        return positionDimensionsPanel;
    }

    private Component createGroupUngroup() {
        JPanel groupUngroupPanel = new JPanel(new GridLayout(1, 3));
        TitledBorder groupUngroupBorder = BorderFactory.createTitledBorder("Group/Ungroup");
        groupUngroupPanel.setBorder(groupUngroupBorder);

        JButton button;

        button = createButton("Group", "group/group.gif");
        button.addActionListener(new CommandActionListener(CommandApi.createGroupCommand("GROUP")));

        groupUngroupPanel.add(button);

        button = createButton("Ungroup", "group/ungroup.gif");
        button.addActionListener(
            new CommandActionListener(CommandApi.createUnGroupCommand("UNGROUP")));


        groupUngroupPanel.add(button);

        return groupUngroupPanel;
    }

    /**
     * Opens the layout window in the specified workbench.
     * If the layout window is already open, it is brought to the front.
     * Otherwise, a new dockable layout panel is created and added to the UI.
     *
     * @param workbench The workbench in which the layout window should appear.
     */
    public static void openLayoutWindow(Workbench workbench) {
        if (_dockable == null) {
            DefaultSingleCDockable layoutWindowDockable = new DefaultSingleCDockable("Layout");
            layoutWindowDockable.setTitleText("Layout");
            layoutWindowDockable.setCloseable(true);
            LayoutWindow layoutWindowPanel = new LayoutWindow();
            layoutWindowPanel.init();
            layoutWindowPanel.setVisible(true);
            layoutWindowDockable.add(layoutWindowPanel);
            workbench.addViewWindow(layoutWindowDockable, WorkbenchImpl.UPPER_RIGHT_GROUP);
            _dockable = layoutWindowDockable;
        }
        if (_dockable.isVisible()) {
            _dockable.toFront();
            return;
        }

        _dockable.setVisible(true);
    }
}
