/*
 * @(#)PaletteLayout.java 5.1
 *
 */

package CH.ifa.draw.util;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;


/**
 * A custom layout manager for the palette.
 * {@link CH.ifa.draw.standard.ToolButton}
 */
public class PaletteLayout implements LayoutManager {
    private final int _gap;
    private final Point _border;
    private boolean _verticalLayout;

    /**
     * Initializes the palette layout.
     * @param gap the gap between palette entries.
     */
    public PaletteLayout(int gap) {
        this(gap, new Point(0, 0), true);
    }

    /**
     * Constructs a new vertical PaletteLayout with a custom gap and custom padding.
     *
     * @param gap the gap between palette entries
     * @param border a Point where <code>border.x</code> represents the space between the
     *               horizontal borders of the Palette and its components, <code>border.y</code>
     *               for the vertical borders
     */
    public PaletteLayout(int gap, Point border) {
        this(gap, border, true);
    }

    /**
     * Constructs a new PaletteLayout with a custom gap and padding
     * and the option making the palette horizontal.
     *
     * @param gap the gap between palette entries
     * @param border a Point where <code>border.x</code> represents the space between the
     *               horizontal borders of the Palette and its components, <code>border.y</code>
     *               for the vertical borders
     * @param vertical <code>true</code> if palette is vertical
     */
    public PaletteLayout(int gap, Point border, boolean vertical) {
        _gap = gap;
        _border = border;
        _verticalLayout = vertical;
    }

    /**
     * Sets the palette layout to vertical.
     *
     * @param vertical <code>true</code> to set palette vertical
     */
    public void setVertical(boolean vertical) {
        _verticalLayout = vertical;
    }

    /**
     * Gets a boolean to indicate whether palette is vertical.
     *
     * @return <code>true</code> if palette is vertical
     */
    public boolean isVertical() {
        return _verticalLayout;
    }

    @Override
    public void addLayoutComponent(String name, Component comp) {}

    @Override
    public void removeLayoutComponent(Component comp) {}

    @Override
    public Dimension preferredLayoutSize(Container target) {
        return minimumLayoutSize(target);
    }

    @Override
    public Dimension minimumLayoutSize(Container target) {
        synchronized (target.getTreeLock()) {
            Dimension dim = new Dimension(0, 0);
            int nmembers = target.getComponentCount();

            for (int i = 0; i < nmembers; i++) {
                Component m = target.getComponent(i);
                if (m.isVisible()) {
                    Dimension d = m.getMinimumSize();
                    if (_verticalLayout) {
                        dim.width = Math.max(dim.width, d.width);
                        if (i > 0) {
                            dim.height += _gap;
                        }
                        dim.height += d.height;
                    } else {
                        dim.height = Math.max(dim.height, d.height);
                        if (i > 0) {
                            dim.width += _gap;
                        }
                        dim.width += d.width;
                    }
                }
            }

            Insets insets = target.getInsets();
            dim.width += insets.left + insets.right;
            dim.width += 2 * _border.x;
            dim.height += insets.top + insets.bottom;
            dim.height += 2 * _border.y;
            return dim;
        }
    }

    @Override
    public void layoutContainer(Container target) {
        synchronized (target.getTreeLock()) {
            Insets insets = target.getInsets();
            int nmembers = target.getComponentCount();
            int x = insets.left + _border.x;
            int y = insets.top + _border.y;

            for (int i = 0; i < nmembers; i++) {
                Component m = target.getComponent(i);
                if (m.isVisible()) {
                    Dimension d = m.getMinimumSize();
                    m.setBounds(x, y, d.width, d.height);
                    if (_verticalLayout) {
                        y += d.height;
                        y += _gap;
                    } else {
                        x += d.width;
                        x += _gap;
                    }
                }
            }
        }
    }
}