/*******************************************************************************
 * Copyright (c) 2000, 2007 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.ui.internal;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.dnd.AbstractDropTarget;
import org.eclipse.ui.internal.dnd.DragUtil;
import org.eclipse.ui.internal.dnd.IDragOverListener;
import org.eclipse.ui.internal.dnd.IDropTarget;
import org.eclipse.ui.internal.misc.StringMatcher;
import org.eclipse.ui.presentations.IStackPresentationSite;

/**
 * A perspective presentation is a collection of parts with a layout. Each part
 * is parented to a main window, so you can create more than one presentation
 * on a set of parts and change the layout just by activating / deactivating a
 * presentation.
 * 
 * In addition, the user can change the position of any part by mouse
 * manipulation (drag & drop). If a part is removed, we leave a placeholder
 * behind to indicate where it goes should the part be added back.
 */
public class PerspectiveHelper {
    private WorkbenchPage page;
    
    private Perspective perspective;

    private Composite parentWidget;

    private ViewSashContainer mainLayout;
    
	private PartStack maximizedStack;

	/**
	 * If there is a ViewStack maximized on shutdown the id is
	 * cached and restored into this field on 'restoreState'.
	 * This is then used to bash the ViewStack's presentation state
	 * into the correct value on activation (the startup life-cycle
	 * is such that we have to use this 'latch' because the window
	 * state isn't valid until the activate happens.
	 */
	private String maximizedStackId;

    private ArrayList detachedWindowList = new ArrayList(1);

    private ArrayList detachedPlaceHolderList = new ArrayList(1);

	/**
	 * Maps a stack's id to its current bounds
	 * this is used to capture the current bounds of all
	 * stacks -before- starting a maximize (since the
	 * iterative 'minimize' calls cause the intial stack's
	 * bounds to change.
	 */
	private Map boundsMap = new HashMap();

    private boolean detachable = false;

    private boolean active = false;

    // key is the LayoutPart object, value is the PartDragDrop object
    //private IPartDropListener partDropListener;

    private static final int MIN_DETACH_WIDTH = 150;

    private static final int MIN_DETACH_HEIGHT = 250;

    protected ActualDropTarget dropTarget;
    
    private IDragOverListener dragTarget = new IDragOverListener() {

        public IDropTarget drag(Control currentControl, Object draggedObject,
                Point position, final Rectangle dragRectangle) {
            
            if (!(draggedObject instanceof ViewPane || draggedObject instanceof ViewStack)) {
                return null;
            }
            final LayoutPart part = (LayoutPart) draggedObject;

            if (part.getWorkbenchWindow() != page.getWorkbenchWindow()) {
                return null;
            }

            if (dropTarget == null) {
                dropTarget = new ActualDropTarget(part, dragRectangle); 
            } else {
                dropTarget.setTarget(part, dragRectangle);
            }
            
            return dropTarget;
        }

    };

    private final class ActualDropTarget extends AbstractDropTarget {
        private LayoutPart part;

        private Rectangle dragRectangle;

        private ActualDropTarget(LayoutPart part, Rectangle dragRectangle) {
            super();
            setTarget(part, dragRectangle);
        }

        /**
         * @param part
         * @param dragRectangle
         * @since 3.1
         */
        private void setTarget(LayoutPart part, Rectangle dragRectangle) {
            this.part = part;
            this.dragRectangle = dragRectangle;
        }

        public void drop() {

            Shell shell = part.getShell();
            if (shell.getData() instanceof DetachedWindow) {
                // only one tab folder in a detach window, so do window
                // move
                if (part instanceof ViewStack) {
                    shell.setLocation(dragRectangle.x,
                            dragRectangle.y);
                    return;
                }
                // if only one view in tab folder then do a window move
                ILayoutContainer container = part.getContainer();
                if (container instanceof ViewStack) {
                    if (((ViewStack) container).getItemCount() == 1) {
                        shell.setLocation(dragRectangle.x,
                                dragRectangle.y);
                        return;
                    }
                }
            }

            // If layout is modified always zoom out.
            if (isZoomed()) {
				zoomOut();
			}
            // do a normal part detach
            detach(part, dragRectangle.x, dragRectangle.y);
        }

        public Cursor getCursor() {
            return DragCursors.getCursor(DragCursors.OFFSCREEN);
        }
    }

    private class MatchingPart implements Comparable {
        String pid;

        String sid;

        LayoutPart part;

        boolean hasWildcard;

        int len;

        MatchingPart(String pid, String sid, LayoutPart part) {
            this.pid = pid;
            this.sid = sid;
            this.part = part;
            this.len = (pid == null ? 0 : pid.length())
                    + (sid == null ? 0 : sid.length());
            this.hasWildcard = (pid != null && pid
                    .indexOf(PartPlaceholder.WILD_CARD) != -1)
                    || (sid != null && sid.indexOf(PartPlaceholder.WILD_CARD) != -1);
        }

