/*******************************************************************************
 * 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 java.util.*;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.ui.*;
import org.eclipse.ui.part.MultiEditor;

/**
 * EditorPresentation is a wrapper for PartTabworkbook.
 */
public class EditorPresentation {
	private WorkbenchPage page;
	private ArrayList editorTable = new ArrayList(4);
	private EditorArea editorArea;
/**
 * Creates a new EditorPresentation.
 */
public EditorPresentation(WorkbenchPage page) {
	IPartDropListener partDropListener = new IPartDropListener() {
		public void dragOver(PartDropEvent e) {
			onPartDragOver(e);
		};
		public void drop(PartDropEvent e){
			onPartDrop(e);
		};
	};
	
	this.page = page;
	this.editorArea = new EditorArea(IPageLayout.ID_EDITOR_AREA, partDropListener, page);
}
/**
 * Closes all of the editors.
 */
public void closeAllEditors() {
	editorArea.removeAllEditors();
	ArrayList editorsToDispose = (ArrayList) editorTable.clone();
	editorTable.clear();
	for (int i = 0; i < editorsToDispose.size(); i++){
		((EditorPane)editorsToDispose.get(i)).dispose();
	}	
}
/**
 * Closes an editor.   
 *
 * @param part the editor to close
 */
public void closeEditor(IEditorReference ref) {
	EditorPane pane = (EditorPane)((WorkbenchPartReference)ref).getPane();
	closeEditor(pane);
}
/**
 * Closes an editor.   
 *
 * @param part the editor to close
 */
public void closeEditor(IEditorPart part) {
	EditorPane pane = (EditorPane)((PartSite)part.getEditorSite()).getPane();
	closeEditor(pane);
}
/**
 * Closes an editor.   
 *
 * @param part the editor to close
 */
private void closeEditor(EditorPane pane) {
	if (pane != null) {
		if (!(pane instanceof MultiEditorInnerPane))
			editorArea.removeEditor(pane);
		editorTable.remove(pane);
		pane.dispose();
	}
}
/**
 * Deref a given part.  Deconstruct its container as required.
 * Do not remove drag listeners.
 */
private void derefPart(LayoutPart part) {
	// Get vital part stats before reparenting.
	ILayoutContainer oldContainer = part.getContainer();
	
	// Reparent the part back to the main window
	part.reparent(editorArea.getParent());
	// Update container.
	if (oldContainer == null) 
		return;
	oldContainer.remove(part);
	LayoutPart[] children = oldContainer.getChildren();
	if (children == null || children.length == 0){
		// 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();
			}
		}
	}
}
/**
 * Dispose of the editor presentation. 
 */
public void dispose() {
	if (editorArea != null) {
		editorArea.dispose();
	}
}
/**
 * @see IEditorPresentation
 */
public String getActiveEditorWorkbookID() {
	return editorArea.getActiveWorkbookID();
}
/**
 * Returns an array of the open editors.
 *
 * @return an array of open editors
 */
public IEditorReference[] getEditors() {
	int nSize = editorTable.size();
	IEditorReference [] retArray = new IEditorReference[nSize];
	for (int i = 0; i < retArray.length; i++){
		retArray[i] = ((EditorPane)editorTable.get(i)).getEditorReference();
	}
	return retArray;
}
/**
 * Returns the editor area.
 */
public LayoutPart getLayoutPart() {
	return editorArea;
}
/**
 * Returns the active editor in this perspective.  If the editors appear
 * in a workbook this will be the visible editor.  If the editors are
 * scattered around the workbench this will be the most recent editor
 * to hold focus.
 *
 * @return the active editor, or <code>null</code> if no editor is active
 */
public IEditorReference getVisibleEditor() {
	EditorWorkbook activeWorkbook = editorArea.getActiveWorkbook();
	EditorPane pane = activeWorkbook.getVisibleEditor();
	if (pane != null) {
		IEditorReference result = pane.getEditorReference();
		IEditorPart editorPart = (IEditorPart)result.getPart(false);
		if((editorPart != null) && (editorPart instanceof MultiEditor)) {
			editorPart = ((MultiEditor)editorPart).getActiveEditor();
			EditorSite site = (EditorSite)editorPart.getSite();
			result = (IEditorReference)site.getPane().getPartReference();
		}
		return result;
	}
	return null;
}
/**
 * The active editor has failed to be restored. Find another editor, restore it
 * and make it visible.
 */
public void fixVisibleEditor() {
	EditorWorkbook activeWorkbook = editorArea.getActiveWorkbook();
	EditorPane pane = activeWorkbook.getVisibleEditor();
	if(pane == null) {
		LayoutPart editors[] = activeWorkbook.getChildren();
		if(editors.length > 0)
			pane = (EditorPane)editors[0];
	}
	if(pane != null) {
		IEditorReference result = pane.getEditorReference();
		IEditorPart editorPart = (IEditorPart)result.getPart(true);
		if(editorPart != null)
			activeWorkbook.setVisibleEditor(pane);
	}
}

