/*******************************************************************************
 * 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.ui.internal;

import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
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.MenuItem;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.internal.dnd.SwtUtil;
import org.eclipse.ui.part.MultiEditor;

/**
 * Provides the common behavior for both views
 * and editor panes.
 * 
 * TODO: Delete ViewPane and EditorPane, and make this class non-abstract.
 * 
 * TODO: Stop subclassing LayoutPart. This class cannot be interchanged with other LayoutParts.
 * Pointers that refer to PartPane instances should do so directly rather than referring to
 * LayoutPart and downcasting. The getPresentablePart() method only applies to PartPanes, and
 * should be removed from LayoutPart.
 */
public abstract class PartPane extends LayoutPart implements IPropertyListener, Listener {

    public static final String PROP_ZOOMED = "zoomed"; //$NON-NLS-1$

    private boolean isZoomed = false;

    private MenuManager paneMenuManager;
    private ListenerList listeners = new ListenerList();

    protected IWorkbenchPartReference partReference;

    protected WorkbenchPage page;

    protected Composite control;

    private boolean inLayout = true;
    
    private TraverseListener traverseListener = new TraverseListener() {
        /* (non-Javadoc)
         * @see org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent)
         */
        public void keyTraversed(TraverseEvent e) {
            // Hack: Currently, SWT sets focus whenever we call Control.traverse. This doesn't
            // cause too much of a problem for ctrl-pgup and ctrl-pgdn, but it is seriously unexpected
            // for other traversal events. When (and if) it becomes possible to call traverse() without
            // forcing a focus change, this if statement should be removed and ALL events should be
            // forwarded to the container.
            if (e.detail == SWT.TRAVERSE_PAGE_NEXT
                    || e.detail == SWT.TRAVERSE_PAGE_PREVIOUS) {
                ILayoutContainer container = getContainer();
                if (container != null && container instanceof LayoutPart) {
                    LayoutPart parent = (LayoutPart) container;
                    Control parentControl = parent.getControl();
                    if (parentControl != null && !parentControl.isDisposed()) {
                        e.doit = parentControl.traverse(e.detail);
                        if (e.doit) {
							e.detail = SWT.TRAVERSE_NONE;
						}
                    }
                }
            }
        }

    };

    public static class Sashes {
        public Sash left;

        public Sash right;

        public Sash top;

        public Sash bottom;
    }

    /**
     * Construct a pane for a part.
     */
    public PartPane(IWorkbenchPartReference partReference,
            WorkbenchPage workbenchPage) {
        super(partReference.getId());
        this.partReference = partReference;
        this.page = workbenchPage;
    }

    public void addSizeMenuItem(Menu menu, int index) {
        //Add size menu
        MenuItem item = new MenuItem(menu, SWT.CASCADE, index);
        item.setText(WorkbenchMessages.PartPane_size);
        Menu sizeMenu = new Menu(menu);
        item.setMenu(sizeMenu);
        addSizeItems(sizeMenu);
    }

    /**
     * 
     */
    public void createControl(Composite parent) {
        if (getControl() != null) {
			return;
		}

        partReference.addPropertyListener(this);
        // Create view form.	
        control = new Composite(parent, SWT.NONE);
        control.setLayout(new FillLayout());
        // the part should never be visible by default.  It will be made visible 
        // by activation.  This allows us to have views appear in tabs without 
        // becoming active by default.
        control.setVisible(false);
        control.moveAbove(null);
        // Create a title bar.
        createTitleBar();

        
        // When the pane or any child gains focus, notify the workbench.
        control.addListener(SWT.Activate, this);

        control.addTraverseListener(traverseListener);
    }

    /**
     * Create a title bar for the pane if required.
     */
    protected abstract void createTitleBar();

    /**
     * @private
     */
    public void dispose() {
        super.dispose();

        if ((control != null) && (!control.isDisposed())) {
            control.removeListener(SWT.Activate, this);
            control.removeTraverseListener(traverseListener);
            control.dispose();
            control = null;
        }
        if ((paneMenuManager != null)) {
            paneMenuManager.dispose();
            paneMenuManager = null;
        }
        
        partReference.removePropertyListener(this);
    }

    /**
     * User has requested to close the pane.
     * Take appropriate action depending on type.
     */
    abstract public void doHide();

    /**
     * Zooms in on the part contained in this pane.
     */
    protected void doZoom() {
        if (isDocked()) {
			page.toggleZoom(partReference);
		}
    }

