/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jface.action;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.jface.util.Assert;
import org.eclipse.jface.util.Policy;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

/**
 * The <code>ToolBarContributionItem</code> class provides a wrapper for tool
 * bar managers when used in cool bar managers. It extends <code>ContributionItem</code>
 * but and provides some additional methods to customize the size of the cool
 * item and to retrieve the underlying tool bar manager.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 * 
 * @since 3.0
 */
public class ToolBarContributionItem extends ContributionItem {

    /**
     * A constant used by <code>setMinimumItemsToShow</code> and <code>getMinimumItemsToShow</code>
     * to indicate that all tool items should be shown in the cool item.
     */
    public static final int SHOW_ALL_ITEMS = -1;

    /**
     * The pull down menu used to list all hidden tool items if the current
     * size is less than the preffered size.
     */
    private MenuManager chevronMenuManager = null;

    /**
     * The widget created for this item; <code>null</code> before creation
     * and after disposal.
     */
    private CoolItem coolItem = null;

    /**
     * Current height of cool item
     */
    private int currentHeight = -1;

    /**
     * Current width of cool item.
     */
    private int currentWidth = -1;

    /**
     * A flag indicating that this item has been disposed. This prevents future
     * method invocations from doing things they shouldn't.
     */
    private boolean disposed = false;

    /**
     * Mininum number of tool items to show in the cool item widget.
     */
    private int minimumItemsToShow = SHOW_ALL_ITEMS;

    /**
     * The tool bar manager used to manage the tool items contained in the cool
     * item widget.
     */
    private ToolBarManager toolBarManager = null;

    /**
     * Enable/disable chevron support.
     */
    private boolean useChevron = true;

    /**
     * Convenience method equivalent to <code>ToolBarContributionItem(new ToolBarManager(), null)</code>.
     */
    public ToolBarContributionItem() {
        this(new ToolBarManager(), null);
    }

    /**
     * Convenience method equivalent to <code>ToolBarContributionItem(toolBarManager, null)</code>.
     * 
     * @param toolBarManager
     *            the tool bar manager
     */
    public ToolBarContributionItem(IToolBarManager toolBarManager) {
        this(toolBarManager, null);
    }

    /**
     * Creates a tool bar contribution item.
     * 
     * @param toolBarManager
     *            the tool bar manager to wrap
     * @param id
     *            the contribution item id, or <code>null</code> if none
     */
    public ToolBarContributionItem(IToolBarManager toolBarManager, String id) {
        super(id);
        Assert.isTrue(toolBarManager instanceof ToolBarManager);
        this.toolBarManager = (ToolBarManager) toolBarManager;
    }