public void moveEditor(IEditorPart part,int position) {
	EditorPane pane = (EditorPane)((EditorSite)part.getSite()).getPane();
	pane.getWorkbook().reorderTab(pane,position);
}
/**
 * Move a part from one position to another.
 * This implementation assumes the target is
 * an editor workbook. 
 */
private void movePart(LayoutPart part, int position, EditorWorkbook relativePart) {
	EditorArea sashContainer = relativePart.getEditorArea();
	if (sashContainer == null)
		return;
		
	// Remove the part from the current container.
	derefPart(part);
	// Add the part.
	int relativePosition = IPageLayout.LEFT;
	if (position == PartDragDrop.RIGHT)
		relativePosition = IPageLayout.RIGHT;
	else if (position == PartDragDrop.TOP)
		relativePosition = IPageLayout.TOP;
	else if (position == PartDragDrop.BOTTOM)
		relativePosition = IPageLayout.BOTTOM;
	if (part instanceof EditorWorkbook) {
		sashContainer.add(part, relativePosition, (float) 0.5, relativePart);
		((EditorWorkbook)part).becomeActiveWorkbook(true);
	}
	else {
		EditorWorkbook newWorkbook = new EditorWorkbook(editorArea);
		sashContainer.add(newWorkbook, relativePosition, (float) 0.5, relativePart);
		newWorkbook.add(part);
		newWorkbook.becomeActiveWorkbook(true);
	}
}
/**
 * Notification sent during drag and drop operation.
 * Only allow editors and editor workbooks to participate
 * in the drag. Only allow the drop on an editor workbook
 * within the same editor area.
 */
private void onPartDragOver(PartDropEvent e) {
	// If source and target are in different windows reject.
	if (e.dragSource != null && e.dropTarget != null) {
		if (e.dragSource.getWorkbenchWindow() != e.dropTarget.getWorkbenchWindow()) {
			e.relativePosition = PartDragDrop.INVALID;
			return;
		}
	}	
	
	// can't detach editor into its own window
	if (/*!detachable &&*/ e.relativePosition == PartDragDrop.OFFSCREEN){
		e.relativePosition = PartDragDrop.INVALID;
		return;
	}
	// can't drop unless over an editor workbook
	if (!(e.dropTarget instanceof EditorWorkbook)) {
		e.relativePosition = PartDragDrop.INVALID;
		return;
	}
	// handle drag of an editor
	if (e.dragSource instanceof EditorPane) {
		EditorWorkbook sourceWorkbook = ((EditorPane)e.dragSource).getWorkbook();
		// limitations when drop is over editor's own workbook
		if (sourceWorkbook == e.dropTarget) {
			// can't stack/detach/attach from same workbook when only one editor
			if (sourceWorkbook.getItemCount() == 1) {
				e.relativePosition = PartDragDrop.INVALID;
				return;
			}
		}
		
		// can't drop into another editor area
		EditorWorkbook targetWorkbook = (EditorWorkbook)e.dropTarget;
		if (sourceWorkbook.getEditorArea() != targetWorkbook.getEditorArea()) {
			e.relativePosition = PartDragDrop.INVALID;
			return;
		}
		// all seems well
		return;
	}
	// handle drag of an editor workbook
	if (e.dragSource instanceof EditorWorkbook) {
		// can't attach nor stack in same workbook
		if (e.dragSource == e.dropTarget) {
			e.relativePosition = PartDragDrop.INVALID;
			return;
		}
		// can't drop into another editor area
		EditorWorkbook sourceWorkbook = (EditorWorkbook)e.dragSource;
		EditorWorkbook targetWorkbook = (EditorWorkbook)e.dropTarget;
		if (sourceWorkbook.getEditorArea() != targetWorkbook.getEditorArea()) {
			e.relativePosition = PartDragDrop.INVALID;
			return;
		}
		
		// all seems well
		return;
	}
	// invalid case - do not allow a drop to happen
	e.relativePosition = PartDragDrop.INVALID;
}
/**
 * Notification sent when drop happens. Only editors
 * and editor workbooks were allowed to participate.
 * Only an editor workbook in the same editor area as
 * the drag started can accept the drop.
 */
private void onPartDrop(PartDropEvent e) {
	switch (e.relativePosition) {
		case PartDragDrop.OFFSCREEN:
			// This case is not supported and should never
			// happen. See onPartDragOver
			//detach(e.dragSource, e.x, e.y);
			break;
		case PartDragDrop.CENTER:
			if (e.dragSource instanceof EditorPane) {
				EditorWorkbook sourceWorkbook = ((EditorPane)e.dragSource).getWorkbook();
				if (sourceWorkbook == e.dropTarget) {
					sourceWorkbook.reorderTab((EditorPane)e.dragSource, e.cursorX, e.cursorY);
					break;
				}
			}
			stack(e.dragSource, (EditorWorkbook)e.dropTarget);
			break;
		case PartDragDrop.LEFT:
		case PartDragDrop.RIGHT:
		case PartDragDrop.TOP:
		case PartDragDrop.BOTTOM:
			if (page.isZoomed())
				page.zoomOut();
			movePart(e.dragSource, e.relativePosition, (EditorWorkbook)e.dropTarget);
			break;
	}
}
/**
 * Opens an editor within the presentation.  
 * </p>
 * @param part the editor
 */
