/*******************************************************************************
 * Copyright (c) 2004, 2005 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/

package org.eclipse.jst.jsf.facesconfig.ui.pageflow;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.gef.ContextMenuProvider;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.KeyHandler;
import org.eclipse.gef.KeyStroke;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CommandStackEvent;
import org.eclipse.gef.commands.CommandStackEventListener;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.editparts.ScalableRootEditPart;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.actions.DeleteAction;
import org.eclipse.gef.ui.actions.GEFActionConstants;
import org.eclipse.gef.ui.actions.RedoAction;
import org.eclipse.gef.ui.actions.SelectionAction;
import org.eclipse.gef.ui.actions.StackAction;
import org.eclipse.gef.ui.actions.UndoAction;
import org.eclipse.gef.ui.actions.UpdateAction;
import org.eclipse.gef.ui.actions.ZoomInAction;
import org.eclipse.gef.ui.actions.ZoomOutAction;
import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.gef.ui.parts.SelectionSynchronizer;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.TransferDropTargetListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.jsf.facesconfig.ui.EditorPlugin;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.action.AlignmentAction;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.action.OpenEditorAction;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.action.ShowPropertyViewAction;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.command.PreExecuteCommandStack;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.ConfigurableRootEditPart;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.IConnectionPreference;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.IFigurePreference;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.ILayerPanePreference;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.INodePreference;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.PageflowEditPartsFactory;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.PageflowNodeEditPart;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.Pageflow;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.PageflowPage;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.synchronization.FC2PFTransformer;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.util.EditPartMarkerUtil;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.util.PageflowAnnotationUtil;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.util.PageflowModelManager;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.util.PageflowResourceFactory;
import org.eclipse.jst.jsf.facesconfig.ui.preference.GEMPreferences;
import org.eclipse.jst.jsf.facesconfig.ui.util.WebrootUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.PropertySheetPage;

/**
 * This the the main editor page for modifying a complete pageflow.
 */