    /**
     * Gets the presentation bounds.
     */
    public Rectangle getBounds() {
        return getControl().getBounds();
    }

    /**
     * Get the control.
     */
    public Control getControl() {
        return control;
    }

    /**
     * Answer the part child.
     */
    public IWorkbenchPartReference getPartReference() {
        return partReference;
    }

    /**
     * @see Listener
     */
    public void handleEvent(Event event) {
        if (event.type == SWT.Activate) {
            if (inLayout) {
                requestActivation();
            }
        }
    }

    /**
     * Return whether the pane is zoomed or not
     */
    public boolean isZoomed() {
        return isZoomed;
    }

    /**
     * Move the control over another one.
     */
    public void moveAbove(Control refControl) {
        if (getControl() != null) {
			getControl().moveAbove(refControl);
		}
    }

    /**
     * Notify the workbook page that the part pane has
     * been activated by the user.
     */
    public void requestActivation() {
        IWorkbenchPart part = partReference.getPart(true);
        // Cannot activate the outer bit of a MultiEditor. In previous versions of the 
        // workbench, MultiEditors had their own implementation of EditorPane for the purpose
        // of overriding requestActivation with a NOP... however, keeping the old pattern would
        // mean it is necessary to eagerly activate an editor's plugin in order to determine
        // what type of pane to create.
        if (part instanceof MultiEditor) {
            return;
        }
        
        this.page.requestActivation(part);
    }

    /**
     * Sets the parent for this part.
     */
    public void setContainer(ILayoutContainer container) {
        
        if (container instanceof LayoutPart) {
            LayoutPart part = (LayoutPart) container;
            
            Control containerControl = part.getControl();
            
            if (containerControl != null) {
                Control control = getControl();
                Composite newParent = containerControl.getParent();
                if (control != null && newParent != control.getParent()) {
                    reparent(newParent);
                }
            }
        }
        super.setContainer(container);
    }

    /**
     * Shows the receiver if <code>visible</code> is true otherwise hide it.
     */
    public void setVisible(boolean makeVisible) {
        // Avoid redundant visibility changes
        if (makeVisible == getVisible()) {
            return;
        }
        
    	if (makeVisible) {
    	    partReference.getPart(true);
    	}
    	
        super.setVisible(makeVisible);
        
        ((WorkbenchPartReference) partReference).fireVisibilityChange();
    }
    
    /**
     * Sets focus to this part.
     */
    public void setFocus() {
        requestActivation();

        IWorkbenchPart part = partReference.getPart(true);
        if (part != null) {
            Control control = getControl();
            if (!SwtUtil.isFocusAncestor(control)) {
                // First try to call part.setFocus
                part.setFocus();
            }
        }
    }

    /**
     * Sets the workbench page of the view. 
     */
    public void setWorkbenchPage(WorkbenchPage workbenchPage) {
        this.page = workbenchPage;
    }

    /**
     * Set whether the pane is zoomed or not
     */
    public void setZoomed(boolean isZoomed) {
        if (this.isZoomed == isZoomed) {
			return; // do nothing if we're already in the right state.
		}

        super.setZoomed(isZoomed);

        this.isZoomed = isZoomed;

        ((WorkbenchPartReference) partReference).fireZoomChange();        
    }
    
    /**
     * Informs the pane that it's window shell has
     * been activated.
     */
    /* package */abstract void shellActivated();

    /**
     * Informs the pane that it's window shell has
     * been deactivated.
     */
    /* package */abstract void shellDeactivated();

    /**
     * Indicate focus in part.
     */
    public abstract void showFocus(boolean inFocus);

    /**
     * @see IPartDropTarget::targetPartFor
     */
    public LayoutPart targetPartFor(LayoutPart dragSource) {
        return this;
    }

    /**
     * Returns the PartStack that contains this PartPane, or null if none.
     * 
     * @return
     */
    public PartStack getStack() {
        ILayoutContainer container = getContainer();
        if (container instanceof PartStack) {
            return (PartStack) container;
        }

        return null;
    }

    /**
     * Show a title label menu for this pane.
     */
    public void showPaneMenu() {
        PartStack folder = getStack();

        if (folder != null) {
            folder.showPaneMenu();
        }
    }

    /**
     * Show the context menu for this part.
     */
    public void showSystemMenu() {
        PartStack folder = getStack();

        if (folder != null) {
            folder.showSystemMenu();
        }
    }