        public int compareTo(Object a) {
            // specific ids always outweigh ids with wildcards
            MatchingPart ma = (MatchingPart) a;
            if (this.hasWildcard && !ma.hasWildcard) {
                return -1;
            }
            if (!this.hasWildcard && ma.hasWildcard) {
                return 1;
            }
            // if both are specific or both have wildcards, simply compare based on length
            return ma.len - this.len;
        }
    }

    
    /**
     * Constructs a new object.
     */
    public PerspectiveHelper(WorkbenchPage workbenchPage,
            ViewSashContainer mainLayout, Perspective perspective) {
        this.page = workbenchPage;
        this.mainLayout = mainLayout;
        this.perspective = perspective;
        
		// Views can be detached if the feature is enabled (true by default,
		// use the plug-in customization file to disable), and if the platform
		// supports detaching.
         
        final IPreferenceStore store = PlatformUI.getPreferenceStore();
        this.detachable = store.getBoolean(IWorkbenchPreferenceConstants.ENABLE_DETACHED_VIEWS);

        if (this.detachable) {
			// Check if some arbitrary Composite supports reparenting. If it
			// doesn't, views cannot be detached.

			Composite client = workbenchPage.getClientComposite();
			if (client == null) {
				// The workbench page is not initialized. I don't think this can happen,
				// but if it does, silently set detachable to false.
				this.detachable = false;
			} else {
				Composite testChild = new Composite(client, SWT.NONE);
				this.detachable = testChild.isReparentable();
				testChild.dispose();
			}
		}
    }

    /**
	 * Show the presentation.
	 */
    public void activate(Composite parent) {

        if (active) {
			return;
		}

        parentWidget = parent;

        // Activate main layout
        // make sure all the views have been properly parented
        Vector children = new Vector();
        collectViewPanes(children, mainLayout.getChildren());
        Enumeration itr = children.elements();
        while (itr.hasMoreElements()) {
            LayoutPart part = (LayoutPart) itr.nextElement();
            part.reparent(parent);
        }
        mainLayout.createControl(parent);
        mainLayout.setActive(true);

        // Open the detached windows.
        for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
            DetachedWindow dwindow = (DetachedWindow) detachedWindowList.get(i);
            dwindow.open();
        }

        enableAllDrag();

        // Ensure that the maximized stack's presentation state is correct
        if (maximizedStackId != null) {
        	LayoutPart part = findPart(maximizedStackId);
        	if (part instanceof PartStack) {
        		maximizedStack = (PartStack) part;
            	maximizedStackId = null;
        	}
        }
        
        // NOTE: we only handle ViewStacks here; Editor Stacks are handled by the
        // perspective
        if (maximizedStack instanceof ViewStack) {
        	maximizedStack.setPresentationState(IStackPresentationSite.STATE_MAXIMIZED);            	
        }
        
