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

import java.util.ArrayList;

import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.util.Geometry;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
import org.eclipse.ui.internal.WorkbenchImages;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.ui.internal.dnd.DragUtil;
import org.eclipse.ui.internal.presentations.r21.R21Colors;
import org.eclipse.ui.internal.presentations.r21.R21PresentationMessages;
import org.eclipse.ui.internal.presentations.r21.widgets.CTabItem;
import org.eclipse.ui.internal.presentations.r21.widgets.R21PaneFolder;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.presentations.IPartMenu;
import org.eclipse.ui.presentations.IPresentablePart;
import org.eclipse.ui.presentations.IStackPresentationSite;
import org.eclipse.ui.presentations.PresentationUtil;
import org.eclipse.ui.presentations.StackDropResult;
import org.eclipse.ui.presentations.StackPresentation;

/**
 * Base class for StackPresentations that display IPresentableParts in a CTabFolder. 
 * 
 * @since 3.0
 */
public class R21BasicStackPresentation extends StackPresentation {

    private R21PaneFolder paneFolder;

    private IPresentablePart current;

    private boolean activeState = false;

    private MenuManager systemMenuManager = new MenuManager();

    private CLabel titleLabel;

    private final static String TAB_DATA = R21BasicStackPresentation.class
            .getName()
            + ".partId"; //$NON-NLS-1$

    //	private PaneFolderButtonListener buttonListener = new PaneFolderButtonListener() {
    //		public void stateButtonPressed(int buttonId) {
    //			getSite().setState(buttonId);
    //		}
    //
    //		public void closeButtonPressed(CTabItem item) {
    //			IPresentablePart part = getPartForTab(item);
    //			
    //			getSite().close(part);		
    //		}
    //	};
    //	
    private MouseListener mouseListener = new MouseAdapter() {
        public void mouseDown(MouseEvent e) {
            if (e.widget instanceof Control) {
                Control ctrl = (Control) e.widget;
                Point globalPos = ctrl.toDisplay(new Point(e.x, e.y));

                // PR#1GDEZ25 - If selection will change in mouse up ignore mouse down.
                // Else, set focus.
                CTabItem newItem = paneFolder.getItem(paneFolder.getControl()
                        .toControl(globalPos));
                if (newItem != null) {
                    CTabItem oldItem = paneFolder.getSelection();
                    if (newItem != oldItem)
                        return;
                }
                if (current != null) {
                    current.setFocus();
                }
            }
        }

        public void mouseDoubleClick(MouseEvent e) {
            if (getSite().getState() == IStackPresentationSite.STATE_MAXIMIZED) {
                getSite().setState(IStackPresentationSite.STATE_RESTORED);
            } else {
                getSite().setState(IStackPresentationSite.STATE_MAXIMIZED);
            }
        }
    };

    private MouseListener titleMouseListener = new MouseAdapter() {
        public void mouseDown(MouseEvent e) {
            if (e.widget instanceof Control) {
                Control ctrl = (Control) e.widget;
                Point globalPos = ctrl.toDisplay(new Point(0, titleLabel
                        .getBounds().height));

                if ((e.button == 1) && overImage(e.x))
                    showSystemMenu(globalPos);
            }
        }
    };

    private Listener menuListener = new Listener() {
        /* (non-Javadoc)
         * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
         */
        public void handleEvent(Event event) {
            Point pos = new Point(event.x, event.y);

            showSystemMenu(pos);
        }
    };

