/*******************************************************************************
 * 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"; //$NON-NLS-1$

	/** 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"; //$NON-NLS-1$

	/** 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", //$NON-NLS-1$
						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")); //$NON-NLS-1$
		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 + " " //$NON-NLS-1$
				+ 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"); //$NON-NLS-1$
		}

		// 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"); //$NON-NLS-1$
				throw new PartInitException(
						EditorPlugin
								.getResourceString("Pageflow.PageflowEditor.Error.invalidPageflowFile")); //$NON-NLS-1$
			}

		} catch (CoreException e) {
			// Pageflow.PageflowEditor.Error.invalidPageflowFile = The specified
			// input is not a valid pageflow.
			log.error("Pageflow.PageflowEditor.Error.invalidPageflowFile", e); //$NON-NLS-1$
			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); //$NON-NLS-1$
		}

		// 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"); //$NON-NLS-1$
			EditorPlugin.getAlerts().throwCoreException(
					"Pageflow.PageflowEditor.Error.invalidPageflowModel"); //$NON-NLS-1$
		}
		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());

		// 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", //$NON-NLS-1$
							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"); //$NON-NLS-1$
		for (int i = 0; i < elements.length; i++) {
			String name = elements[i].getName();
			String id = elements[i].getAttribute("id"); //$NON-NLS-1$
			if ("view".equals(name) && viewid.equals(id)) { //$NON-NLS-1$
				String iconPath = elements[i].getAttribute("icon"); //$NON-NLS-1$
				if (iconPath != null) {
					return AbstractUIPlugin.imageDescriptorFromPlugin(
							elements[i].getDeclaringExtension().getContributor().getName(),
							iconPath);
				}
			}
		}
		return null;
	}
}