    /**
     * Finds and return the sashes around this part.
     */
    protected Sashes findSashes() {
        Sashes result = new Sashes();

        ILayoutContainer container = getContainer();

        if (container == null) {
            return result;
        }

        container.findSashes(this, result);
        return result;
    }

    /**
     * Enable the user to resize this part using
     * the keyboard to move the specified sash
     */
    protected void moveSash(final Sash sash) {
        moveSash(sash, this);
    }

    public static void moveSash(final Sash sash,
            final LayoutPart toGetFocusWhenDone) {
        final KeyListener listener = new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if (e.character == SWT.ESC || e.character == '\r') {
                    if (toGetFocusWhenDone != null) {
						toGetFocusWhenDone.setFocus();
					}
                }
            }
        };
        sash.addFocusListener(new FocusAdapter() {
            public void focusGained(FocusEvent e) {
                sash.setBackground(sash.getDisplay().getSystemColor(
                        SWT.COLOR_LIST_SELECTION));
                sash.addKeyListener(listener);
            }

            public void focusLost(FocusEvent e) {
                sash.setBackground(null);
                sash.removeKeyListener(listener);
            }
        });
        sash.setFocus();

    }

    /**
     * Add a menu item to the Size Menu
     */
    protected void addSizeItem(Menu sizeMenu, String labelMessage,
            final Sash sash) {
        MenuItem item = new MenuItem(sizeMenu, SWT.NONE);
        item.setText(labelMessage);
        item.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                moveSash(sash);
            }
        });
        item.setEnabled(!isZoomed() && sash != null);
    }

    /**
     * Returns the workbench page of this pane.
     */
    public WorkbenchPage getPage() {
        return page;
    }

    /**
     * Add the Left,Right,Up,Botton menu items to the Size menu.
     */
    protected void addSizeItems(Menu sizeMenu) {
        Sashes sashes = findSashes();
        addSizeItem(sizeMenu,
                WorkbenchMessages.PartPane_sizeLeft, sashes.left);
        addSizeItem(sizeMenu,
                WorkbenchMessages.PartPane_sizeRight, sashes.right); 
        addSizeItem(sizeMenu,
                WorkbenchMessages.PartPane_sizeTop, sashes.top); 
        addSizeItem(sizeMenu, WorkbenchMessages.PartPane_sizeBottom, sashes.bottom);
    }

    /**
     * Pin this part.
     */
    protected void doDock() {
        // do nothing
    }

    /**
     * Set the busy state of the pane.
     */
    public void setBusy(boolean isBusy) {
        //Do nothing by default
    }

    /**
     * Show a highlight for the receiver if it is 
     * not currently the part in the front of its
     * presentation.
     *
     */
    public void showHighlight() {
        //No nothing by default
    }

    /**
     * @return
     */
    public abstract Control getToolBar();

    /**
     * @return
     */
    public boolean hasViewMenu() {
        return false;
    }

    /**
     * @param location
     */
    public void showViewMenu(Point location) {

    }
    
    public boolean isBusy() {
        return false;
    }

    /**
     * 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 do not need to be translated.
     * 
     * @param buf
     */
    public void describeLayout(StringBuffer buf) {

        IWorkbenchPartReference part = getPartReference();

        if (part != null) {
            buf.append(part.getPartName());
            return;
        }
    }
    
    /**
     * @return
     * @since 3.1
     */
    public abstract boolean isCloseable();
    
    public void setInLayout(boolean inLayout) {
        this.inLayout = inLayout;
    }
    
    public boolean getInLayout() {
        return inLayout;
    }
        
    public boolean allowsAutoFocus() {
        if (!inLayout) {
            return false;
        }
        
        return super.allowsAutoFocus();
    }

    /**
     * Clears all contribution items from the contribution managers (this is done separately
     * from dispose() since it is done after the part is disposed). This is a bit of a hack.
     * Really, the contribution managers should be part of the site, not the PartPane. If these
     * were moved elsewhere, then disposal of the PartPane would be atomic and this method could
     * be removed.
     */
	public void removeContributions() {

	}

    public void addPropertyListener(IPropertyListener listener) {
        listeners.add(listener);
    }

    public void removePropertyListener(IPropertyListener listener) {
        listeners.remove(listener);
    }
 
    public void firePropertyChange(int propertyId) {
        Object listeners[] = this.listeners.getListeners();
        for (int i = 0; i < listeners.length; i++) {
            ((IPropertyListener) listeners[i]).propertyChanged(this, propertyId);
        }
    }

    public void propertyChanged(Object source, int propId) {
        firePropertyChange(propId);
    }
}