    private Listener dragListener = new Listener() {
        public void handleEvent(Event event) {

            Point localPos = new Point(event.x, event.y);
            CTabItem tabUnderPointer = paneFolder.getItem(localPos);

            // Drags on the title area drag the selected part only
            if (tabUnderPointer == null) {
                if (paneFolder.getTabPosition() == SWT.BOTTOM
                        && localPos.y < paneFolder.getControl().getBounds().height
                                - paneFolder.getTabHeight())
                    tabUnderPointer = paneFolder.getSelection();
                else if (paneFolder.getTabPosition() == SWT.TOP
                        && localPos.y > paneFolder.getTabHeight())
                    tabUnderPointer = paneFolder.getSelection();
            }

            // Not in a tab, not in a title area, must be dragging the whole stack
            if (tabUnderPointer == null) {
                getSite().dragStart(
                        paneFolder.getControl().toDisplay(localPos), false);
                return;
            }

            IPresentablePart part = getPartForTab(tabUnderPointer);

            if (getSite().isPartMoveable(part)) {
                getSite().dragStart(part,
                        paneFolder.getControl().toDisplay(localPos), false);
            }
        }
    };

    private Listener selectionListener = new Listener() {
        public void handleEvent(Event e) {
            IPresentablePart item = getPartForTab((CTabItem) e.item);

            if (item != null) {
                getSite().selectPart(item);
            }
        }
    };

    private Listener resizeListener = new Listener() {
        public void handleEvent(Event e) {
            setControlSize();
        }
    };

    private IPropertyListener childPropertyChangeListener = new IPropertyListener() {
        public void propertyChanged(Object source, int property) {
            if (source instanceof IPresentablePart) {
                IPresentablePart part = (IPresentablePart) source;
                childPropertyChanged(part, property);
            }
        }
    };

    private DisposeListener tabDisposeListener = new DisposeListener() {
        public void widgetDisposed(DisposeEvent e) {
            if (e.widget instanceof CTabItem) {
                CTabItem item = (CTabItem) e.widget;

                IPresentablePart part = getPartForTab(item);

                part.removePropertyListener(childPropertyChangeListener);
            }
        }
    };

    /** the shell listener for upgrading the gradient */
    private ShellAdapter shellListener = new ShellAdapter() {

        public void shellActivated(ShellEvent event) {
            updateGradient();
        }

        public void shellDeactivated(ShellEvent event) {
            updateGradient();
        }
    };

    private ToolBar viewToolBar;

    private ToolItem pullDownButton;

    private ToolItem closeButton;