public void openEditor(IEditorReference ref,IEditorReference[] innerEditors, boolean setVisible) {
	EditorPane pane = new MultiEditorOuterPane(ref, page, editorArea.getActiveWorkbook());
	initPane(pane,ref);
	for (int i = 0; i < innerEditors.length; i++) {
		EditorPane innerPane = new MultiEditorInnerPane(pane,innerEditors[i], page, editorArea.getActiveWorkbook());
		initPane(innerPane,innerEditors[i]);
	}
	// Show the editor.
	editorArea.addEditor(pane);
	if(setVisible)
		setVisibleEditor(ref, true);
}
/**
 * Opens an editor within the presentation.  
 * </p>
 * @param part the editor
 */
public void openEditor(IEditorReference ref,boolean setVisible) {
	
	EditorPane pane = new EditorPane(ref, page, editorArea.getActiveWorkbook());
	initPane(pane,ref);
	
	// Show the editor.
	editorArea.addEditor(pane);
	if(setVisible)
		setVisibleEditor(ref, true);
}
private EditorPane initPane(EditorPane pane, IEditorReference ref) {
	((WorkbenchPartReference)ref).setPane(pane);
	// Record the new editor.
	editorTable.add(pane);
	return pane;
}
/**
 * @see IPersistablePart
 */
public IStatus restoreState(IMemento memento) {
	// Restore the editor area workbooks layout/relationship
	return editorArea.restoreState(memento);
}
/**
 * @see IPersistablePart
 */
public IStatus saveState(IMemento memento) {
	// Save the editor area workbooks layout/relationship
	return editorArea.saveState(memento);
}
/**
 * @see IEditorPresentation
 */
public void setActiveEditorWorkbookFromID(String id) {
	editorArea.setActiveWorkbookFromID(id);
}
/**
 * Makes sure the visible editor's tab is visible.
 */
public void showVisibleEditor() {
	EditorWorkbook activeWorkbook = editorArea.getActiveWorkbook();
	if(activeWorkbook != null)
		activeWorkbook.showVisibleEditor();
}
/**
 * Brings an editor to the front and gives it focus.
 *
 * @param part the editor to make visible
 * @param setFocus whether to give the editor focus
 * @return true if the active editor was changed, false if not.
 */
public boolean setVisibleEditor(IEditorReference ref, boolean setFocus) {
	IEditorReference visibleEditor = getVisibleEditor();
	if (ref != visibleEditor) {
		IEditorPart part = (IEditorPart)ref.getPart(true);
		EditorPane pane = null;
		if(part != null)
			pane = (EditorPane)((PartSite)part.getEditorSite()).getPane();
		if (pane != null) {
			if(pane instanceof MultiEditorInnerPane) {
				EditorPane parentPane = ((MultiEditorInnerPane)pane).getParentPane();
				EditorWorkbook activeWorkbook = parentPane.getWorkbook();
				EditorPane activePane = activeWorkbook.getVisibleEditor();
				if(activePane != parentPane)
					parentPane.getWorkbook().setVisibleEditor(parentPane);
				else
					return false;
			} else {
				pane.getWorkbook().setVisibleEditor(pane);
			}
			if (setFocus)
				part.setFocus();
			return true;
		}
	}
	return false;
}
private void stack(LayoutPart newPart, EditorWorkbook refPart) {
	editorArea.getControl().setRedraw(false);
	if (newPart instanceof EditorWorkbook) {
		EditorPane visibleEditor = ((EditorWorkbook)newPart).getVisibleEditor();
		LayoutPart[] children = ((EditorWorkbook)newPart).getChildren();
		for (int i = 0; i < children.length; i++)
			stackEditor((EditorPane)children[i], refPart);
		if (visibleEditor != null) {
			visibleEditor.setFocus();
			refPart.becomeActiveWorkbook(true);
			refPart.setVisibleEditor(visibleEditor);
		}
	}
	else {
		stackEditor((EditorPane)newPart, refPart);
		newPart.setFocus();
		refPart.becomeActiveWorkbook(true);
		refPart.setVisibleEditor((EditorPane)newPart);
	}
	editorArea.getControl().setRedraw(true);
}
private void stackEditor(EditorPane newPart, EditorWorkbook refPart) {
	// Remove the part from old container.
	derefPart(newPart);
	// Reparent part and add it to the workbook
	newPart.reparent(refPart.getParent());
	refPart.add(newPart);
}
/**
 * Method getWorkbooks.
 * @return ArrayList
 */
public ArrayList getWorkbooks() {
	return editorArea.getEditorWorkbooks();
}
/**
 * Open the list of editors
 */
public void openEditorList() {
		editorArea.getActiveWorkbook().openEditorList();
}
}