public class PageflowEditor extends GraphicalEditorWithFlyoutPalette implements
		IAdaptable, IPropertyChangeListener, IGotoMarker {
	/** log instance */
	private static final Logger log = EditorPlugin
			.getLogger(PageflowEditor.class);

	/** pageflow context menu registration ID */
	private static final String PAGEFLOW_CONTEXTMENU_REG_ID = ".pageflow.editor.contextmenu";

	/** the edit domain */
	private final DefaultEditDomain domain;

	/** the palette root */
	private PaletteRoot paletteRoot = null;

	/** the parent multi-page editor */
	private IEditorPart parentEditor = null;

	/** the graphical viewer */
	private GraphicalViewer viewer = null;

	/** the undoable <code>IPropertySheetPage</code> */
	private PropertySheetPage undoablePropertySheetPage = null;

	/** the editor's action registry */
	private ActionRegistry actionRegistry = null;

	/**
	 * The id of the editor page
	 */
	public static final String PAGE_ID = "org.eclipse.jst.jsf.facesconfig.ui.pageflow.PageflowEditor";

	/** the list of action ids that are to EditPart actions */
	private List editPartActionIDs = new ArrayList();

	/** the selection listener */
	private ISelectionListener selectionListener = new ISelectionListener() {
		public void selectionChanged(IWorkbenchPart part, ISelection selection) {
			updateActions();
		}
	};

	/** the selection synchronizer for the edit part viewer */
	private SelectionSynchronizer synchronizer = null;

	/** the shared key handler */
	private KeyHandler sharedKeyHandler = null;

	/** pageflow model manager */
	private PageflowModelManager pageflowManager;

	/** the dirty status of this page */
	private boolean isDirty = false;

	/** the command stack of this page */
	private CommandStack commandStack;

	private FC2PFTransformer modelsTransform;

	List stackActions = new ArrayList();

	/**
	 * @return the faces-config to pageflow model
	 */
	public FC2PFTransformer getModelsTransform() {
		if (modelsTransform == null) {
			modelsTransform = new FC2PFTransformer();
		}
		return modelsTransform;
	}

	/**
	 * update the editor actions
	 */
	public void updateActions() {
		updateActions(stackActions);
		updateActions(editPartActionIDs);
	}

	/**
	 * This class listens for command stack changes of the page and decides if
	 * the editor is dirty or not.
	 * 
	 */
	private class PageCommandStackListener implements CommandStackEventListener {
		public void stackChanged(CommandStackEvent event) {
			if (((CommandStack) event.getSource()).isDirty()) {
				// at least one command stack is dirty,
				// so the multi page editor is dirty too
				setDirty(true);
			}
			updateActions();
		}
	}

	/**
	 * This class listens to changes to the file system in the workspace, and
	 * validate the current pageflow based on web files' status.
	 */
	private class ResourceTracker implements IResourceChangeListener,
			IResourceDeltaVisitor {
		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
		 */
		public void resourceChanged(IResourceChangeEvent event) {
			IResourceDelta delta = event.getDelta();
			try {
				if (delta != null) {
					delta.accept(this);
				}
			} catch (CoreException exception) {
				// Pageflow.PageflowEditor.Error.ResourceChange = Failed in the
				// resource change.
				log.error("Pageflow.PageflowEditor.Error.ResourceChange",
						exception);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
		 */
		public boolean visit(IResourceDelta delta) {
			// if the delta is not a file instance, just return true
			if (!(delta.getResource() instanceof IFile)) {
				return true;
			}

			// web file is changed.
			if (WebrootUtil.isValidWebFile(((IFile) delta.getResource())
					.getFullPath())) {
				webPageChanged(((IFile) delta.getResource()).getFullPath());
				return false;
			}
			return false;
		}
	}

	/** the resource tracker instance */
	private ResourceTracker resourceTracker = null;

	/**
	 * Returns the resource tracker instance
	 * 
	 * @return - Returns the resource tracker instance
	 */
	private ResourceTracker getResourceTracker() {
		if (null == resourceTracker) {
			resourceTracker = new ResourceTracker();
		}
		return resourceTracker;
	}

	/**
	 * Changes the dirty state.
	 * 
	 * @param dirty -
	 *            dirty state
	 */
	protected void setDirty(boolean dirty) {
		if (isDirty != dirty) {
			isDirty = dirty;
		}
	}

	/**
	 * Updates the specified actions.
	 * 
	 * @param actionIds -
	 *            the list of ids of actions to update
	 */
	protected void updateActions(List actionIds) {
		for (Iterator ids = actionIds.iterator(); ids.hasNext();) {
			IAction action = getActionRegistry().getAction(ids.next());
			if (null != action && action instanceof UpdateAction) {
				((UpdateAction) action).update();
			}
		}
	}

	/**
	 * Creates a new PageflowPage instance.
	 * <p>
	 * By design this page uses its own <code>EditDomain</code>. The main
	 * goal of this approach is that this page has its own undo/redo command
	 * stack.
	 * 
	 * @param parent -
	 *            the parent multi page editor
	 */
	public PageflowEditor(IEditorPart parent) {
		domain = new DefaultEditDomain(parent);
		domain.setCommandStack(getCommandStack());
		this.setEditDomain(domain);
		parentEditor = parent;
	}

	/**
	 * Adds an <code>CommandStack</code> action to this editor.
	 * <p>
	 * <code>CommandStack</code> actions are actions that depend and work on
	 * the <code>CommandStack</code>.
	 * 
	 * @param action -
	 *            the <code>CommandStack</code> action
	 */
	protected void addStackAction(StackAction action) {
		getActionRegistry().registerAction(action);
		stackActions.add(action.getId());
	}

	/**
	 * Creates different kinds of actions and registers them to the
	 * ActionRegistry.
	 */
	protected void createActions() {
		// register delete action
		addEditPartAction(new DeleteAction((IWorkbenchPart) this));
		// register undo/redo action
		addStackAction(new UndoAction(this));
		addStackAction(new RedoAction(this));

		// Allows opening of JSP files from the pageflow
		addEditPartAction(new OpenEditorAction(this));

		// Allows showing property view for the pageflow
		SelectionAction action = new ShowPropertyViewAction(this);
		action
				.setImageDescriptor(getImageDescriptorForView("org.eclipse.ui.views.PropertySheet"));
		addEditPartAction(action);
		// Allows showing property view for the pageflow
		// addEditPartAction(new ShowPaletteViewAction((IWorkbenchPart) this));

		// register alignment actions
		addEditPartAction(new AlignmentAction((IWorkbenchPart) this,
				PositionConstants.LEFT));
		addEditPartAction(new AlignmentAction((IWorkbenchPart) this,
				PositionConstants.RIGHT));
		addEditPartAction(new AlignmentAction((IWorkbenchPart) this,
				PositionConstants.TOP));
		addEditPartAction(new AlignmentAction((IWorkbenchPart) this,
				PositionConstants.BOTTOM));
		addEditPartAction(new AlignmentAction((IWorkbenchPart) this,
				PositionConstants.CENTER));
		addEditPartAction(new AlignmentAction((IWorkbenchPart) this,
				PositionConstants.MIDDLE));

		// register zoom in/out action
		IAction zoomIn = new ZoomInAction(getZoomManager(getGraphicalViewer()));
		IAction zoomOut = new ZoomOutAction(
				getZoomManager(getGraphicalViewer()));
		addAction(zoomIn);
		addAction(zoomOut);

//		getSite().getKeyBindingService().registerAction(zoomIn);
//		getSite().getKeyBindingService().registerAction(zoomOut);
	}

	/**
	 * Returns the zoom manager of the specified viewer.
	 * 
	 * @param viewer_ -
	 *            the viewer to get the zoom manager from
	 * @return - the zoom manager
	 */
	private ZoomManager getZoomManager(GraphicalViewer viewer_) {
		// get zoom manager from root edit part
		RootEditPart rootEditPart = viewer_.getRootEditPart();
		ZoomManager zoomManager = null;
		if (rootEditPart instanceof ScalableFreeformRootEditPart) {
			zoomManager = ((ScalableFreeformRootEditPart) rootEditPart)
					.getZoomManager();
		} else if (rootEditPart instanceof ScalableRootEditPart) {
			zoomManager = ((ScalableRootEditPart) rootEditPart)
					.getZoomManager();
		}
		return zoomManager;
	}

	/**
	 * Adds an action to this editor's <code>ActionRegistry</code>.
	 * 
	 * @param action -
	 *            the action to add.
	 */
	protected void addAction(IAction action) {
		getActionRegistry().registerAction(action);
	}

	/**
	 * Adds an <code>EditPart</code> action to this editor.
	 * <p>
	 * <code>EditPart</code> actions are actions that depend and work on the
	 * selected <code>EditPart</code>s.
	 * 
	 * @param action -
	 *            the <code>EditPart</code> action
	 */
	protected void addEditPartAction(SelectionAction action) {
		getActionRegistry().registerAction(action);
		editPartActionIDs.add(action.getId());
	}

	/**
	 * Returns the action registry of this editor.
	 * 
	 * @return - the action registry
	 */
	public ActionRegistry getActionRegistry() {
		if (null == actionRegistry) {
			actionRegistry = new ActionRegistry();
		}

		return actionRegistry;
	}

	/**
	 * Creates the GraphicalViewer on the specified <code>Composite</code>.
	 * 
	 * @param parent -
	 *            the parent composite
	 */
	public void createGraphicalViewer(Composite parent) {
		viewer = new ScrollingGraphicalViewer();
		viewer.createControl(parent);

		// configure the viewer
		viewer.getControl().setBackground(parent.getBackground());

		viewer.setRootEditPart(new ConfigurableRootEditPart());
		// _viewer.setRootEditPart(new ScalableFreeformRootEditPart());
		viewer.setKeyHandler(new GraphicalViewerKeyHandler(viewer));

		// hook the viewer into the editor
		registerEditPartViewer(viewer);

		// configure the viewer with context menu and template drag and drop
		configureEditPartViewer(viewer);

		// initialize the viewer with input
		viewer.setEditPartFactory(new PageflowEditPartsFactory());
		// viewer.setContents(getPageflow());

		// support the resource drag&drop
		viewer
				.addDropTargetListener((TransferDropTargetListener) new ResourceTransferDropTargetListener(
						viewer, getParentEditor()) {
					protected CreationFactory getFactory(Object obj) {
						return getResourceFactory((IResource) obj);
					}
				});

		// apply Editor's preferences
		// propertyChange(null);
		// add listener to Editor's preferences changing
		EditorPlugin.getDefault().getPreferenceStore()
				.addPropertyChangeListener(this);
	}

	private CreationFactory getResourceFactory(IResource resource) {
		return new PageflowResourceFactory(resource);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public final void doSave(IProgressMonitor monitor) {
		// our policy: delegate saving to the parent
		getParentEditor().doSave(monitor);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ISaveablePart#doSaveAs()
	 */
	public final void doSaveAs() {
		// our policy: delegate saving to the parent
		getParentEditor().doSaveAs();
	}

	/**
	 * Saves the pageflow under the specified path.
	 * @param file 
	 * 
	 * @param progressMonitor
	 * @throws CoreException 
	 */
	public void doSave(IFile file, IProgressMonitor progressMonitor)
			throws CoreException {
		if (((FileEditorInput) getEditorInput()).getFile() != file) {
			// TODO: save to other page.
		}
		if (null == progressMonitor) {
			progressMonitor = new NullProgressMonitor();
		}
		// Pageflow.Label.Saving = Saving
		progressMonitor.beginTask(PageflowMessages.Pageflow_Label_Saving + " "
				+ file.getFullPath(), 2);

		if (null == getPageflowManager()) {
			// Pageflow.PageflowEditor.Alert.nullModelManager = No model manager
			// found for saving the file.
			EditorPlugin.getAlerts().throwCoreException(
					"Pageflow.PageflowEditor.Alert.nullModelManager");
		}

		// save pageflow to file
		try {
			getPageflowManager().save(getPageflowFilePath(file));

			progressMonitor.worked(1);
			file.refreshLocal(IResource.DEPTH_ZERO, new SubProgressMonitor(
					progressMonitor, 1));
			progressMonitor.done();
			setDirty(false);
		} catch (FileNotFoundException e) {
			// Pageflow.PageflowEditor.Alert.errorSaveFileInfo = The current
			// pageflow model could not be saved.
			EditorPlugin.getAlerts().throwCoreException(e);
		} catch (IOException e) {
			// Pageflow.PageflowEditor.Alert.errorSaveFileInfo = The current
			// pageflow model could not be saved.
			EditorPlugin.getAlerts().throwCoreException(e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see IEditorPart#init(org.eclipse.ui.IEditorSite,
	 *      org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		setSite(site);
		setInput(input);
		IFile fileFacesConfig = null;
		try {
			fileFacesConfig = ((FileEditorInput) input).getFile();

			// load and validate pageflow
			if (null == createPageflow(getPageflowFilePath(fileFacesConfig))) {
				// Pageflow.PageflowEditor.Error.invalidPageflowFile = The
				// specified input is not a valid pageflow.
				log.error("Pageflow.PageflowEditor.Error.invalidPageflowFile");
				throw new PartInitException(
						EditorPlugin
								.getResourceString("Pageflow.PageflowEditor.Error.invalidPageflowFile"));
			}

		} catch (CoreException e) {
			// Pageflow.PageflowEditor.Error.invalidPageflowFile = The specified
			// input is not a valid pageflow.
			log.error("Pageflow.PageflowEditor.Error.invalidPageflowFile", e);
			throw new PartInitException(e.getStatus());
		} catch (IOException e) {
			// Pageflow.PageflowEditor.Alert.errorSaveFileInfo = The current
			// pageflow model could not be saved.
			log.error("Pageflow.PageflowEditor.Alert.errorSaveFileInfo", e);
		}

		// add selection change listener
		getSite().getWorkbenchWindow().getSelectionService()
				.addSelectionListener(getSelectionListener());

		// Add resource change listener
		fileFacesConfig.getWorkspace().addResourceChangeListener(
				getResourceTracker());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPart#dispose()
	 */
	public void dispose() {
		// remove selection change listener
		getModelsTransform().dispose();
		getSite().getWorkbenchWindow().getSelectionService()
				.removeSelectionListener(getSelectionListener());

		// remove listener to Editor's preferences changing
		EditorPlugin.getDefault().getPreferenceStore()
				.removePropertyChangeListener(this);

		if (getEditorInput() != null) {
			IFile file = (IFile) getEditorInput().getAdapter(IResource.class);
			if (file != null) {
				file.getWorkspace().removeResourceChangeListener(
						getResourceTracker());
			}
		}
		super.dispose();
	}

	/**
	 * get the pageflow file path based on faces-config.xml file path
	 * 
	 * @return
	 */
	private IPath getPageflowFilePath(IFile file) {
		IPath pageflowFilePath;
		pageflowFilePath = PageflowModelManager.makePageflowPath(file
				.getFullPath());
		return pageflowFilePath;
	}

	/**
	 * Returns the pageflow object from the specified file.
	 * 
	 * @param file -
	 *            the file resource
	 * @return -the pageflow object from the specified file
	 * @throws IOException
	 */
	private Pageflow createPageflow(IPath pathPageflow) throws CoreException,
			IOException {
		Pageflow pageflow = null;

		try {
			getPageflowManager().load(pathPageflow);
		} catch (Exception e) {
			// Pageflow.PageflowEditor.Error.invalidPageflowFile = The specified
			// input is not a valid pageflow.
			// _log.error("Pageflow.PageflowEditor.Error.invalidPageflowFile",
			// e);
			getPageflowManager().createPageflow(pathPageflow);
		}
		IFile fileFacesConfig = ((FileEditorInput) getEditorInput()).getFile();
		// it should update related config file
		if (!fileFacesConfig.getFullPath().toString().trim().equalsIgnoreCase(
				getPageflowManager().getModel().getConfigfile())) {
			getPageflowManager().getModel().setConfigfile(
					fileFacesConfig.getFullPath().toString());
			getPageflowManager().save(pathPageflow);
		}
		pageflow = getPageflowManager().getModel();
		if (null == pageflow) {
			// Pageflow.PageflowEditor.Error.invalidPageflowModel = The model in
			// the pageflow file is not a valid pageflow model.
			log.error("Pageflow.PageflowEditor.Error.invalidPageflowModel");
			EditorPlugin.getAlerts().throwCoreException(
					"Pageflow.PageflowEditor.Error.invalidPageflowModel");
		}
		return pageflow;
	}

	/** get the pageflow manager for this page 
	 * @return  the model manager
	 */
	public PageflowModelManager getPageflowManager() {
		if (pageflowManager == null) {
			pageflowManager = new PageflowModelManager();
		}
		return pageflowManager;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ISaveablePart#isDirty()
	 */
	public final boolean isDirty() {
		return isDirty;
	}

	/**
	 * Returns the <code>CommandStack</code> of this editor page.
	 * 
	 * @return - the <code>CommandStack</code> of this editor page
	 */
	public final CommandStack getCommandStack() {
		if (commandStack == null) {
			commandStack = new PreExecuteCommandStack();
			commandStack
					.addCommandStackEventListener(new PageCommandStackListener());
		}
		return commandStack;
	}

	/**
	 * Returns the default <code>PaletteRoot</code> for this editor and all
	 * its pages.
	 * 
	 * @return - the default <code>PaletteRoot</code>
	 */
	protected PaletteRoot getPaletteRoot() {
		if (null == paletteRoot) {
			// create root
			paletteRoot = new PageflowPaletteRoot();
		}
		return paletteRoot;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ISaveablePart#isSaveAsAllowed()
	 */
	public final boolean isSaveAsAllowed() {
		// our policy: delegate saving to the parent
		return getParentEditor().isSaveAsAllowed();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see IWorkbenchPart#setFocus()
	 */
	public void setFocus() {
		getGraphicalViewer().getControl().setFocus();
	}

	/**
	 * Returns the multi page pageflow editor this editor page is contained in.
	 * 
	 * @return - the parent multi page editor
	 */
	protected final IEditorPart getParentEditor() {
		return parentEditor;
	}

	/**
	 * Returns the edit domain this editor page uses.
	 * 
	 * @return - the edit domain this editor page uses
	 */
	public final DefaultEditDomain getEditDomain() {
		return domain;
	}

	/**
	 * Hooks a <code>EditPartViewer</code> to the rest of the Editor.
	 * <p>
	 * By default, the viewer is added to the SelectionSynchronizer, which can
	 * be used to keep 2 or more EditPartViewers in sync. The viewer is also
	 * registered as the ISelectionProvider for the Editor's PartSite.
	 * 
	 * @param viewer_ -
	 *            the viewer to hook into the editor
	 */
	protected void registerEditPartViewer(EditPartViewer viewer_) {
		// register viewer to edit domain
		getEditDomain().addViewer(viewer_);

		// the multi page pageflow editor keeps track of synchronizing
		getSelectionSynchronizer().addViewer(viewer_);

		// add viewer as selection provider
		getSite().setSelectionProvider(viewer_);
	}

	/**
	 * Configures the specified <code>EditPartViewer</code> including context
	 * menu, key handler, etc.
	 * 
	 * @param viewer_ -
	 *            the pageflow graphical viewer.
	 */
	protected void configureEditPartViewer(EditPartViewer viewer_) {
		// configure the shared key handler
		if (null != viewer_.getKeyHandler()) {
			viewer_.getKeyHandler().setParent(getSharedKeyHandler());
		}
		// create the ActionRegistry
		createActions();

		// append the parent editor's action registry.
		ActionRegistry actionRegistry_ = (ActionRegistry) getParentEditor()
				.getAdapter(ActionRegistry.class);
		if (actionRegistry_ != null) {
			for (Iterator iter = actionRegistry_.getActions(); iter.hasNext();) {
				getActionRegistry().registerAction((IAction) iter.next());
			}
		}
		// configure and register the context menu
		ContextMenuProvider provider = new PageflowEditorContextMenuProvider(
				viewer_, getActionRegistry());
		viewer_.setContextMenu(provider);
		getSite().registerContextMenu(
				EditorPlugin.getPluginId() + PAGEFLOW_CONTEXTMENU_REG_ID,
				provider, getSite().getSelectionProvider()); //$NON-NLS-1$

		// enable viewer as drop target for template transfers
		viewer_
				.addDropTargetListener((TransferDropTargetListener) new PageflowTemplateTransferDropTargetListener(
						viewer_));

	}

	/**
	 * Returns the pageflow that is edited.
	 * 
	 * @return - the pageflow that is edited
	 */
	public Pageflow getPageflow() {
		return getPageflowManager().getModel();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see AbstractEditorPage#getGraphicalViewerForZoomSupport()
	 */
	public GraphicalViewer getGraphicalViewer() {
		return viewer;
	}

	/**
	 * @param contents
	 */
	public void setGraphicalViewerContents(Object contents) {
		viewer.setContents(contents);
		propertyChange(null);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see IAdaptable#getAdapter(Class)
	 */
	public Object getAdapter(Class type) {
		if (type == IContentOutlinePage.class) {
			return getOutlinePage();
		} else if (type == CommandStack.class) {
			return getCommandStack();
		} else if (type == ActionRegistry.class) {
			return getActionRegistry();
		} else if (type == IPropertySheetPage.class) {
			return getPropertySheetPage();
		} else if (type == ZoomManager.class) {
			return getZoomManager(getGraphicalViewer());
		}
		return super.getAdapter(type);
	}

	/**
	 * Returns the outline page for the outline view with lazy creation
	 * 
	 * @return - the outline page
	 */
	protected PageflowEditorOutlinePage getOutlinePage() {
		PageflowEditorOutlinePage outlinePage = new PageflowEditorOutlinePage(
				this);
		outlinePage.initialize(this);
		return outlinePage;
	}

	/**
	 * Returns the undoable <code>PropertySheetPage</code> for this editor.
	 * 
	 * @return - the undoable <code>PropertySheetPage</code>
	 */
	protected IPropertySheetPage getPropertySheetPage() {
		if (null == undoablePropertySheetPage) {
			undoablePropertySheetPage = new PropertySheetPage();

			/** set the property source for property sheet page */
			undoablePropertySheetPage
					.setRootEntry(new org.eclipse.gef.ui.properties.UndoablePropertySheetEntry(
							(CommandStack) getAdapter(CommandStack.class)));

		}

		return undoablePropertySheetPage;
	}

	/**
	 * Returns the selection syncronizer object. The synchronizer can be used to
	 * sync the selection of 2 or more EditPartViewers.
	 * 
	 * @return - the syncrhonizer
	 */
	protected SelectionSynchronizer getSelectionSynchronizer() {
		if (null == synchronizer) {
			synchronizer = new SelectionSynchronizer();
		}
		return synchronizer;
	}

	/**
	 * Returns the shared KeyHandler that should be used for all viewers.
	 * 
	 * @return - the shared KeyHandler
	 */
	protected KeyHandler getSharedKeyHandler() {
		if (null == sharedKeyHandler) {
			sharedKeyHandler = new KeyHandler();

			// configure common keys for all viewers
			sharedKeyHandler
					.put(KeyStroke.getPressed(SWT.DEL, 127, 0),
							getActionRegistry().getAction(
									ActionFactory.DELETE.getId()));
			sharedKeyHandler.put(KeyStroke.getPressed(SWT.F2, 0),
					getActionRegistry().getAction(
							GEFActionConstants.DIRECT_EDIT));
		}
		return sharedKeyHandler;
	}

	/**
	 * Returns the selection listener.
	 * 
	 * @return - the <code>ISelectionListener</code>
	 */
	protected ISelectionListener getSelectionListener() {
		return selectionListener;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent event) {
		String property = (event == null) ? null : event.getProperty();

		propagateProperty(property, viewer.getRootEditPart());
	}

	/**
	 * propagate property change to children edit part
	 * 
	 * @param property -
	 *            property's string name
	 * @param part -
	 *            parent edit part.
	 */
	private void propagateProperty(String property, EditPart part) {
		processPropertyChange(property, part);

		if (part instanceof GraphicalEditPart) {
			// get the connections edit part
			Iterator iterConns = ((GraphicalEditPart) part)
					.getSourceConnections().iterator();
			while (iterConns.hasNext()) {
				EditPart child = (EditPart) iterConns.next();
				propagateProperty(property, child);
			}
		}
		Iterator iter = part.getChildren().iterator();
		while (iter.hasNext()) {
			EditPart child = (EditPart) iter.next();
			propagateProperty(property, child);
		}
	}

	/**
	 * process the property change FIXME: The property change should be category
	 * to improve the performance.
	 * 
	 * @param property -
	 *            property's string name
	 * @param part
	 */
	private void processPropertyChange(String property, EditPart part) {
		IPreferenceStore store = EditorPlugin.getDefault().getPreferenceStore();

		if (property != null
				&& property.equals(GEMPreferences.USE_SYSTEM_COLORS)) {
			// reload all properties - it's easiest
			property = null;
		}

		if (property == null || GEMPreferences.SNAP_TO_GRID.equals(property)) {
			boolean bSnapToGrid = store.getBoolean(GEMPreferences.SNAP_TO_GRID);
			if (part instanceof ILayerPanePreference) {
				((ILayerPanePreference) part).setGridVisible(bSnapToGrid);
			}
		}

		if (property == null || GEMPreferences.GRID_WIDTH.equals(property)
				|| GEMPreferences.GRID_HEIGHT.equals(property)) {
			Dimension gridSpacing = new Dimension(store
					.getInt(GEMPreferences.GRID_WIDTH), store
					.getInt(GEMPreferences.GRID_HEIGHT));
			if (part instanceof ILayerPanePreference) {
				((ILayerPanePreference) part).setGridSpacing(gridSpacing);
			}
		}

		if (property == null || GEMPreferences.GRID_COLOR.equals(property)) {
			Color gridFgColor = GEMPreferences.getColor(store,
					GEMPreferences.GRID_COLOR);
			if (part instanceof ILayerPanePreference) {
				((ILayerPanePreference) part)
						.setGridForegroundColor(gridFgColor);
			}
		}

		if (property == null || GEMPreferences.CANVAS_COLOR.equals(property)) {
			Color containerBgColor = GEMPreferences.getColor(store,
					GEMPreferences.CANVAS_COLOR);
			if (part instanceof IFigurePreference) {
				((IFigurePreference) part).setBackgroundColor(containerBgColor);
			}
		}

		if (property == null || GEMPreferences.LINE_WIDTH.equals(property)) {
			int linkLineWidth = store.getInt(GEMPreferences.LINE_WIDTH);

			if (part instanceof IConnectionPreference) {
				((IConnectionPreference) part).setLineWidth(linkLineWidth);
			}
		}

		if (property == null || GEMPreferences.LINE_COLOR.equals(property)) {
			Color linkLineColor = GEMPreferences.getColor(store,
					GEMPreferences.LINE_COLOR);
			if (part instanceof IConnectionPreference) {
				((IConnectionPreference) part)
						.setForegroundColor(linkLineColor);
			}
		}

		if (property == null
				|| GEMPreferences.SHOW_LINE_LABELS.equals(property)) {
			boolean bLinkLabelVisible = store
					.getBoolean(GEMPreferences.SHOW_LINE_LABELS);
			if (part instanceof IConnectionPreference) {
				((IConnectionPreference) part)
						.setLabelVisible(bLinkLabelVisible);
			}
		}

		if (property == null || GEMPreferences.LINE_LABEL_FONT.equals(property)
				|| GEMPreferences.LINE_LABEL_FONT_COLOR.equals(property)) {
			Font linkLabelFont = getLinkLabelFont();
			Color linkLabelFgColor = GEMPreferences.getColor(store,
					GEMPreferences.LINE_LABEL_FONT_COLOR);
			if (part instanceof IConnectionPreference) {
				((IConnectionPreference) part).setFont(linkLabelFont);
				((IConnectionPreference) part)
						.setLabelForegroundColor(linkLabelFgColor);
			}
		}

		if (property == null
				|| GEMPreferences.LINE_LABEL_COLOR.equals(property)) {
			Color linkLabelBgColor = GEMPreferences.getColor(store,
					GEMPreferences.LINE_LABEL_COLOR);
			if (part instanceof IConnectionPreference) {
				((IConnectionPreference) part)
						.setLabelBackgroundColor(linkLabelBgColor);
			}
		}

		if (property == null || GEMPreferences.LINE_ROUTING.equals(property)) {
			String connectionStyle = store
					.getString(GEMPreferences.LINE_ROUTING);
			int style;
			if (GEMPreferences.LINE_ROUTING_MANHATTAN.equals(connectionStyle)) {
				style = ILayerPanePreference.LINE_ROUTING_MANHATTAN;
			} else {
				style = ILayerPanePreference.LINE_ROUTING_MANUAL;
			}

			if (part instanceof ILayerPanePreference) {
				((ILayerPanePreference) part).setConnectionRouterStyle(style);
			} else if (part instanceof IConnectionPreference) {
				((IConnectionPreference) part).setConnectionRouterStyle(style);
			}
		}

		if (property == null
				|| GEMPreferences.FIGURE_LABEL_FONT.equals(property)
				|| GEMPreferences.FIGURE_LABEL_FONT_COLOR.equals(property)) {
			Font nodeLabelFont = getNodeLabelFont();
			Color nodeLabelFgColor = GEMPreferences.getColor(store,
					GEMPreferences.FIGURE_LABEL_FONT_COLOR);

			if (part instanceof INodePreference) {
				((INodePreference) part).setFont(nodeLabelFont);
				((INodePreference) part).setForegroundColor(nodeLabelFgColor);
			}
		}

		if (property == null || GEMPreferences.LABEL_PLACEMENT.equals(property)) {
			int placement = PositionConstants.SOUTH;
			String nodeLabelPlacement = store
					.getString(GEMPreferences.LABEL_PLACEMENT);
			if (GEMPreferences.LABEL_PLACEMENT_TOP.equals(nodeLabelPlacement))
				placement = PositionConstants.NORTH;
			else if (GEMPreferences.LABEL_PLACEMENT_BOTTOM
					.equals(nodeLabelPlacement))
				placement = PositionConstants.SOUTH;
			else if (GEMPreferences.LABEL_PLACEMENT_LEFT
					.equals(nodeLabelPlacement))
				placement = PositionConstants.WEST;
			else if (GEMPreferences.LABEL_PLACEMENT_RIGHT
					.equals(nodeLabelPlacement))
				placement = PositionConstants.EAST;
			if (part instanceof INodePreference)
				((INodePreference) part).setTextPlacement(placement);
		}
	}

	private Font getLinkLabelFont() {
		FontRegistry registry = JFaceResources.getFontRegistry();
		IPreferenceStore store = EditorPlugin.getDefault().getPreferenceStore();
		FontData fontData = PreferenceConverter.getFontData(store,
				GEMPreferences.LINE_LABEL_FONT);
		if (!registry.get(fontData.toString()).equals(registry.defaultFont()))
			return registry.get(fontData.toString());
		
		registry.put(fontData.toString(), new FontData[] {fontData});
		return registry.get(fontData.toString());
	}

	private Font getNodeLabelFont() {
		FontRegistry registry = JFaceResources.getFontRegistry();
		IPreferenceStore store = EditorPlugin.getDefault().getPreferenceStore();
		FontData fontData = PreferenceConverter.getFontData(store,
				GEMPreferences.FIGURE_LABEL_FONT);
		if (!registry.get(fontData.toString()).equals(registry.defaultFont()))
			return registry.get(fontData.toString());
		
		registry.put(fontData.toString(), new FontData[] {fontData});
		return registry.get(fontData.toString());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.ide.IGotoMarker#gotoMarker(org.eclipse.core.resources.IMarker)
	 */
	public void gotoMarker(IMarker marker) {
		// The LOCATION attribute in the marker should be the ID string
		Object id = null;
		try {
			id = marker.getAttribute(IMarker.LOCATION);
		} catch (CoreException e) {
			// Pageflow.PageflowEditor.Error.invalidMarkerAttribute = Unable to
			// get marker's attribute
			log
					.error(
							"Pageflow.PageflowEditor.Error.invalidMarkerAttribute",
							e);
		}
		if (id instanceof String) {
			GraphicalEditPart part = EditPartMarkerUtil.findEditPart(
					(GraphicalEditPart) getGraphicalViewer().getRootEditPart(),
					(String) id);
			if (part != null) {
				getGraphicalViewer().reveal(part);
				getGraphicalViewer().select(part);
				return;
			}
		}

	}

	/**
	 * the related web page is changed in outside editor, the pageflow should be
	 * revalidated to update the validation icons
	 * 
	 * @param fullPath
	 */
	public void webPageChanged(IPath fullPath) {
		PageflowPage page = getPageflowManager().foundPage(
				WebrootUtil.getWebPath(fullPath));

		if (page != null && getGraphicalViewer() != null
				&& getGraphicalViewer().getRootEditPart() != null) {
			GraphicalEditPart pagePart = EditPartMarkerUtil.findEditPart(
					(GraphicalEditPart) getGraphicalViewer().getRootEditPart(),
					page.getId());
			PageflowAnnotationUtil
					.validatePage((PageflowNodeEditPart) pagePart);
		}
	}

	/**
	 * Get the image desriptor from the view's id.
	 * 
	 * @param viewid
	 * @return
	 */
	private ImageDescriptor getImageDescriptorForView(String viewid) {
		IConfigurationElement[] elements = Platform.getExtensionRegistry()
				.getConfigurationElementsFor("org.eclipse.ui.views");
		for (int i = 0; i < elements.length; i++) {
			String name = elements[i].getName();
			String id = elements[i].getAttribute("id");
			if ("view".equals(name) && viewid.equals(id)) {
				String iconPath = elements[i].getAttribute("icon");
				if (iconPath != null) {
					return AbstractUIPlugin.imageDescriptorFromPlugin(
							elements[i].getDeclaringExtension().getContributor().getName(),
							iconPath);
				}
			}
		}
		return null;
	}
}