    /**
     * Checks whether this contribution item has been disposed. If it has, and
     * the tracing options are active, then it prints some debugging
     * information.
     * 
     * @return <code>true</code> if the item is disposed; <code>false</code>
     *         otherwise.
     *  
     */
    private final boolean checkDisposed() {
        if (disposed) {
            if (Policy.TRACE_TOOLBAR) {
                System.out
                        .println("Method invocation on a disposed tool bar contribution item."); //$NON-NLS-1$
                new Exception().printStackTrace(System.out);
            }

            return true;
        }

        return false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IContributionItem#dispose()
     */
    public void dispose() {
        // Dispose of the ToolBar and all its contributions
        if (toolBarManager != null) {
            toolBarManager.dispose();
            toolBarManager = null;
        }

        /*
         * We need to dispose the cool item or we might be left holding a cool
         * item with a disposed control.
         */
        if ((coolItem != null) && (!coolItem.isDisposed())) {
            coolItem.dispose();
            coolItem = null;
        }

        // Mark this item as disposed.
        disposed = true;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IContributionItem#fill(org.eclipse.swt.widgets.CoolBar,
     *      int)
     */
    public void fill(CoolBar coolBar, int index) {
        if (checkDisposed()) {
            return;
        }

        if (coolItem == null && coolBar != null) {
            ToolBar oldToolBar = toolBarManager.getControl();
            ToolBar toolBar = toolBarManager.createControl(coolBar);
            if ((oldToolBar != null) && (oldToolBar.equals(toolBar))) {
                // We are using an old tool bar, so we need to update.
                toolBarManager.update(true);
            }

            // Do not create a coolItem if the toolbar is empty
            if (toolBar.getItemCount() < 1)
                return;
            int flags = SWT.DROP_DOWN;
            if (index >= 0) {
                coolItem = new CoolItem(coolBar, flags, index);
            } else {
                coolItem = new CoolItem(coolBar, flags);
            }
            // sets the back reference
            coolItem.setData(this);
            // Add the toolbar to the CoolItem widget
            coolItem.setControl(toolBar);

            // Handle Context Menu
            // ToolBarManager.createControl can actually return a pre-existing control.
            // Only add the listener if the toolbar was newly created (bug 62097).
            if (oldToolBar != toolBar) {
	            toolBar.addListener(SWT.MenuDetect, new Listener() {
	
	                public void handleEvent(Event event) {
	                    // if the toolbar does not have its own context menu then
	                    // handle the event
	                    if (toolBarManager.getContextMenuManager() == null) {
	                        handleContextMenu(event);
	                    }
	                }
	            });
            }

            // Handle for chevron clicking
            if (getUseChevron()) {
                // Chevron Support
                coolItem.addSelectionListener(new SelectionAdapter() {

                    public void widgetSelected(SelectionEvent event) {
                        if (event.detail == SWT.ARROW) {
                            handleChevron(event);
                        }
                    }
                });
            }

            // Handle for disposal
            coolItem.addDisposeListener(new DisposeListener() {

                public void widgetDisposed(DisposeEvent event) {
                    handleWidgetDispose(event);
                }
            });

            // Sets the size of the coolItem
            updateSize(true);
        }
    }

    /**
     * Returns a consistent set of wrap indices. The return value will always
     * include at least one entry and the first entry will always be zero.
     * CoolBar.getWrapIndices() is inconsistent in whether or not it returns an
     * index for the first row.
     */
    private int[] getAdjustedWrapIndices(int[] wraps) {
        int[] adjustedWrapIndices;
        if (wraps.length == 0) {
            adjustedWrapIndices = new int[] { 0 };
        } else {
            if (wraps[0] != 0) {
                adjustedWrapIndices = new int[wraps.length + 1];
                adjustedWrapIndices[0] = 0;
                for (int i = 0; i < wraps.length; i++) {
                    adjustedWrapIndices[i + 1] = wraps[i];
                }
            } else {
                adjustedWrapIndices = wraps;
            }
        }
        return adjustedWrapIndices;
    }

    /**
     * Returns the current height of the corresponding cool item.
     * 
     * @return the current height
     */
    public int getCurrentHeight() {
        if (checkDisposed()) {
            return -1;
        }
        return currentHeight;
    }

    /**
     * Returns the current width of the corresponding cool item.
     * 
     * @return the current size
     */
    public int getCurrentWidth() {
        if (checkDisposed()) {
            return -1;
        }
        return currentWidth;
    }

    /**
     * Returns the minimum number of tool items to show in the cool item.
     * 
     * @return the minimum number of tool items to show, or <code>SHOW_ALL_ITEMS</code>
     *         if a value was not set
     * @see #setMinimumItemsToShow(int)
     */
    public int getMinimumItemsToShow() {
        if (checkDisposed()) {
            return -1;
        }
        return minimumItemsToShow;
    }

    /**
     * Returns the internal tool bar manager of the contribution item.
     * 
     * @return the tool bar manager, or <code>null</code> if one is not
     *         defined.
     * @see IToolBarManager
     */
    public IToolBarManager getToolBarManager() {
        if (checkDisposed()) {
            return null;
        }
        return toolBarManager;
    }

    /**
     * Returns whether chevron support is enabled.
     * 
     * @return <code>true</code> if chevron support is enabled, <code>false</code>
     *         otherwise
     */
    public boolean getUseChevron() {
        if (checkDisposed()) {
            return false;
        }
        return useChevron;
    }

    /**
     * Create and display the chevron menu.
     */
    private void handleChevron(SelectionEvent event) {
        CoolItem item = (CoolItem) event.widget;
        Control control = item.getControl();
        if ((control instanceof ToolBar) == false) {
            return;
        }
        CoolBar coolBar = item.getParent();
        ToolBar toolBar = (ToolBar) control;
        Rectangle toolBarBounds = toolBar.getBounds();
        ToolItem[] items = toolBar.getItems();
        ArrayList hidden = new ArrayList();
        for (int i = 0; i < items.length; ++i) {
            Rectangle itemBounds = items[i].getBounds();
            if (!((itemBounds.x + itemBounds.width <= toolBarBounds.width) && (itemBounds.y
                    + itemBounds.height <= toolBarBounds.height))) {
                hidden.add(items[i]);
            }
        }

        // Create a pop-up menu with items for each of the hidden buttons.
        if (chevronMenuManager != null) {
            chevronMenuManager.dispose();
        }
        chevronMenuManager = new MenuManager();
        for (Iterator i = hidden.iterator(); i.hasNext();) {
            ToolItem toolItem = (ToolItem) i.next();
            IContributionItem data = (IContributionItem) toolItem.getData();
            if (data instanceof ActionContributionItem) {
                ActionContributionItem contribution = new ActionContributionItem(
                        ((ActionContributionItem) data).getAction());
                chevronMenuManager.add(contribution);
            } else if (data instanceof SubContributionItem) {
                IContributionItem innerData = ((SubContributionItem) data)
                        .getInnerItem();
                if (innerData instanceof ActionContributionItem) {
                    ActionContributionItem contribution = new ActionContributionItem(
                            ((ActionContributionItem) innerData).getAction());
                    chevronMenuManager.add(contribution);
                }
            } else if (data.isSeparator()) {
                chevronMenuManager.add(new Separator());
            }
        }
        Menu popup = chevronMenuManager.createContextMenu(coolBar);
        Point chevronPosition = coolBar.toDisplay(event.x, event.y);
        popup.setLocation(chevronPosition.x, chevronPosition.y);
        popup.setVisible(true);
    }

    /**
     * Handles the event when the toobar item does not have its own context
     * menu.
     * 
     * @param event
     *            the event object
     */
    private void handleContextMenu(Event event) {
        ToolBar toolBar = toolBarManager.getControl();
        // If parent has a menu then use that one
        Menu parentMenu = toolBar.getParent().getMenu();
        if ((parentMenu != null) && (!parentMenu.isDisposed())) {
            toolBar.setMenu(parentMenu);
            // Hook listener to remove menu once it has disapeared
            parentMenu.addListener(SWT.Hide, new Listener() {

                public void handleEvent(Event innerEvent) {
                    ToolBar innerToolBar = toolBarManager.getControl();
                    if (innerToolBar != null) {
                        innerToolBar.setMenu(null);
                        Menu innerParentMenu = innerToolBar.getParent()
                                .getMenu();
                        if (innerParentMenu != null) {
                            innerParentMenu.removeListener(SWT.Hide, this);
                        }
                    }
                }
            });
        }
    }

    /**
     * Handles the disposal of the widget.
     * 
     * @param event
     *            the event object
     */
    private void handleWidgetDispose(DisposeEvent event) {
        coolItem = null;
    }

    /**
     * A contribution item is visible iff its internal state is visible <em>or</em>
     * the tool bar manager contains something other than group markers and
     * separators.
     * 
     * @return <code>true</code> if the tool bar manager contains something
     *         other than group marks and separators, and the internal state is
     *         set to be visible.
     */
    public boolean isVisible() {
        if (checkDisposed()) {
            return false;
        }

        boolean visibleItem = false;
        if (toolBarManager != null) {
            IContributionItem[] contributionItems = toolBarManager.getItems();
            for (int i = 0; i < contributionItems.length; i++) {
                IContributionItem contributionItem = contributionItems[i];
                if ((!contributionItem.isGroupMarker())
                        && (!contributionItem.isSeparator())) {
                    visibleItem = true;
                    break;
                }
            }
        }

        return (visibleItem || super.isVisible());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IContributionItem#saveWidgetState()
     */
    public void saveWidgetState() {
        if (checkDisposed()) {
            return;
        }
        if (coolItem == null)
            return;

        //1. Save current size
        CoolBar coolBar = coolItem.getParent();
        boolean isLastOnRow = false;
        int lastIndex = coolBar.getItemCount() - 1;
        int coolItemIndex = coolBar.indexOf(coolItem);
        int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices());
        // Traverse through all wrap indicies backwards
        for (int row = wrapIndicies.length - 1; row >= 0; row--) {
            if (wrapIndicies[row] <= coolItemIndex) {

                int nextRow = row + 1;
                int nextRowStartIndex;
                if (nextRow > (wrapIndicies.length - 1)) {
                    nextRowStartIndex = lastIndex + 1;
                } else {
                    nextRowStartIndex = wrapIndicies[nextRow];
                }

                // Check to see if its the last item on the row
                if (coolItemIndex == (nextRowStartIndex - 1)) {
                    isLastOnRow = true;
                }
                break;
            }
        }

        // Save the preferred size as actual size for the last item on a row
        int nCurrentWidth;
        if (isLastOnRow) {
            nCurrentWidth = coolItem.getPreferredSize().x;
        } else {
            nCurrentWidth = coolItem.getSize().x;
        }
        setCurrentWidth(nCurrentWidth);
        setCurrentHeight(coolItem.getSize().y);
    }

    /**
     * Sets the current height of the cool item. Update(SIZE) should be called
     * to adjust the widget.
     * 
     * @param currentHeight
     *            the current height to set
     */
    public void setCurrentHeight(int currentHeight) {
        if (checkDisposed()) {
            return;
        }
        this.currentHeight = currentHeight;
    }

    /**
     * Sets the current width of the cool item. Update(SIZE) should be called
     * to adjust the widget.
     * 
     * @param currentWidth
     *            the current width to set
     */
    public void setCurrentWidth(int currentWidth) {
        if (checkDisposed()) {
            return;
        }
        this.currentWidth = currentWidth;
    }

    /**
     * Sets the minimum number of tool items to show in the cool item. If this
     * number is less than the total tool items, a chevron will appear and the
     * hidden tool items appear in a drop down menu. By default, all the tool
     * items are shown in the cool item.
     * 
     * @param minimumItemsToShow
     *            the minimum number of tool items to show.
     * @see #getMinimumItemsToShow()
     * @see #setUseChevron(boolean)
     */
    public void setMinimumItemsToShow(int minimumItemsToShow) {
        if (checkDisposed()) {
            return;
        }
        this.minimumItemsToShow = minimumItemsToShow;
    }

    /**
     * Enables or disables chevron support for the cool item. By default,
     * chevron support is enabled.
     * 
     * @param value
     *            <code>true</code> to enable chevron support, <code>false</code>
     *            otherwise.
     */
    public void setUseChevron(boolean value) {
        if (checkDisposed()) {
            return;
        }
        useChevron = value;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IContributionItem#update(java.lang.String)
     */
    public void update(String propertyName) {
        if (checkDisposed()) {
            return;
        }
        if (coolItem != null) {
            IToolBarManager manager = getToolBarManager();
            if (manager != null) {
                manager.update(true);
            }

            if ((propertyName == null)
                    || propertyName.equals(ICoolBarManager.SIZE)) {
                updateSize(true);
            }
        }
    }

    /**
     * Updates the cool items' preferred, minimum, and current size. The
     * preferred size is calculated based on the tool bar size and extra trim.
     * 
     * @param changeCurrentSize
     *            <code>true</code> if the current size should be changed to
     *            the preferred size, <code>false</code> to not change the
     *            current size
     */
    private void updateSize(boolean changeCurrentSize) {
        if (checkDisposed()) {
            return;
        }
        // cannot set size if coolItem is null
        if (coolItem == null || coolItem.isDisposed()) {
            return;
        }
        boolean locked = false;
        CoolBar coolBar = coolItem.getParent();
        try {
            // Fix odd behaviour with locked tool bars
            if (coolBar != null) {
                if (coolBar.getLocked()) {
                    coolBar.setLocked(false);
                    locked = true;
                }
            }
            ToolBar toolBar = (ToolBar) coolItem.getControl();
            if ((toolBar == null) || (toolBar.isDisposed())
                    || (toolBar.getItemCount() <= 0)) {
                // if the toolbar does not contain any items then dispose of
                // coolItem
                coolItem.setData(null);
                Control control = coolItem.getControl();
                if ((control != null) && !control.isDisposed()) {
                    control.dispose();
                    coolItem.setControl(null);
                }
                if (!coolItem.isDisposed()) {
                    coolItem.dispose();
                }
            } else {
                // If the toolbar item exists then adjust the size of the cool
                // item
                Point toolBarSize = toolBar.computeSize(SWT.DEFAULT,
                        SWT.DEFAULT);
                // Set the preffered size to the size of the toolbar plus trim
                Point preferredSize = coolItem.computeSize(toolBarSize.x,
                        toolBarSize.y);
                coolItem.setPreferredSize(preferredSize);
                // note setMinimumSize must be called before setSize, see PR
                // 15565
                // Set minimum size
                if (getMinimumItemsToShow() != SHOW_ALL_ITEMS) {
                    int toolItemWidth = toolBar.getItems()[0].getWidth();
                    int minimumWidth = toolItemWidth * getMinimumItemsToShow();
                    coolItem.setMinimumSize(minimumWidth, toolBarSize.y);
                } else {
                    coolItem.setMinimumSize(toolBarSize.x, toolBarSize.y);
                }
                if (changeCurrentSize) {
                    // Set current size to preferred size
                    coolItem.setSize(preferredSize);
                }
            }
        } finally {
            // If the cool bar was locked, then set it back to locked
            if ((locked) && (coolBar != null)) {
                coolBar.setLocked(true);
            }
        }
    }

}
