/*******************************************************************************
 * Copyright (c) 2000, 2003 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;


import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.SafeRunnable;
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.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.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.misc.UIStats;
import org.eclipse.ui.part.WorkbenchPart;


/**
 * Provides the common behavior for both views
 * and editor panes.
 */
public abstract class PartPane extends LayoutPart
	implements Listener
{
	public static final String PROP_ZOOMED = "zoomed"; //$NON-NLS-1$
	private boolean isZoomed = false;
	private MenuManager paneMenuManager;
	protected IWorkbenchPartReference partReference;
	protected WorkbenchPage page;
	protected Composite control;
	
	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;
	((WorkbenchPartReference)partReference).setPane(this);
}
/**
 * Factory method for creating the SWT Control hierarchy for this Pane's child.
 */
protected void createChildControl() {
	final IWorkbenchPart part[] = new IWorkbenchPart[]{partReference.getPart(false)};
	if(part[0] == null)
		return;

	if(control == null)
		return;
	
	final Composite content = new Composite(control, SWT.NONE);
	content.setLayout(new FillLayout());
	
	String error = WorkbenchMessages.format("PartPane.unableToCreate", new Object[] {partReference.getTitle()}); //$NON-NLS-1$
	Platform.run(new SafeRunnable(error) {
		public void run() {
			try {
				UIStats.start(UIStats.CREATE_PART_CONTROL,id);
				part[0].createPartControl(content);
			} finally {
				UIStats.end(UIStats.CREATE_PART_CONTROL,id);
			}
		}
		public void handleException(Throwable e) {
			// Log error.
			Workbench wb = (Workbench)PlatformUI.getWorkbench();
			if (!wb.isStarting())
				super.handleException(e);

			// Dispose old part.
			Control children[] = content.getChildren();
			for (int i = 0; i < children.length; i++){
				children[i].dispose();
			}
			
			// Create new part.
			IWorkbenchPart newPart = createErrorPart((WorkbenchPart)part[0]);
			part[0].getSite().setSelectionProvider(null);
			newPart.createPartControl(content);
			((WorkbenchPartReference)partReference).setPart(newPart);
			part[0] = newPart;
		}
	});
	page.addPart(partReference);
	page.firePartOpened(part[0]);	
}

public void addSizeMenuItem (Menu menu, int index) {
	//Add size menu
	MenuItem item = new MenuItem(menu, SWT.CASCADE, index);
	item.setText(WorkbenchMessages.getString("PartPane.size")); //$NON-NLS-1$
	Menu sizeMenu = new Menu(menu);
	item.setMenu(sizeMenu);
	addSizeItems(sizeMenu);
}

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

	// 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);

	// Create a title bar.
	createTitleBar();

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

protected abstract WorkbenchPart createErrorPart(WorkbenchPart oldPart);
/**
 * 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.dispose();
		control = null;
	}
	if ((paneMenuManager != null)) {
		paneMenuManager.dispose();	
		paneMenuManager = null;
	}
}
/**
 * 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 (getWindow() instanceof IWorkbenchWindow)
		page.toggleZoom(partReference);
}
/**
 * Gets the presentation bounds.
 */
public Rectangle getBounds() {
	return getControl().getBounds();
}
/**
 * Get the control.
 */
public Control getControl() {
	return control;
}

/*
 * @see LayoutPart#getMinimumHeight()
 */
public int getMinimumHeight() {
	if (control == null || control.isDisposed())
		return super.getMinimumHeight();
	
	// account for the borders
	return control.computeTrim(0, 0, 0, 0).height;
}

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

/**
 * @see Listener
 */
public void handleEvent(Event event) {
	if (event.type == SWT.Activate)
		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.
 */
protected void requestActivation() {
	this.page.requestActivation(partReference.getPart(true));
}
/**
 * Sets the parent for this part.
 */
public void setContainer(ILayoutContainer container) {
	super.setContainer(container);
}

/**
 * Shows the receiver if <code>visible</code> is true otherwise hide it.
 */
public void setVisible(boolean makeVisible) {
	super.setVisible(makeVisible);
	if(makeVisible) //Make sure that the part is restored.
		partReference.getPart(true);
}
/**
 * Sets focus to this part.
 */
public void setFocus() {
	requestActivation();
	IWorkbenchPart part = partReference.getPart(true);
	if (part != null) {
		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;
	
	final Object[] listeners = getPropertyListeners().getListeners();
	if (listeners.length > 0) {
		Boolean oldValue = isZoomed ? Boolean.FALSE : Boolean.TRUE;
		Boolean zoomed = isZoomed ? Boolean.TRUE : Boolean.FALSE;
		PropertyChangeEvent event = new PropertyChangeEvent(this, PROP_ZOOMED, oldValue, zoomed);
		for (int i = 0; i < listeners.length; ++i)
			((IPropertyChangeListener)listeners[i]).propertyChange(event);
	}
}
/**
 * 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;
}

/**
 * Show a title label menu for this pane.
 */
public abstract void showPaneMenu();
/**
 * Show the context menu for this part.
 */
public abstract void showViewMenu();

/**
 * Return the sashes around this part.
 */
protected abstract Sashes findSashes();
/**
 * 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); //$NON-NLS-1$
	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.getString("PartPane.sizeLeft"), sashes.left); //$NON-NLS-1$
    addSizeItem(sizeMenu,
            WorkbenchMessages.getString("PartPane.sizeRight"), sashes.right); //$NON-NLS-1$
    addSizeItem(sizeMenu,
            WorkbenchMessages.getString("PartPane.sizeTop"), sashes.top); //$NON-NLS-1$
    addSizeItem(sizeMenu,
            WorkbenchMessages.getString("PartPane.sizeBottom"), sashes.bottom); //$NON-NLS-1$
}


/**
 * 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
}

/**
 * Ensure that we are not in the zoomed before reparenting.
 * TODO: I am certain this isn't correct but I'll be damned if I know what is.
 */
public void reparent(Composite newParent) {
    if (isZoomed())
        setZoomed(false);
    super.reparent(newParent);
}
}