        active = true;
    }

	/**
     * Adds a part to the presentation. If a placeholder exists for the part
     * then swap the part in. Otherwise, add the part in the bottom right
     * corner of the presentation.
     */
    public void addPart(LayoutPart part) {
        
    	// Look for a placeholder.
        PartPlaceholder placeholder = null;
        LayoutPart testPart = null;
        String primaryId = part.getID();
        String secondaryId = null;

        IViewReference ref = null;
        if (part instanceof ViewPane) {
            ViewPane pane = (ViewPane) part;
            ref = (IViewReference) pane.getPartReference();
            secondaryId = ref.getSecondaryId();
        }
        if (secondaryId != null) {
			testPart = findPart(primaryId, secondaryId);
		} else {
			testPart = findPart(primaryId);
		}

        // validate the testPart
        if (testPart != null && testPart instanceof PartPlaceholder) {
			placeholder = (PartPlaceholder) testPart;
		}

        // If there is no placeholder do a simple add. Otherwise, replace the
        // placeholder if its not a pattern matching placholder
        if (placeholder == null) {
            part.reparent(mainLayout.getParent());
            LayoutPart relative = mainLayout.findBottomRight();
            if (relative != null && relative instanceof ILayoutContainer) {
                ILayoutContainer stack = (ILayoutContainer)relative;
                if (stack.allowsAdd(part)) {
                    mainLayout.stack(part, stack);
                } else {
                    mainLayout.add(part);
                }
            } else {
                mainLayout.add(part);
            }
        } else {
            ILayoutContainer container = placeholder.getContainer();
            if (container != null) {
                if (container instanceof DetachedPlaceHolder) {
                    //Create a detached window add the part on it.
                    DetachedPlaceHolder holder = (DetachedPlaceHolder) container;
                    detachedPlaceHolderList.remove(holder);
                    container.remove(testPart);
                    DetachedWindow window = new DetachedWindow(page);
                    detachedWindowList.add(window);
                    window.create();
                    part.createControl(window.getShell());
                    // Open window.
                    window.getShell().setBounds(holder.getBounds());
                    window.open();
                    // add part to detached window.
                    ViewPane pane = (ViewPane) part;
                    window.add(pane);
                    LayoutPart otherChildren[] = holder.getChildren();
                    for (int i = 0; i < otherChildren.length; i++) {
						part.getContainer().add(otherChildren[i]);
					}
                } else {
                    // show parent if necessary
                    if (container instanceof ContainerPlaceholder) {
                        ContainerPlaceholder containerPlaceholder = (ContainerPlaceholder) container;                        
                        ILayoutContainer parentContainer = containerPlaceholder
                                .getContainer();
                        container = (ILayoutContainer) containerPlaceholder
                                .getRealContainer();
                        if (container instanceof LayoutPart) {
                            parentContainer.replace(containerPlaceholder,
                                    (LayoutPart) container);
                        }
                        containerPlaceholder.setRealContainer(null);
                    }

                    // reparent part.
                    if (!(container instanceof ViewStack)) {
                        // We don't need to reparent children of PartTabFolders since they will automatically
                        // reparent their children when they become visible. This if statement used to be 
                        // part of an else branch. Investigate if it is still necessary.
                        part.reparent(mainLayout.getParent());
                    }

                    // see if we should replace the placeholder
                    if (placeholder.hasWildCard()) {
                        if (container instanceof PartSashContainer) {
							((PartSashContainer) container)
                                    .addChildForPlaceholder(part, placeholder);
						} else {
							container.add(part);
						}
                    } else {
						container.replace(placeholder, part);
					}
                }
            }
        }
    }
    
    /**
     * Attaches a part that was previously detached to the mainLayout. 
     * 
     * @param ref
     */
    public void attachPart(IViewReference ref) {
		ViewPane pane = (ViewPane)((WorkbenchPartReference)ref).getPane();	
		
		// Restore any maximized part before re-attaching.
		// Note that 'getMaximizedStack != null' implies 'useNewMinMax'
		if (getMaximizedStack() != null) {
			getMaximizedStack().setState(IStackPresentationSite.STATE_RESTORED);
		}
		
		derefPart(pane);
		addPart(pane);
		bringPartToTop(pane);
		pane.setFocus();
    }

    /**
     * Return whether detachable parts can be supported.
     */
    public boolean canDetach() {
        return detachable;
    }

    /**
     * Bring a part forward so it is visible.
     * 
     * @return true if the part was brought to top, false if not.
     */
    public boolean bringPartToTop(LayoutPart part) {
        ILayoutContainer container = part.getContainer();
        if (container != null && container instanceof PartStack) {
            PartStack folder = (PartStack) container;
            if (folder.getSelection() != part) {
                folder.setSelection(part);
                return true;
            }
        }
        return false;
    }

    /**
     * Returns true if the given part is visible.
     * A part is visible if it's top-level (not in a tab folder) or if it is the top one 
     * in a tab folder.
     */
    public boolean isPartVisible(IWorkbenchPartReference partRef) {
        LayoutPart foundPart;
        if (partRef instanceof IViewReference) {
			foundPart = findPart(partRef.getId(), ((IViewReference) partRef).getSecondaryId());
		} else {
			foundPart = findPart(partRef.getId());
		}
        if (foundPart == null) {
			return false;
		}
        if (foundPart instanceof PartPlaceholder) {
			return false;
		}

        ILayoutContainer container = foundPart.getContainer();
        
        if (container instanceof ContainerPlaceholder) {
			return false;
		}

        if (container instanceof ViewStack) {
            ViewStack folder = (ViewStack) container;
            PartPane visiblePart = folder.getSelection();
            if (visiblePart == null) {
				return false;
			}
            return partRef.equals(visiblePart.getPartReference());
        }
        return true;
    }

    /**
     * Returns true is not in a tab folder or if it is the top one in a tab
     * folder.
     */
    public boolean willPartBeVisible(String partId) {
        return willPartBeVisible(partId, null);
    }

    public boolean willPartBeVisible(String partId, String secondaryId) {
        LayoutPart part = findPart(partId, secondaryId);
        if (part == null) {
			return false;
		}
        ILayoutContainer container = part.getContainer();
        if (container != null && container instanceof ContainerPlaceholder) {
			container = (ILayoutContainer) ((ContainerPlaceholder) container)
                    .getRealContainer();
		}

        if (container != null && container instanceof ViewStack) {
            ViewStack folder = (ViewStack) container;
            if (folder.getSelection() == null) {
				return false;
			}
            return part.getCompoundId().equals(
                    folder.getSelection().getCompoundId());
        }
        return true;
    }

    /**
     * Answer a list of the PartPlaceholder objects.
     */
    private PartPlaceholder[] collectPlaceholders() {
        // Scan the main window.
        PartPlaceholder[] results = collectPlaceholders(mainLayout
                .getChildren());

        // Scan each detached window.
        if (detachable) {
            for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
                DetachedWindow win = (DetachedWindow) detachedWindowList.get(i);
                PartPlaceholder[] moreResults = collectPlaceholders(win
                        .getChildren());
                if (moreResults.length > 0) {
                    int newLength = results.length + moreResults.length;
                    PartPlaceholder[] newResults = new PartPlaceholder[newLength];
                    System.arraycopy(results, 0, newResults, 0, results.length);
                    System.arraycopy(moreResults, 0, newResults,
                            results.length, moreResults.length);
                    results = newResults;
                }
            }
        }
        return results;
    }

    /**
     * Answer a list of the PartPlaceholder objects.
     */
    private PartPlaceholder[] collectPlaceholders(LayoutPart[] parts) {
        PartPlaceholder[] result = new PartPlaceholder[0];

        for (int i = 0, length = parts.length; i < length; i++) {
            LayoutPart part = parts[i];
            if (part instanceof ILayoutContainer) {
                // iterate through sub containers to find sub-parts
                PartPlaceholder[] newParts = collectPlaceholders(((ILayoutContainer) part)
                        .getChildren());
                PartPlaceholder[] newResult = new PartPlaceholder[result.length
                        + newParts.length];
                System.arraycopy(result, 0, newResult, 0, result.length);
                System.arraycopy(newParts, 0, newResult, result.length,
                        newParts.length);
                result = newResult;
            } else if (part instanceof PartPlaceholder) {
                PartPlaceholder[] newResult = new PartPlaceholder[result.length + 1];
                System.arraycopy(result, 0, newResult, 0, result.length);
                newResult[result.length] = (PartPlaceholder) part;
                result = newResult;
            }
        }

        return result;
    }

    /**
     * Answer a list of the view panes.
     */
    public void collectViewPanes(List result) {
        // Scan the main window.
        collectViewPanes(result, mainLayout.getChildren());

        // Scan each detached window.
        if (detachable) {
            for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
                DetachedWindow win = (DetachedWindow) detachedWindowList.get(i);
                collectViewPanes(result, win.getChildren());
            }
        }
    }

    /**
     * Answer a list of the view panes.
     */
    private void collectViewPanes(List result, LayoutPart[] parts) {
        for (int i = 0, length = parts.length; i < length; i++) {
            LayoutPart part = parts[i];
            if (part instanceof ViewPane) {
                result.add(part);
            } else if (part instanceof ILayoutContainer) {
                collectViewPanes(result, ((ILayoutContainer) part)
                        .getChildren());
            }
        }
    }

    /**
     * Hide the presentation.
     */
    public void deactivate() {
        if (!active) {
			return;
		}

        disableAllDrag();

        // Reparent all views to the main window
        Composite parent = mainLayout.getParent();
        Vector children = new Vector();
        collectViewPanes(children, mainLayout.getChildren());

        for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
            DetachedWindow window = (DetachedWindow) detachedWindowList.get(i);
            collectViewPanes(children, window.getChildren());
        }

        // *** Do we even need to do this if detached windows not supported?
        Enumeration itr = children.elements();
        while (itr.hasMoreElements()) {
            LayoutPart part = (LayoutPart) itr.nextElement();
            part.reparent(parent);
        }
        
        // Dispose main layout.

        mainLayout.setActive(false);
        
        // Dispose the detached windows
        for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
            DetachedWindow window = (DetachedWindow) detachedWindowList.get(i);
            window.close();
        }
        
        active = false;
    }
    
    public void dispose() {
        mainLayout.dispose();
        mainLayout.disposeSashes();
    }
    
    /**
     * Writes a description of the layout to the given string buffer.
     * This is used for drag-drop test suites to determine if two layouts are the
     * same. Like a hash code, the description should compare as equal iff the
     * layouts are the same. However, it should be user-readable in order to
     * help debug failed tests. Although these are english readable strings,
     * they should not be translated or equality tests will fail.
     * <p>
     * This is only intended for use by test suites.
     * </p>
     * 
     * @param buf
     */
    public void describeLayout(StringBuffer buf) {

        if (detachable) {
            if(detachedWindowList.size() != 0){
                buf.append("detachedWindows ("); //$NON-NLS-1$
          
	            for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
	                DetachedWindow window = (DetachedWindow) detachedWindowList.get(i);
	                LayoutPart[] children = window.getChildren();
	                if(children.length != 0){
	                    buf.append("dWindow ("); //$NON-NLS-1$
	                    for(int j = 0; j < children.length; j++){
	                        buf.append(((ViewPane)children[j]).getViewReference().getPartName());
	                        if(j < (children.length - 1)) {
								buf.append(", "); //$NON-NLS-1$
							}
	                    }
	                    buf.append(")"); //$NON-NLS-1$
	                }
	                
	            }
	            buf.append("), "); //$NON-NLS-1$
            }
        }
            
        getLayout().describeLayout(buf);
    }

    /**
     * Deref a given part. Deconstruct its container as required. Do not remove
     * drag listeners.
     */
    /* package */void derefPart(LayoutPart part) {
        if (part instanceof ViewPane) {
        	IViewReference ref = ((ViewPane) part).getViewReference();
        	if (perspective.isFastView(ref)) {
        		// Special check: if it's a fast view then it's actual ViewStack
        		// may only contain placeholders and the stack is represented in
        		// the presentation by a container placeholder...make sure the
        		// PartPlaceHolder for 'ref' is removed from the ViewStack
        		String id = perspective.getFastViewManager().getIdForRef(ref);
        		LayoutPart parentPart = findPart(id, null);
        		if (parentPart instanceof ContainerPlaceholder) {
        			ViewStack vs = (ViewStack) ((ContainerPlaceholder)parentPart).getRealContainer();
        			LayoutPart[] kids = vs.getChildren();
        			for (int i = 0; i < kids.length; i++) {
						if (kids[i] instanceof PartPlaceholder) {
							if (ref.getId().equals(kids[i].id))
								vs.remove(kids[i]);
						}
					}
        		}
        		perspective.getFastViewManager().removeViewReference(ref, true, true);
        	}
        }

        // Get vital part stats before reparenting.
        ILayoutContainer oldContainer = part.getContainer();
        boolean wasDocked = part.isDocked();
        Shell oldShell = part.getShell();

        // Reparent the part back to the main window
        part.reparent(mainLayout.getParent());

        // Update container.
        if (oldContainer == null) {
			return;
		}

        oldContainer.remove(part);

        LayoutPart[] children = oldContainer.getChildren();
        if (wasDocked) {
            boolean hasChildren = (children != null) && (children.length > 0);
            if (hasChildren) {
                // make sure one is at least visible
                int childVisible = 0;
                for (int i = 0; i < children.length; i++) {
					if (children[i].getControl() != null) {
						childVisible++;
					}
				}

                // none visible, then reprarent and remove container
                if (oldContainer instanceof ViewStack) {
                    ViewStack folder = (ViewStack) oldContainer;
                    
                    // Is the part in the trim?
                    boolean inTrim = false;
                    // Safety check...there may be no FastViewManager
                    if (perspective.getFastViewManager() != null)
                    	inTrim = perspective.getFastViewManager().getFastViews(folder.getID()).size() > 0;
                    	
                    if (childVisible == 0 && !inTrim) {
                        ILayoutContainer parentContainer = folder
                                .getContainer();
                        for (int i = 0; i < children.length; i++) {
                            folder.remove(children[i]);
                            parentContainer.add(children[i]);
                        }
                        hasChildren = false;
                    } else if (childVisible == 1) {
                        LayoutTree layout = mainLayout.getLayoutTree();
                        layout = layout.find(folder);
                        layout.setBounds(layout.getBounds());
                    }
                }
            }

            if (!hasChildren) {
                // There are no more children in this container, so get rid of
                // it
                if (oldContainer instanceof LayoutPart) {
                    LayoutPart parent = (LayoutPart) oldContainer;
                    ILayoutContainer parentContainer = parent.getContainer();
                    if (parentContainer != null) {
                        parentContainer.remove(parent);
                        parent.dispose();
                    }
                }
            }
        } else if (!wasDocked) {
            if (children == null || children.length == 0) {
                // There are no more children in this container, so get rid of
                // it
                // Turn on redraw again just in case it was off.
                //oldShell.setRedraw(true);
                DetachedWindow w = (DetachedWindow)oldShell.getData();
                oldShell.close();
                detachedWindowList.remove(w);
            } else {
                // There are children. If none are visible hide detached
                // window.
                boolean allInvisible = true;
                for (int i = 0, length = children.length; i < length; i++) {
                    if (!(children[i] instanceof PartPlaceholder)) {
                        allInvisible = false;
                        break;
                    }
                }
                if (allInvisible) {
                    DetachedPlaceHolder placeholder = new DetachedPlaceHolder(
                            "", //$NON-NLS-1$
                            oldShell.getBounds());
                    for (int i = 0, length = children.length; i < length; i++) {
                        oldContainer.remove(children[i]);
                        children[i].setContainer(placeholder);
                        placeholder.add(children[i]);
                    }
                    detachedPlaceHolderList.add(placeholder);
                    DetachedWindow w = (DetachedWindow)oldShell.getData();
                    oldShell.close();
                    detachedWindowList.remove(w);
                }
            }
        }

    }

    /**
     * Create a detached window containing a part.
     */
    private void detach(LayoutPart source, int x, int y) {

        // Detaching is disabled on some platforms ..
        if (!detachable) {
			return;
		}

        LayoutPart part = source.getPart();
        // Calculate detached window size.
        Point size = part.getSize();
        if (size.x == 0 || size.y == 0) {
            ILayoutContainer container = part.getContainer();
            if (container instanceof LayoutPart) {
                size = ((LayoutPart) container).getSize();
            }
        }
        int width = Math.max(size.x, MIN_DETACH_WIDTH);
        int height = Math.max(size.y, MIN_DETACH_HEIGHT);

        // Create detached window.
        DetachedWindow window = new DetachedWindow(page);
        detachedWindowList.add(window);

        // Open window.
        window.create();
        window.getShell().setBounds(x, y, width, height);
        window.open();

        if (part instanceof ViewStack) {
            window.getShell().setRedraw(false);
            parentWidget.setRedraw(false);
            LayoutPart visiblePart = ((ViewStack) part).getSelection();
            LayoutPart children[] = ((ViewStack) part).getChildren();
            for (int i = 0; i < children.length; i++) {
                if (children[i] instanceof ViewPane) {
                    // remove the part from its current container
                    derefPart(children[i]);
                    // add part to detached window.
                    ViewPane pane = (ViewPane) children[i];
                    window.add(pane);
                }
            }
            if (visiblePart != null) {
                bringPartToTop(visiblePart);
                visiblePart.setFocus();
            }
            window.getShell().setRedraw(true);
            parentWidget.setRedraw(true);
        } else {
            // remove the part from its current container
            derefPart(part);
            // add part to detached window.
            ViewPane pane = (ViewPane) part;
            window.add(pane);
            part.setFocus();
        }

    }
    
    /**
     * Detached a part from the mainLayout. Presently this does not use placeholders
     * since the current implementation is not robust enough to remember a view's position
     * in more than one root container. For now the view is simply derefed and will dock
     * in the default position when attachPart is called. 
     * 
     * By default parts detached this way are set to float on top of the workbench
     * without docking. It is assumed that people that want to drag a part back onto
     * the WorkbenchWindow will detach it via drag and drop. 
     * 
     * @param ref
     */
    public void detachPart(IViewReference ref) {
		ViewPane pane = (ViewPane)((WorkbenchPartReference)ref).getPane();
    	if (canDetach() && pane != null) {
    		Rectangle bounds = pane.getParentBounds();
    	    detach(pane, bounds.x ,bounds.y);
    	}
    }

    /**
     * Create a detached window containing a part.
     */
    public void addDetachedPart(LayoutPart part) {
        // Calculate detached window size.
        Rectangle bounds = parentWidget.getShell().getBounds();
        bounds.x = bounds.x + (bounds.width - 300) / 2;
        bounds.y = bounds.y + (bounds.height - 300) / 2;
        
        addDetachedPart(part, bounds);
    }
    
    public void addDetachedPart(LayoutPart part, Rectangle bounds) {
        // Detaching is disabled on some platforms ..
        if (!detachable) {
            addPart(part);
            return;
        }
        
        // Create detached window.
        DetachedWindow window = new DetachedWindow(page);
        detachedWindowList.add(window);
        window.create();

        // add part to detached window.
        part.createControl(window.getShell());
        ViewPane pane = (ViewPane) part;
        window.add(pane);

        // Open window.
        window.getShell().setBounds(bounds.x, bounds.y, bounds.width, bounds.height);
        window.open();

        part.setFocus();
        
    }

    /**
     * disableDragging.
     */
    private void disableAllDrag() {
        DragUtil.removeDragTarget(null, dragTarget);
    }

    /**
     * enableDragging.
     */
    private void enableAllDrag() {
        DragUtil.addDragTarget(null, dragTarget);
    }

    /**
     * Find the first part with a given ID in the presentation.
     * Wild cards now supported.
     */
    private LayoutPart findPart(String id) {
        return findPart(id, null);
    }

    /**
     * Find the first part that matches the specified 
     * primary and secondary id pair.  Wild cards
     * are supported.
     */
    public LayoutPart findPart(String primaryId, String secondaryId) {
        // check main window.
        ArrayList matchingParts = new ArrayList();
        LayoutPart part = (secondaryId != null) ? findPart(primaryId,
                secondaryId, mainLayout.getChildren(), matchingParts)
                : findPart(primaryId, mainLayout.getChildren(), matchingParts);
        if (part != null) {
			return part;
		}

        // check each detached windows.
        for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
            DetachedWindow window = (DetachedWindow) detachedWindowList.get(i);
            part = (secondaryId != null) ? findPart(primaryId, secondaryId,
                    window.getChildren(), matchingParts) : findPart(primaryId,
                    window.getChildren(), matchingParts);
            if (part != null) {
				return part;
			}
        }
        for (int i = 0; i < detachedPlaceHolderList.size(); i++) {
            DetachedPlaceHolder holder = (DetachedPlaceHolder) detachedPlaceHolderList
                    .get(i);
            part = (secondaryId != null) ? findPart(primaryId, secondaryId,
                    holder.getChildren(), matchingParts) : findPart(primaryId,
                    holder.getChildren(), matchingParts);
            if (part != null) {
				return part;
			}
        }

        // sort the matching parts
        if (matchingParts.size() > 0) {
            Collections.sort(matchingParts);
            MatchingPart mostSignificantPart = (MatchingPart) matchingParts
                    .get(0);
            if (mostSignificantPart != null) {
				return mostSignificantPart.part;
			}
        }

        // Not found.
        return null;
    }

    /**
     * Find the first part with a given ID in the presentation.
     */
    private LayoutPart findPart(String id, LayoutPart[] parts,
            ArrayList matchingParts) {
        for (int i = 0, length = parts.length; i < length; i++) {
            LayoutPart part = parts[i];
            // check for part equality, parts with secondary ids fail
            if (part.getID().equals(id)) {
                if (part instanceof ViewPane) {
                    ViewPane pane = (ViewPane) part;
                    IViewReference ref = (IViewReference) pane
                            .getPartReference();
                    if (ref.getSecondaryId() != null) {
						continue;
					}
                }
                return part;
            }
            // check pattern matching placeholders
            else if (part instanceof PartPlaceholder
                    && ((PartPlaceholder) part).hasWildCard()) {
                StringMatcher sm = new StringMatcher(part.getID(), true, false);
                if (sm.match(id)) {
					matchingParts
                            .add(new MatchingPart(part.getID(), null, part));
				}
            } else if (part instanceof EditorSashContainer) {
                // Skip.
            } else if (part instanceof ILayoutContainer) {
                part = findPart(id, ((ILayoutContainer) part).getChildren(),
                        matchingParts);
                if (part != null) {
					return part;
				}
            }
        }
        return null;
    }

    /**
     * Find the first part that matches the specified 
     * primary and secondary id pair.  Wild cards
     * are supported.
     */
    private LayoutPart findPart(String primaryId, String secondaryId,
            LayoutPart[] parts, ArrayList matchingParts) {
        for (int i = 0, length = parts.length; i < length; i++) {
            LayoutPart part = parts[i];
            // check containers first
            if (part instanceof ILayoutContainer) {
                LayoutPart testPart = findPart(primaryId, secondaryId,
                        ((ILayoutContainer) part).getChildren(), matchingParts);
                if (testPart != null) {
					return testPart;
				}
            }
            // check for view part equality
            if (part instanceof ViewPane) {
                ViewPane pane = (ViewPane) part;
                IViewReference ref = (IViewReference) pane.getPartReference();
                if (ref.getId().equals(primaryId)
                        && ref.getSecondaryId() != null
                        && ref.getSecondaryId().equals(secondaryId)) {
					return part;
				}
            }
            // check placeholders
            else if ((parts[i] instanceof PartPlaceholder)) {
                String id = part.getID();

                // optimization: don't bother parsing id if it has no separator -- it can't match
                String phSecondaryId = ViewFactory.extractSecondaryId(id);
                if (phSecondaryId == null) {
                    // but still need to check for wildcard case
                    if (id.equals(PartPlaceholder.WILD_CARD)) {
						matchingParts.add(new MatchingPart(id, null, part));
					}
                    continue;
                }

                String phPrimaryId = ViewFactory.extractPrimaryId(id);
                // perfect matching pair
                if (phPrimaryId.equals(primaryId)
                        && phSecondaryId.equals(secondaryId)) {
                    return part;
                }
                // check for partial matching pair
                StringMatcher sm = new StringMatcher(phPrimaryId, true, false);
                if (sm.match(primaryId)) {
                    sm = new StringMatcher(phSecondaryId, true, false);
                    if (sm.match(secondaryId)) {
                        matchingParts.add(new MatchingPart(phPrimaryId,
                                phSecondaryId, part));
                    }
                }
            } else if (part instanceof EditorSashContainer) {
                // Skip.
            }
        }
        return null;
    }

    /**
     * Returns true if a placeholder exists for a given ID.
     */
    public boolean hasPlaceholder(String id) {
        return hasPlaceholder(id, null);
    }

    /**
     * Returns true if a placeholder exists for a given ID.
     * @since 3.0
     */
    public boolean hasPlaceholder(String primaryId, String secondaryId) {
        LayoutPart testPart;
        if (secondaryId == null) {
			testPart = findPart(primaryId);
		} else {
			testPart = findPart(primaryId, secondaryId);
		}
        return (testPart != null && testPart instanceof PartPlaceholder);
    }

    /**
     * Returns the layout container.
     */
    public ViewSashContainer getLayout() {
        return mainLayout;
    }

    /**
     * Gets the active state.
     */
    public boolean isActive() {
        return active;
    }

    /**
     * Returns whether the presentation is zoomed.
     */
    public boolean isZoomed() {
    	// New 3.3 behavior
		if (Perspective.useNewMinMax(perspective)) {
			return getMaximizedStack() != null;
		}
		
        return mainLayout.getZoomedPart() != null;
    }

    /**
	 * @return The currently maxmized stack (if any)
	 */
	public PartStack getMaximizedStack() {
		return maximizedStack;
	}

	/**
	 * Sets the currently maximized stack. Used for query
	 * and 'unZoom' purposes in the 3.3 presentation.
	 * 
	 * @param stack The newly maximized stack
	 */
	public void setMaximizedStack(PartStack stack) {
		if (stack == maximizedStack)
			return;
		
		maximizedStack = stack;
	}
	
	/**
     * Returns the ratio that should be used when docking the given source
     * part onto the given target
     * 
     * @param source newly added part
     * @param target existing part being dragged over
     * @return the final size of the source part (wrt the current size of target)
     * after it is docked
     */
    public static float getDockingRatio(LayoutPart source, LayoutPart target) {
        if ((source instanceof ViewPane || source instanceof ViewStack)
                && target instanceof EditorSashContainer) {
            return 0.25f;
        }
        return 0.5f;
    }

    /**
     * Returns whether changes to a part will affect zoom. There are a few
     * conditions for this .. - we are zoomed. - the part is contained in the
     * main window. - the part is not the zoom part - the part is not a fast
     * view - the part and the zoom part are not in the same editor workbook
	 * - the part and the zoom part are not in the same view stack.
     */
    public boolean partChangeAffectsZoom(LayoutPart pane) {
        return pane.isObscuredByZoom();
    }
    
    /**
     * Remove all references to a part.
     */
    public void removePart(LayoutPart part) {

        // Reparent the part back to the main window
        Composite parent = mainLayout.getParent();
        part.reparent(parent);

        // Replace part with a placeholder
        ILayoutContainer container = part.getContainer();
        if (container != null) {
            String placeHolderId = part.getPlaceHolderId();
            container.replace(part, new PartPlaceholder(placeHolderId));

            // If the parent is root we're done. Do not try to replace
            // it with placeholder.
            if (container == mainLayout) {
				return;
			}

            // If the parent is empty replace it with a placeholder.
            LayoutPart[] children = container.getChildren();
            if (children != null) {
                boolean allInvisible = true;
                for (int i = 0, length = children.length; i < length; i++) {
                    if (!(children[i] instanceof PartPlaceholder)) {
                        allInvisible = false;
                        break;
                    }
                }
                if (allInvisible && (container instanceof LayoutPart)) {
                    // what type of window are we in?
                    LayoutPart cPart = (LayoutPart) container;
                    //Window oldWindow = cPart.getWindow();
                    boolean wasDocked = cPart.isDocked();
                    Shell oldShell = cPart.getShell();
                    if (wasDocked) {
                        
                        // PR 1GDFVBY: ViewStack not disposed when page
                        // closed.
                        if (container instanceof ViewStack) {
							((ViewStack) container).dispose();
						}
                        
                        // replace the real container with a
                        // ContainerPlaceholder
                        ILayoutContainer parentContainer = cPart.getContainer();
                        ContainerPlaceholder placeholder = new ContainerPlaceholder(
                                cPart.getID());
                        placeholder.setRealContainer(container);
                        parentContainer.replace(cPart, placeholder);
                        
                    } else {
                        DetachedPlaceHolder placeholder = new DetachedPlaceHolder(
                                "", oldShell.getBounds()); //$NON-NLS-1$
                        for (int i = 0, length = children.length; i < length; i++) {
                            children[i].getContainer().remove(children[i]);
                            children[i].setContainer(placeholder);
                            placeholder.add(children[i]);
                        }
                        detachedPlaceHolderList.add(placeholder);
                        DetachedWindow w = (DetachedWindow)oldShell.getData();
                        oldShell.close();
                        detachedWindowList.remove(w);
                    }
                }
            }
        }
    }

    /**
     * Add a part to the presentation.
     * 
     * Note: unlike all other LayoutParts, PartPlaceholders will still point to
     * their parent container even when it is inactive. This method relies on this
     * fact to locate the parent.
     */
    public void replacePlaceholderWithPart(LayoutPart part) {
        
        // Look for a PartPlaceholder that will tell us how to position this
        // object
        PartPlaceholder[] placeholders = collectPlaceholders();
        for (int i = 0, length = placeholders.length; i < length; i++) {
            if (placeholders[i].getCompoundId().equals(part.getCompoundId())) {
                // found a matching placeholder which we can replace with the
                // new View
                ILayoutContainer container = placeholders[i].getContainer();
                if (container != null) {
                    if (container instanceof ContainerPlaceholder) {
                        // One of the children is now visible so replace the
                        // ContainerPlaceholder with the real container
                        ContainerPlaceholder containerPlaceholder = (ContainerPlaceholder) container;
                        ILayoutContainer parentContainer = containerPlaceholder
                                .getContainer();
                        container = (ILayoutContainer) containerPlaceholder
                                .getRealContainer();
                        if (container instanceof LayoutPart) {
                            parentContainer.replace(containerPlaceholder,
                                    (LayoutPart) container);
                        }
                        containerPlaceholder.setRealContainer(null);
                    }
                    container.replace(placeholders[i], part);
                    return;
                }
            }
        }

    }

    /**
     * @see org.eclipse.ui.IPersistable
     */
    public IStatus restoreState(IMemento memento) {
        // Restore main window.
        IMemento childMem = memento
                .getChild(IWorkbenchConstants.TAG_MAIN_WINDOW);
        IStatus r = mainLayout.restoreState(childMem);

        // Restore each floating window.
        if (detachable) {
            IMemento detachedWindows[] = memento
                    .getChildren(IWorkbenchConstants.TAG_DETACHED_WINDOW);
            for (int nX = 0; nX < detachedWindows.length; nX++) {
                DetachedWindow win = new DetachedWindow(page);
                detachedWindowList.add(win);
                win.restoreState(detachedWindows[nX]);
            }
            IMemento childrenMem[] = memento
                    .getChildren(IWorkbenchConstants.TAG_HIDDEN_WINDOW);
            for (int i = 0, length = childrenMem.length; i < length; i++) {
                DetachedPlaceHolder holder = new DetachedPlaceHolder(
                        "", new Rectangle(0, 0, 0, 0)); //$NON-NLS-1$
                holder.restoreState(childrenMem[i]);
                detachedPlaceHolderList.add(holder);
            }
        }
        
        // Get the cached id of the currently maximized stack
        maximizedStackId = childMem.getString(IWorkbenchConstants.TAG_MAXIMIZED);
        
        return r;
    }

    /**
     * @see org.eclipse.ui.IPersistable
     */
    public IStatus saveState(IMemento memento) {
        // Persist main window.
        IMemento childMem = memento
                .createChild(IWorkbenchConstants.TAG_MAIN_WINDOW);
        IStatus r = mainLayout.saveState(childMem);

        if (detachable) {
            // Persist each detached window.
            for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
                DetachedWindow window = (DetachedWindow) detachedWindowList
                        .get(i);
                childMem = memento
                        .createChild(IWorkbenchConstants.TAG_DETACHED_WINDOW);
                window.saveState(childMem);
            }
            for (int i = 0, length = detachedPlaceHolderList.size(); i < length; i++) {
                DetachedPlaceHolder holder = (DetachedPlaceHolder) detachedPlaceHolderList
                        .get(i);
                childMem = memento
                        .createChild(IWorkbenchConstants.TAG_HIDDEN_WINDOW);
                holder.saveState(childMem);
            }
        }
        
        // Write out the id of the maximized (View) stack (if any)
        // NOTE: we only write this out if it's a ViewStack since the
        // Editor Area is handled by the perspective
        if (maximizedStack instanceof ViewStack) {
        	childMem.putString(IWorkbenchConstants.TAG_MAXIMIZED, maximizedStack.getID());
        }
        else if (maximizedStackId != null) {
        	// Maintain the cache if the perspective has never been activated
        	childMem.putString(IWorkbenchConstants.TAG_MAXIMIZED, maximizedStackId);        	
        }
        
        return r;
    }

    /**
     * Zoom in on a particular layout part.
     */
    public void zoomIn(IWorkbenchPartReference ref) {
        PartPane pane = ((WorkbenchPartReference) ref).getPane();


        parentWidget.setRedraw(false);
        try {
            pane.requestZoomIn();
        } finally {
            parentWidget.setRedraw(true);
        }
    }

    /**
     * Zoom out.
     */
    public void zoomOut() {
    	// New 3.3 behavior
		if (Perspective.useNewMinMax(perspective)) {
			 if (maximizedStack != null)
				 maximizedStack.setState(IStackPresentationSite.STATE_RESTORED);
			 return;
		}
		
        LayoutPart zoomPart = mainLayout.getZoomedPart();
        if (zoomPart != null) {
            zoomPart.requestZoomOut();
        }
    }

    /**
     * Forces the perspective to have no zoomed or minimized parts.
     * This is used when switching to the 3.3 presentation...
     */
    public void forceNoZoom() {
    	// Ensure that nobody's zoomed
    	zoomOut();
    	
    	// Now, walk the layout ensuring that nothing is minimized
    	LayoutPart[] kids = mainLayout.getChildren();
    	for (int i = 0; i < kids.length; i++) {
			if (kids[i] instanceof ViewStack) {
				((ViewStack)kids[i]).setMinimized(false);
			}
			else if (kids[i] instanceof EditorSashContainer) {
				LayoutPart[] editorStacks = ((EditorSashContainer)kids[i]).getChildren();
				for (int j = 0; j < editorStacks.length; j++) {
					if (editorStacks[j] instanceof EditorStack) {
						((EditorStack)editorStacks[j]).setMinimized(false);
					}
				}
			}
		}
    }

    /**
     * Captures the current bounds of all ViewStacks and the editor
     * area and puts them into an ID -> Rectangle map. This info is
     * used to cache the bounds so that we can correctly place minimized
     * stacks during a 'maximized' operation (where the iterative min's
     * affect the current layout while being performed.
     */
    public void updateBoundsMap() {
    	boundsMap.clear();
    	
    	// Walk the layout gathering the current bounds of each stack
    	// and the editor area
    	LayoutPart[] kids = mainLayout.getChildren();
    	for (int i = 0; i < kids.length; i++) {
			if (kids[i] instanceof ViewStack) {
				ViewStack vs = (ViewStack)kids[i];
				boundsMap.put(vs.getID(), vs.getBounds());
			}
			else if (kids[i] instanceof EditorSashContainer) {
				EditorSashContainer esc = (EditorSashContainer)kids[i];
				boundsMap.put(esc.getID(), esc.getBounds());
			}
		}
    }

	/**
	 * Resets the bounds map so that it won't interfere with normal minimize
	 * operayions
	 */
	public void resetBoundsMap() {
		boundsMap.clear();
	}
	
	public Rectangle getCachedBoundsFor(String id) {
		return (Rectangle) boundsMap.get(id);
	}
}