    public R21BasicStackPresentation(R21PaneFolder control,
            IStackPresentationSite stackSite) {
        super(stackSite);
        paneFolder = control;

        //		tabFolder.setMinimizeVisible(stackSite.supportsState(IStackPresentationSite.STATE_MINIMIZED));
        //		tabFolder.setMaximizeVisible(stackSite.supportsState(IStackPresentationSite.STATE_MAXIMIZED));
        //				
        titleLabel = new CLabel(paneFolder.getControl(), SWT.SHADOW_NONE);
        titleLabel.setVisible(false);
        titleLabel.moveAbove(null);
        titleLabel.addMouseListener(titleMouseListener);
        titleLabel.addMouseListener(mouseListener);
        titleLabel.addListener(SWT.MenuDetect, menuListener);
        PresentationUtil.addDragListener(titleLabel, dragListener);

        //ColorSchemeService.setViewTitleFont(this, titleLabel);

        viewToolBar = new ToolBar(control.getControl(), SWT.HORIZONTAL
                | SWT.FLAT);
        viewToolBar.moveAbove(null);

        pullDownButton = new ToolItem(viewToolBar, SWT.PUSH);
        //				Image img = WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_VIEW_MENU);
        Image hoverImage = WorkbenchImages
                .getImage(IWorkbenchGraphicConstants.IMG_LCL_VIEW_MENU_HOVER);
        pullDownButton.setDisabledImage(null); // TODO: comment this out?
        // PR#1GE56QT - Avoid creation of unnecessary image.
        pullDownButton.setImage(hoverImage);
        pullDownButton.setToolTipText(R21PresentationMessages
                .getString("BasicStackPresentation.menu")); //$NON-NLS-1$
        pullDownButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                showPaneMenu();
            }
        });

        // listener to switch between visible tabItems
        paneFolder.getControl().addListener(SWT.Selection, selectionListener);

        // listener to resize visible components
        paneFolder.getControl().addListener(SWT.Resize, resizeListener);

        // listen for mouse down on tab to set focus.
        paneFolder.getControl().addMouseListener(mouseListener);

        paneFolder.getControl().addListener(SWT.MenuDetect, menuListener);

        //		tabFolder.addButtonListener(buttonListener);

        PresentationUtil.addDragListener(paneFolder.getControl(), dragListener);

        // add the shell listener to track shell activations
        // TODO: check if workaround can be removed (see bug 55458)
        paneFolder.getControl().getShell().addShellListener(shellListener);

        // Uncomment to allow dragging from the title label
        //		PresentationUtil.addDragListener(titleLabel, new Listener() {
        //			public void handleEvent(Event event) {
        //				if (layout.isTrimOnTop()) {
        //					Point localPos = new Point(event.x, event.y);
        //					getSite().dragStart(titleLabel.toDisplay(localPos), false);
        //				}
        //			}
        //		});

        //		// Compute the tab height
        //		int tabHeight = viewToolBar.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
        //
        //		// Enforce a minimum tab height
        //		if (tabHeight < 20) {
        //			tabHeight = 20;
        //		}
        //		paneFolder.setTabHeight(tabHeight);
        //		
        populateSystemMenu(systemMenuManager);
    }

    /*
     * Return true if <code>x</code> is over the label image.
     */
    private boolean overImage(int x) {
        return x < titleLabel.getImage().getBounds().width;
    }

    /**
     * @param systemMenuManager
     */
    private void populateSystemMenu(IMenuManager systemMenuManager) {

        systemMenuManager.add(new GroupMarker("misc")); //$NON-NLS-1$
        systemMenuManager.add(new GroupMarker("restore")); //$NON-NLS-1$
        systemMenuManager.add(new UpdatingActionContributionItem(
                new SystemMenuRestore(getSite())));

        systemMenuManager.add(new SystemMenuMove(getSite(), getPaneName()));
        systemMenuManager.add(new GroupMarker("size")); //$NON-NLS-1$
        systemMenuManager.add(new GroupMarker("state")); //$NON-NLS-1$
        systemMenuManager.add(new UpdatingActionContributionItem(
                new SystemMenuMinimize(getSite())));

        systemMenuManager.add(new UpdatingActionContributionItem(
                new SystemMenuMaximize(getSite())));
        systemMenuManager.add(new Separator("close")); //$NON-NLS-1$
        systemMenuManager.add(new UpdatingActionContributionItem(
                new SystemMenuClose(getSite())));

        getSite().addSystemActions(systemMenuManager);
    }

    protected String getPaneName() {
        return R21PresentationMessages.getString("BasicStackPresentation.pane"); //$NON-NLS-1$
    }

    /**
     * Displays the view menu as a popup
     */
    public void showPaneMenu() {
        IPartMenu menu = getPartMenu();

        if (menu != null) {
            Rectangle bounds = DragUtil.getDisplayBounds(viewToolBar);
            menu.showMenu(new Point(bounds.x, bounds.y + bounds.height));
        }
    }

    /**
     * Returns the currently selected part, or <code>null</code>.
     * 
     * @return the currently selected part, or <code>null</code>
     */
    protected IPresentablePart getCurrent() {
        return current;
    }

    /**
     * Returns the index of the tab for the given part, or returns tabFolder.getItemCount()
     * if there is no such tab.
     * 
     * @param part part being searched for
     * @return the index of the tab for the given part, or the number of tabs
     * if there is no such tab
     */
    private final int indexOf(IPresentablePart part) {
        if (part == null) {
            return paneFolder.getItemCount();
        }

        CTabItem[] items = paneFolder.getItems();

        for (int idx = 0; idx < items.length; idx++) {
            IPresentablePart tabPart = getPartForTab(items[idx]);

            if (part == tabPart) {
                return idx;
            }
        }

        return items.length;
    }

    /**
     * Returns the tab for the given part, or null if there is no such tab
     * 
     * @param part the part being searched for
     * @return the tab for the given part, or null if there is no such tab
     */
    protected final CTabItem getTab(IPresentablePart part) {
        CTabItem[] items = paneFolder.getItems();

        int idx = indexOf(part);

        if (idx < items.length) {
            return items[idx];
        }

        return null;
    }

    /**
     * @param part
     * @param property
     */
    protected void childPropertyChanged(IPresentablePart part, int property) {

        CTabItem tab = getTab(part);
        initTab(tab, part);

        switch (property) {
        case IPresentablePart.PROP_BUSY:
            break;
        case IPresentablePart.PROP_HIGHLIGHT_IF_BACK:
        //	     	FontRegistry registry = 
        //			    PlatformUI.getWorkbench().
        //			    	getThemeManager().getCurrentTheme().
        //			    		getFontRegistry();
        //	     	
        //	       	if(!getCurrent().equals(part))//Set bold if it does currently have focus
        //				tab.setFont(registry.getBold(IWorkbenchThemeConstants.TAB_TEXT_FONT));
        //	        break;
        case IPresentablePart.PROP_TOOLBAR:
        case IPresentablePart.PROP_PANE_MENU:
        case IPresentablePart.PROP_TITLE:
            setControlSize();
            break;
        }
    }

    protected final IPresentablePart getPartForTab(CTabItem item) {
        IPresentablePart part = (IPresentablePart) item.getData(TAB_DATA);

        return part;
    }

    /**
     * Returns the underlying tab folder for this presentation.
     * 
     * @return
     */
    protected R21PaneFolder getPaneFolder() {
        return paneFolder;
    }

    /**
     * Returns true iff the underlying tab folder has been disposed.
     * 
     * @return
     */
    public boolean isDisposed() {
        return paneFolder == null || paneFolder.isDisposed();
    }

    /**
     * Update the tab folder's colours to match the current theme settings
     * and active state
     */
    protected void updateGradient() {

        if (isDisposed())
            return;

        Color fgColor;
        Color[] bgColors;
        int[] bgPercents;
        boolean vertical = false;
        if (isActive()) {
            if (getShellActivated()) {
                fgColor = R21Colors.getSystemColor(SWT.COLOR_TITLE_FOREGROUND);
                bgColors = R21Colors.getActiveViewGradient();
                bgPercents = R21Colors.getActiveViewGradientPercents();
            } else {
                fgColor = R21Colors
                        .getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND);
                bgColors = R21Colors.getDeactivatedViewGradient();
                bgPercents = R21Colors.getDeactivatedViewGradientPercents();
            }

        } else {
            fgColor = R21Colors.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
            bgColors = null;
            bgPercents = null;
        }

        drawGradient(fgColor, bgColors, bgPercents, vertical);

        //		Color fgColor;
        //		ITheme currentTheme = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme();
        //        FontRegistry fontRegistry = currentTheme.getFontRegistry();	    
        //		ColorRegistry colorRegistry = currentTheme.getColorRegistry();
        //		Color [] bgColors = new Color[2];
        //		int [] percent = new int[1];
        //		boolean vertical;

        //        if (isActive()){
        //        	
        //        	CTabItem item = getPaneFolder().getSelection();
        //            if(item != null && !getPartForTab(item).isBusy()){
        //            	Font tabFont = fontRegistry.get(IWorkbenchThemeConstants.TAB_TEXT_FONT);
        ////            	item.setFont(tabFont);
        //            }
        //            
        //	        fgColor = colorRegistry.get(IWorkbenchThemeConstants.ACTIVE_TAB_TEXT_COLOR);
        //            bgColors[0] = colorRegistry.get(IWorkbenchThemeConstants.ACTIVE_TAB_BG_START);
        //            bgColors[1] = colorRegistry.get(IWorkbenchThemeConstants.ACTIVE_TAB_BG_END);
        //            percent[0] = currentTheme.getInt(IWorkbenchThemeConstants.ACTIVE_TAB_PERCENT);
        //            vertical = currentTheme.getBoolean(IWorkbenchThemeConstants.ACTIVE_TAB_VERTICAL);
        //		} else {
        //	        fgColor = colorRegistry.get(IWorkbenchThemeConstants.INACTIVE_TAB_TEXT_COLOR);
        //            bgColors[0] = colorRegistry.get(IWorkbenchThemeConstants.INACTIVE_TAB_BG_START);
        //            bgColors[1] = colorRegistry.get(IWorkbenchThemeConstants.INACTIVE_TAB_BG_END);
        //            percent[0] = currentTheme.getInt(IWorkbenchThemeConstants.INACTIVE_TAB_PERCENT);
        //            vertical = currentTheme.getBoolean(IWorkbenchThemeConstants.INACTIVE_TAB_VERTICAL);
        //		}	
        //      
        //		
        //		drawGradient(fgColor, bgColors, bgPercents, false);	
    }

    /**
     * Draws the applicable gradient on the title area
     * 
     * @param fgColor
     * @param bgColors
     * @param percentages
     * @param vertical
     */
    public void drawGradient(Color fgColor, Color[] bgColors,
            int[] percentages, boolean vertical) {
        //		paneFolder.setSelectionForeground(fgColor);
        //		paneFolder.setSelectionBackground(bgColors, percentages, vertical);	

        if (titleLabel == null || viewToolBar == null)
            return;

        titleLabel.setBackground(bgColors, percentages, vertical);
        titleLabel.setForeground(fgColor);

        titleLabel.update();
    }

    public boolean isActive() {
        return activeState;
    }

    /**
     * Set the size of a page in the folder.
     * 
     * TODO: Kim here...I had to make this public so that the when the font
     * was updated via the color scheme service it could relayout the 
     * presentation... calling control.getLayout() doesn't do the trick.
     */
    public void setControlSize() {
        // Set up the top-right controls
        //List topRight = new ArrayList(3);

        if (current != null) {
            paneFolder.setTopLeft(titleLabel);
            titleLabel.setText(current.getTitle());
            titleLabel.setImage(current.getTitleImage());
            titleLabel.setVisible(true);
        }

        Control currentToolbar = getCurrentToolbar();
        paneFolder.setTopCenter(currentToolbar);

        IPartMenu partMenu = getPartMenu();

        if (partMenu != null) {
            pullDownButton.setEnabled(true);
        } else {
            pullDownButton.setEnabled(false);
        }
        paneFolder.setTopRight(viewToolBar);
        viewToolBar.setVisible(true);

        paneFolder.layout(true);

        if (current != null) {
            Rectangle clientArea = paneFolder.getClientArea();
            Rectangle bounds = paneFolder.getControl().getBounds();
            clientArea.x += bounds.x;
            clientArea.y += bounds.y;

            current.setBounds(clientArea);
        }

    }

    /**
     * Returns the IPartMenu for the currently selected part, or null if the current
     * part does not have a menu.
     * 
     * @return the IPartMenu for the currently selected part or null if none
     */
    protected IPartMenu getPartMenu() {
        IPresentablePart part = getCurrentPart();
        if (part == null) {
            return null;
        }

        return part.getMenu();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.Presentation#dispose()
     */
    public void dispose() {
        if (isDisposed()) {
            return;
        }

        // remove shell listener
        paneFolder.getControl().getShell().removeShellListener(shellListener);

        PresentationUtil.removeDragListener(paneFolder.getControl(),
                dragListener);
        PresentationUtil.removeDragListener(titleLabel, dragListener);

        systemMenuManager.dispose();
        systemMenuManager.removeAll();
        paneFolder.getControl().dispose();
        paneFolder = null;

        titleLabel.dispose();
        titleLabel = null;

        viewToolBar.dispose();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.Presentation#setActive(boolean)
     */
    public void setActive(boolean isActive) {
        activeState = isActive;
        updateGradient();
    }

    /**
     * Return whether the window's shell is activated
     */
    /* package */boolean getShellActivated() {
        Window window = getWindow();
        if (window instanceof WorkbenchWindow)
            return ((WorkbenchWindow) window).getShellActivated();
        else
            return false;
    }

    /**
     * Returns the top level window.
     */
    public Window getWindow() {
        Control ctrl = getControl();
        if (ctrl != null) {
            Object data = ctrl.getShell().getData();
            if (data instanceof Window)
                return (Window) data;
        }
        return null;
    }

    private CTabItem createPartTab(IPresentablePart part, int tabIndex) {
        CTabItem tabItem;

        int style = SWT.NONE;

        if (getSite().isCloseable(part))
            style |= SWT.CLOSE;

        tabItem = paneFolder.createItem(style, tabIndex);

        tabItem.setData(TAB_DATA, part);

        part.addPropertyListener(childPropertyChangeListener);
        tabItem.addDisposeListener(tabDisposeListener);

        initTab(tabItem, part);

        return tabItem;
    }

    // Create a close button in the title bar for the argument part (if needed).
    private void updateCloseButton() {
        // remove the close button if needed
        if (current == null || !getSite().isCloseable(current)) {
            if (closeButton != null) {
                closeButton.dispose();
                closeButton = null;

                paneFolder.flush();
            }
            return;
        }

        // a close button is needed, so if its already there, we're done
        if (closeButton != null)
            return;

        // otherwise create it
        closeButton = new ToolItem(viewToolBar, SWT.PUSH);
        closeButton.setDisabledImage(null);
        closeButton.setImage(WorkbenchImages
                .getImage(IWorkbenchGraphicConstants.IMG_LCL_CLOSE_VIEW_HOVER));
        closeButton.setToolTipText(R21PresentationMessages
                .getString("BasicStackPresentation.close")); //$NON-NLS-1$
        closeButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                close(getCurrent());
            }
        });

        paneFolder.flush();
    }

    /**
     * Initializes a tab for the given part. Sets the text, icon, tool tip,
     * etc. This will also be called whenever a relevant property changes
     * in the part to reflect those changes in the tab. Subclasses may override
     * to change the appearance of tabs for a particular part.
     * 
     * @param tabItem tab for the part
     * @param part the part being displayed
     */
    protected void initTab(CTabItem tabItem, IPresentablePart part) {
        tabItem.setText(part.getName());

        //tabItem.setImage(part.getTitleImage());

        String toolTipText = part.getTitleToolTip();
        if (!toolTipText.equals(Util.ZERO_LENGTH_STRING)) {
            tabItem.setToolTipText(toolTipText);
        }

        //		FontRegistry registry = 
        //		    PlatformUI.getWorkbench().
        //		    	getThemeManager().getCurrentTheme().
        //		    		getFontRegistry();
        //		
        //		if(part.isBusy())
        //			tabItem.setFont(registry.getItalic(IWorkbenchThemeConstants.TAB_TEXT_FONT));
        //		else{
        //			tabItem.setFont(registry.get(IWorkbenchThemeConstants.TAB_TEXT_FONT));
        //		}			

    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.StackPresentation#addPart(org.eclipse.ui.internal.skins.IPresentablePart, org.eclipse.ui.internal.skins.IPresentablePart)
     */
    public void addPart(IPresentablePart newPart, Object cookie) {

        int idx;

        if (cookie instanceof Integer) {
            idx = ((Integer) cookie).intValue();
        } else {
            // Select a location for newly inserted parts
            idx = paneFolder.getItemCount();
        }

        addPart(newPart, idx);
    }

    /**
     * Adds the given presentable part to this presentation at the given index.
     * Does nothing if a tab already exists for the given part. 
     *
     * @param newPart
     * @param index
     */
    public void addPart(IPresentablePart newPart, int index) {
        // If we already have a tab for this part, do nothing
        if (getTab(newPart) != null) {
            return;
        }
        createPartTab(newPart, index);

        setControlSize();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.StackPresentation#removePart(org.eclipse.ui.internal.skins.IPresentablePart)
     */
    public void removePart(IPresentablePart oldPart) {
        if (current == oldPart)
            current = null;

        CTabItem item = getTab(oldPart);
        if (item == null) {
            return;
        }
        oldPart.setVisible(false);

        item.dispose();

        // Layout the folder again in case there is only one item
        setControlSize();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.StackPresentation#selectPart(org.eclipse.ui.internal.skins.IPresentablePart)
     */
    public void selectPart(IPresentablePart toSelect) {
        if (toSelect == current) {
            return;
        }

        if (current != null) {
            current.setVisible(false);
        }

        current = toSelect;

        if (current != null) {
            paneFolder.setSelection(indexOf(current));
            current.setVisible(true);
            updateCloseButton();
            setControlSize();
        }
    }

    public IPresentablePart getCurrentPart() {
        return current;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.Presentation#setBounds(org.eclipse.swt.graphics.Rectangle)
     */
    public void setBounds(Rectangle bounds) {
        if (getSite().getState() == IStackPresentationSite.STATE_MINIMIZED) {
        	bounds = Geometry.copy(bounds);
        	bounds.height = computePreferredSize(false, Integer.MAX_VALUE, bounds.width, Integer.MAX_VALUE);
        }
    	
        paneFolder.getControl().setBounds(bounds);
        setControlSize();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.Presentation#computeMinimumSize()
     */
    public Point computeMinimumSize() {
        Point result = Geometry.getSize(paneFolder.computeTrim(0, 0, 0, 0));
        
        result.x += 100;
        
        return result;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.Presentation#setVisible(boolean)
     */
    public void setVisible(boolean isVisible) {
        if (current != null) {
            current.setVisible(isVisible);
        }
        paneFolder.getControl().setVisible(isVisible);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.Presentation#setState(int)
     */
    public void setState(int state) {
        //		tabFolder.setState(state);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.Presentation#getSystemMenuManager()
     */
    public IMenuManager getSystemMenuManager() {
        return systemMenuManager;
    }

    /**
     * @param point
     */
    protected void showSystemMenu(Point point) {
        Menu aMenu = systemMenuManager.createContextMenu(paneFolder
                .getControl().getParent());
        systemMenuManager.update(true);
        aMenu.setLocation(point.x, point.y);
        aMenu.setVisible(true);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.skins.Presentation#getControl()
     */
    public Control getControl() {
        return paneFolder.getControl();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.internal.skins.StackPresentation#dragOver(org.eclipse.swt.widgets.Control,
     *      org.eclipse.swt.graphics.Point)
     */
    public StackDropResult dragOver(Control currentControl, Point location) {

        // Determine which tab we're currently dragging over
        Point localPos = paneFolder.getControl().toControl(location);
        final CTabItem tabUnderPointer = paneFolder.getItem(localPos);

        // This drop target only deals with tabs... if we're not dragging over
        // a tab, exit.
        if (tabUnderPointer == null)
            return null;

        // workaround when left tab is dragged over next
        int dragOverIndex = paneFolder.indexOf(tabUnderPointer);

        return new StackDropResult(Geometry.toDisplay(paneFolder.getControl(),
                tabUnderPointer.getBounds()), new Integer(dragOverIndex));
    }

    /**
     * Returns the toolbar control for the currently selected part, or null if none (not 
     * all parts have a toolbar).
     * 
     * @return the current toolbar or null if none
     */
    protected Control getCurrentToolbar() {
        IPresentablePart part = getCurrentPart();
        if (part == null) {
            return null;
        }

        return part.getToolBar();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.presentations.StackPresentation#showSystemMenu()
     */
    public void showSystemMenu() {
        IPresentablePart part = getCurrentPart();
        if (part != null) {
            Rectangle bounds = DragUtil.getDisplayBounds(paneFolder
                    .getControl());

            int idx = paneFolder.getSelectionIndex();
            if (idx > -1) {
                CTabItem item = paneFolder.getItem(idx);
                Rectangle itemBounds = item.getBounds();

                bounds.x += itemBounds.x;
                bounds.y += itemBounds.y;
            }

            Point location = new Point(bounds.x, bounds.y
                    + paneFolder.getTabHeight());
            showSystemMenu(location);
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.presentations.StackPresentation#getTabList(IPresentablePart)
     */
    public Control[] getTabList(IPresentablePart part) {
        ArrayList list = new ArrayList();
        if (paneFolder.getTabPosition() == SWT.BOTTOM) {
            if (part.getToolBar() != null)
                list.add(part.getToolBar());
            if (part.getControl() != null)
                list.add(part.getControl());
            if (getPaneFolder() != null)
                list.add(getPaneFolder().getControl());
        } else {
            if (getPaneFolder() != null)
                list.add(getPaneFolder().getControl());
            if (part.getToolBar() != null)
                list.add(part.getToolBar());
            if (part.getControl() != null)
                list.add(part.getControl());
        }
        return (Control[]) list.toArray(new Control[list.size()]);
    }

    protected void showList(Shell parentShell, int x, int y) {
        //        final R21PaneFolder tabFolder = getTabFolder();
        //
        //        int shellStyle = SWT.RESIZE | SWT.ON_TOP | SWT.NO_TRIM;
        //        int tableStyle = SWT.V_SCROLL | SWT.H_SCROLL;
        //        final BasicStackList editorList = new BasicStackList(tabFolder.getControl().getShell(),
        //                shellStyle, tableStyle);
        //        editorList.setInput(this);
        //        Point size = editorList.computeSizeHint();
        //        
        //        Rectangle bounds = Display.getCurrent().getBounds();
        //        if (x + size.x > bounds.width) x = bounds.width - size.x;
        //        if (y + size.y > bounds.height) y = bounds.height - size.y;
        //        editorList.setLocation(new Point(x, y));
        //        editorList.setVisible(true);
        //        editorList.setFocus();
        //        editorList.getTableViewer().getTable().getShell().addListener(
        //                SWT.Deactivate, new Listener() {
        //
        //                    public void handleEvent(Event event) {
        //                        editorList.setVisible(false);
        //                    }
        //                });
    }

    /*
     * Shows the list of tabs at the top left corner of the editor
     */
    protected void showListDefaultLocation() {
        R21PaneFolder tabFolder = getPaneFolder();
        Shell shell = tabFolder.getControl().getShell();
        Rectangle clientArea = tabFolder.getClientArea();
        Point location = tabFolder.getControl().getDisplay().map(
                tabFolder.getControl(), null, clientArea.x, clientArea.y);
        showList(shell, location.x, location.y);
    }

    void setSelection(CTabItem tabItem) {
        getSite().selectPart(getPartForTab(tabItem));
    }

    void close(IPresentablePart presentablePart) {
        getSite().close(new IPresentablePart[] { presentablePart });
    }

    Image getLabelImage(IPresentablePart presentablePart) {
        return presentablePart.getTitleImage();
    }

    String getLabelText(IPresentablePart presentablePart, boolean includePath) {
        String title = presentablePart.getTitle().trim();
        return title;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.presentations.StackPresentation#setActive(int)
     */
    public void setActive(int newState) {
        setActive(newState == AS_ACTIVE_FOCUS);
    }

}