/*****************************************************************************
 * Copyright (c) 2004, 2010 IBM Corporation and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms
 * of the Eclipse Public License v1.0 which accompanies this distribution, and
 * is available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: IBM Corporation - initial API and implementation
 ****************************************************************************/
package org.eclipse.wst.xml.ui.internal.tabletree;


import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.part.MultiPageEditorSite;
import org.eclipse.ui.part.MultiPageSelectionProvider;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.eclipse.wst.sse.ui.internal.contentoutline.IJFaceNodeAdapter;
import org.eclipse.wst.xml.core.internal.provisional.IXMLPreferenceNames;
import org.eclipse.wst.xml.core.internal.provisional.contenttype.ContentTypeIdForXML;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.ui.internal.Logger;
import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
import org.eclipse.wst.xml.ui.internal.contentoutline.JFaceNodeLabelProvider;
import org.w3c.dom.Attr;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XMLMultiPageEditorPart extends MultiPageEditorPart {

	/**
	 * Internal part activation listener, copied from AbstractTextEditor
	 */
	class ActivationListener implements IPartListener, IWindowListener {

		/**
		 * The maximum number of children the root nodes can have for the
		 * design page to auto expand the root nodes
		 */
		private static final int MAX_NUM_CHILD_NODES_FOR_AUTO_EXPAND = 500;
		
		/** Cache of the active workbench part. */
		private IWorkbenchPart fActivePart;
		/** Indicates whether activation handling is currently be done. */
		private boolean fIsHandlingActivation = false;
		/**
		 * The part service.
		 * 
		 * @since 3.1
		 */
		private IPartService fPartService;

		/**
		 * Creates this activation listener.
		 * 
		 * @param partService
		 *            the part service on which to add the part listener
		 * @since 3.1
		 */
		public ActivationListener(IPartService partService) {
			fPartService = partService;
			fPartService.addPartListener(this);
			PlatformUI.getWorkbench().addWindowListener(this);
		}

		/**
		 * Disposes this activation listener.
		 * 
		 * @since 3.1
		 */
		public void dispose() {
			fPartService.removePartListener(this);
			PlatformUI.getWorkbench().removeWindowListener(this);
			fPartService = null;
		}

		/*
		 * @see IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partActivated(IWorkbenchPart part) {
			fActivePart = part;
			handleActivation();
		}

		/*
		 * @see IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partBroughtToTop(IWorkbenchPart part) {
			// do nothing
		}

		/*
		 * @see IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partClosed(IWorkbenchPart part) {
			// do nothing
		}

		/*
		 * @see IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partDeactivated(IWorkbenchPart part) {
			fActivePart = null;
		}

		/*
		 * @see IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partOpened(IWorkbenchPart part) {
			if (fDesignViewer instanceof AbstractTreeViewer) {
				IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(getDocument());
				try {
					if (model instanceof IDOMModel) {
						IDOMDocument modelDocument = ((IDOMModel) model).getDocument();
						NodeList rootChildren = modelDocument.getChildNodes();

						boolean tooManyChildren = (rootChildren.getLength() > MAX_NUM_CHILD_NODES_FOR_AUTO_EXPAND);
						/*
						 * For each root (there should really only be one
						 * real root but there are also could be empty
						 * text regions and doc type at the root level)
						 * determine if it has to many children or not to
						 * auto expand
						 */
						for (int i = 0; i < rootChildren.getLength() && !tooManyChildren; ++i) {
							tooManyChildren = (rootChildren.item(i).getChildNodes().getLength() > MAX_NUM_CHILD_NODES_FOR_AUTO_EXPAND);
						}

						/*
						 * if root node does not have to many children then
						 * auto expand the root node
						 */
						if (!tooManyChildren) {
							((AbstractTreeViewer) fDesignViewer).expandToLevel(2);
						}
					}
				}
				finally {
					if (model != null) {
						model.releaseFromRead();
					}
				}
			}
		}

		/**
		 * Handles the activation triggering a element state check in the
		 * editor.
		 */
		void handleActivation() {
			if (fIsHandlingActivation || (getTextEditor() == null)) {
				return;
			}

			if (fActivePart == XMLMultiPageEditorPart.this) {
				fIsHandlingActivation = true;
				try {
					getTextEditor().safelySanityCheckState(getEditorInput());
				}
				finally {
					fIsHandlingActivation = false;
				}
			}
		}

		/*
		 * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow)
		 * @since 3.1
		 */
		public void windowActivated(IWorkbenchWindow window) {
			if (window == getEditorSite().getWorkbenchWindow()) {
				/*
				 * Workaround for problem described in
				 * http://dev.eclipse.org/bugs/show_bug.cgi?id=11731 Will be
				 * removed when SWT has solved the problem.
				 */
				window.getShell().getDisplay().asyncExec(new Runnable() {
					public void run() {
						handleActivation();
					}
				});
			}
		}

		/*
		 * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow)
		 * @since 3.1
		 */
		public void windowDeactivated(IWorkbenchWindow window) {
			// do nothing
		}

		/*
		 * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow)
		 * @since 3.1
		 */
		public void windowClosed(IWorkbenchWindow window) {
			// do nothing
		}

		/*
		 * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow)
		 * @since 3.1
		 */
		public void windowOpened(IWorkbenchWindow window) {
			// do nothing
		}
	}

	/**
	 * Listens for selection from the source page, applying it to the design
	 * viewer.
	 */
	private class TextEditorPostSelectionAdapter extends UIJob implements ISelectionChangedListener {
		boolean forcePostSelection = false;
		ISelection selection = null;

		public TextEditorPostSelectionAdapter() {
			super(getTitle());
			setUser(true);
		}

		public IStatus runInUIThread(IProgressMonitor monitor) {
			if (selection != null) {
				fDesignViewer.getSelectionProvider().setSelection(selection);
			}
			return Status.OK_STATUS;
		}

		public void selectionChanged(SelectionChangedEvent event) {
			if ((fDesignViewer != null) && ((getActivePage() != fDesignPageIndex) || !XMLMultiPageEditorPart.this.equals(getSite().getPage().getActivePart()))) {
				if (forcePostSelection) {
					selection = event.getSelection();
					schedule(200);
				}
				else {
					fDesignViewer.getSelectionProvider().setSelection(event.getSelection());
				}
			}
		}
	}

	private class PageInitializationData {
		IConfigurationElement fElement;
		String fPropertyName;
		Object fData;

		PageInitializationData(IConfigurationElement cfig, String propertyName, Object data) {
			super();
			fElement = cfig;
			fPropertyName = propertyName;
			fData = data;
		}

		void sendInitializationData(IExecutableExtension executableExtension) {
			try {
				executableExtension.setInitializationData(fElement, fPropertyName, fData);
			}
			catch (CoreException e) {
				Logger.logException(e);
			}
		}
	}

	/**
	 * Internal IPropertyListener on the source page
	 */
	class PropertyListener implements IPropertyListener {
		public void propertyChanged(Object source, int propId) {
			switch (propId) {
				// had to implement input changed "listener" so that
				// StructuredTextEditor could tell it containing editor that
				// the input has change, when a 'resource moved' event is
				// found.
				case IEditorPart.PROP_INPUT : {
					if (source == getTextEditor() && fDesignViewer instanceof XMLTableTreeViewer) {
						IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(getDocument());
						try {
							if (model instanceof IDOMModel) {
								IDOMDocument modelDocument = ((IDOMModel) model).getDocument();
								Object designInput = ((XMLTableTreeViewer) fDesignViewer).getInput();
								if (modelDocument != designInput)
									setInput(getTextEditor().getEditorInput());
							}
						}
						finally {
							if (model != null)
								model.releaseFromRead();
						}
					}
				}
				case IEditorPart.PROP_DIRTY : {
					if (source == getTextEditor()) {
						if (getTextEditor().getEditorInput() != getEditorInput()) {
							setInput(getTextEditor().getEditorInput());
							/*
							 * title should always change when input changes.
							 * create runnable for following post call
							 */
							Runnable runnable = new Runnable() {
								public void run() {
									_firePropertyChange(IWorkbenchPart.PROP_TITLE);
								}
							};
							/*
							 * Update is just to post things on the display
							 * queue (thread). We have to do this to get the
							 * dirty property to get updated after other
							 * things on the queue are executed.
							 */
							((Control) getTextEditor().getAdapter(Control.class)).getDisplay().asyncExec(runnable);
						}
					}
					break;
				}
				case IWorkbenchPart.PROP_TITLE : {
					// update the input if the title is changed
					if (source == getTextEditor()) {
						if (getTextEditor().getEditorInput() != getEditorInput()) {
							setInput(getTextEditor().getEditorInput());
						}
					}
					break;
				}
				default : {
					// propagate changes. Is this needed? Answer: Yes.
					if (source == getTextEditor()) {
						_firePropertyChange(propId);
					}
					break;
				}
			}

		}
	}

	class TextInputListener implements ITextInputListener {
		public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
			// do nothing
		}

		public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
			if ((fDesignViewer != null) && (newInput != null)) {
				fDesignViewer.setDocument(newInput);
			}
		}
	}

	class StatusLineLabelProvider extends JFaceNodeLabelProvider {
		public StatusLineLabelProvider() {
		}

		public String getText(Object element) {
			if (element == null)
				return null;

			Node node = (Node) element;
			if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
				return getText(((Attr) node).getOwnerElement());
			}

			StringBuffer s = new StringBuffer();
			if (node.getNodeType() != Node.DOCUMENT_NODE) {
				while (node != null && node instanceof INodeNotifier) {
					INodeNotifier notifier = (INodeNotifier) node;
					if (node.getNodeType() != Node.DOCUMENT_NODE) {
						IJFaceNodeAdapter adapter = (IJFaceNodeAdapter) notifier.getAdapterFor(IJFaceNodeAdapter.class);
						if (adapter != null) {
							s.insert(0, adapter.getLabelText(node));
						}
					}
					node = node.getParentNode();
					if (node != null && node.getNodeType() != Node.DOCUMENT_NODE)
						s.insert(0, IPath.SEPARATOR);
				}
			}
			return s.toString();
		}

		public Image getImage(Object element) {
			if (element == null)
				return null;

			Node node = (Node) element;
			if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
				return getImage(((Attr) node).getOwnerElement());
			}
			return super.getImage(element);
		}
	}

	/** The design page index. */
	private int fDesignPageIndex;

	/** The design viewer */
	IDesignViewer fDesignViewer;
	/** Any container for the design viewer */
	private Composite fDesignContainer;

	private ActivationListener fActivationListener;

	IPropertyListener fPropertyListener = null;

	/** The source page index. */
	int fSourcePageIndex;

	/** The text editor. */
	private StructuredTextEditor fTextEditor;

	private TextEditorPostSelectionAdapter fTextEditorSelectionListener;

	private ILabelProvider fStatusLineLabelProvider;

	private PageInitializationData fPageInitializer;
	
	private ToolBarManager fToolbarManager;

	private boolean fAllocateToolbar = true;
	
	/**
	 * StructuredTextMultiPageEditorPart constructor comment.
	 */
	public XMLMultiPageEditorPart() {
		super();
		fStatusLineLabelProvider = new StatusLineLabelProvider();
	}

	/*
	 * This method is just to make firePropertyChanged accessible from some
	 * (anonomous) inner classes.
	 */
	void _firePropertyChange(int property) {
		super.firePropertyChange(property);
	}

	/**
	 * Adds the source page of the multi-page editor.
	 */
	private void addSourcePage() throws PartInitException {
		fSourcePageIndex = addPage(fTextEditor, getEditorInput());
		setPageText(fSourcePageIndex, XMLEditorMessages.XMLMultiPageEditorPart_0);

		firePropertyChange(PROP_TITLE);

		// Changes to the Text Viewer's document instance should also
		// force an
		// input refresh
		fTextEditor.getTextViewer().addTextInputListener(new TextInputListener());
	}

	/**
	 * Connects the design viewer with the viewer selection manager. Should be
	 * done after createSourcePage() is done because we need to get the
	 * ViewerSelectionManager from the TextEditor. setModel is also done here
	 * because getModel() needs to reference the TextEditor.
	 */
	private void connectDesignPage() {
		if (fDesignViewer != null) {
			fDesignViewer.setDocument(getDocument());
		}

		/*
		 * Connect selection from the Design page to the selection provider
		 * for the XMLMultiPageEditorPart so that selection changes in the
		 * Design page will propagate across the workbench
		 */
		if (fDesignViewer.getSelectionProvider() instanceof IPostSelectionProvider) {
			((IPostSelectionProvider) fDesignViewer.getSelectionProvider()).addPostSelectionChangedListener(new ISelectionChangedListener() {
				public void selectionChanged(SelectionChangedEvent event) {
					((MultiPageSelectionProvider) getSite().getSelectionProvider()).firePostSelectionChanged(event);
				}
			});
		}
		fDesignViewer.getSelectionProvider().addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				((MultiPageSelectionProvider) getSite().getSelectionProvider()).fireSelectionChanged(event);
			}
		});

		/*
		 * Connect selection from the Design page to the selection provider of
		 * the Source page so that selection in the Design page will drive
		 * selection in the Source page. Prefer post selection.
		 */
		if (fDesignViewer.getSelectionProvider() instanceof IPostSelectionProvider) {
			((IPostSelectionProvider) fDesignViewer.getSelectionProvider()).addPostSelectionChangedListener(new ISelectionChangedListener() {
				public void selectionChanged(final SelectionChangedEvent event) {
					/*
					 * Only force selection update if source page is not
					 * active
					 */
					if (getActivePage() != fSourcePageIndex) {
						getTextEditor().getSelectionProvider().setSelection(event.getSelection());
					}
				}
			});
		}
		else {
			fDesignViewer.getSelectionProvider().addSelectionChangedListener(new ISelectionChangedListener() {
				public void selectionChanged(SelectionChangedEvent event) {
					/*
					 * Only force selection update if source page is not
					 * active
					 */
					if (getActivePage() != fSourcePageIndex) {
						getTextEditor().getSelectionProvider().setSelection(event.getSelection());
					}
					/*
					 * Bug 210481 - Removed call to updateStatusLine because
					 * this is already handled by the selection in the source
					 * page
					 */
				}
			});
		}

		/*
		 * Handle double-click in the Design page by selecting the
		 * corresponding amount of text in the Source page.
		 * 
		 * Warning: This implies more knowledge of the design viewer's underlying
		 * Control than expressed in the IDesignViewer interface
		 */
		fDesignViewer.getControl().addListener(SWT.MouseDoubleClick, new Listener() {
			public void handleEvent(Event event) {
				ISelection selection = fDesignViewer.getSelectionProvider().getSelection();
				int start = -1;
				int length = -1;
				if (selection instanceof IStructuredSelection) {
					/*
					 * selection goes from the start of the first object to
					 * the end of the last
					 */
					IStructuredSelection structuredSelection = (IStructuredSelection) selection;
					Object o = structuredSelection.getFirstElement();
					Object o2 = null;
					if (structuredSelection.size() > 1) {
						o2 = structuredSelection.toArray()[structuredSelection.size() - 1];
					}
					else {
						o2 = o;
					}
					if (o instanceof IndexedRegion) {
						start = ((IndexedRegion) o).getStartOffset();
						length = ((IndexedRegion) o2).getEndOffset() - start;
					}
					else if (o2 instanceof ITextRegion) {
						start = ((ITextRegion) o).getStart();
						length = ((ITextRegion) o2).getEnd() - start;
					}
				}
				else if (selection instanceof ITextSelection) {
					start = ((ITextSelection) selection).getOffset();
					length = ((ITextSelection) selection).getLength();
				}
				if ((start > -1) && (length > -1)) {
					getTextEditor().selectAndReveal(start, length);
				}
			}
		});

		/*
		 * Connect selection from the Source page to the selection provider of
		 * the Design page so that selection in the Source page will drive
		 * selection in the Design page. Prefer post selection.
		 */
		ISelectionProvider provider = getTextEditor().getSelectionProvider();
		if (fTextEditorSelectionListener == null) {
			fTextEditorSelectionListener = new TextEditorPostSelectionAdapter();
		}
		if (provider instanceof IPostSelectionProvider) {
			fTextEditorSelectionListener.forcePostSelection = false;
			((IPostSelectionProvider) provider).addPostSelectionChangedListener(fTextEditorSelectionListener);
		}
		else {
			fTextEditorSelectionListener.forcePostSelection = true;
			provider.addSelectionChangedListener(fTextEditorSelectionListener);
		}
	}

	/**
	 * Create and Add the Design Page using a registered factory
	 * 
	 */
	private void createAndAddDesignPage() {
		IDesignViewer designViewer = createDesignPage();

		fDesignViewer = designViewer;
		// note: By adding the design page as a Control instead of an
		// IEditorPart, page switches will indicate
		// a "null" active editor when the design page is made active
		if (fDesignContainer != null)
			fDesignPageIndex = addPage(fDesignContainer);
		else
			fDesignPageIndex = addPage(designViewer.getControl());
			
		setPageText(fDesignPageIndex, designViewer.getTitle());
	}

	protected IDesignViewer createDesignPage() {		
		Composite container = getDesignContainer(getContainer());

		XMLTableTreeViewer tableTreeViewer = new XMLTableTreeViewer(container);
		tableTreeViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
		// Set the default info-pop for XML design viewer.
		XMLUIPlugin.getInstance().getWorkbench().getHelpSystem().setHelp(tableTreeViewer.getControl(), XMLTableTreeHelpContextIds.XML_DESIGN_VIEW_HELPID);

		// Toolbar wasn't allocated
		if (fToolbarManager != null) {
			addToolBarActions(tableTreeViewer);
		}
		return tableTreeViewer;
	}

	protected Composite getDesignContainer(Composite defaultContainer) {
		Composite container = defaultContainer;
		// create a container to hold the toolbar if it should be created
		if (fAllocateToolbar) {
			container = new Composite(defaultContainer, SWT.NONE);
			GridLayout layout = new GridLayout();
			layout.marginHeight = 0;
			layout.verticalSpacing = 0;
			layout.marginWidth = 0;
			container.setLayout(layout);
	
			ToolBar tb = new ToolBar(container, SWT.FLAT);
			fToolbarManager = new ToolBarManager(tb);
			tb.setLayoutData(new GridData(GridData.END, GridData.VERTICAL_ALIGN_BEGINNING, true, false));
			fDesignContainer = container;
		}
		return container;
	}

	private void addToolBarActions(IDesignViewer viewer) {
		if (viewer instanceof AbstractTreeViewer) {
			ViewerExpandCollapseAction expand = new ViewerExpandCollapseAction(true);
			ViewerExpandCollapseAction collapse = new ViewerExpandCollapseAction(false);
			fToolbarManager.add(expand);
			fToolbarManager.add(collapse);
			fToolbarManager.update(true);
	
	
			expand.setViewer((AbstractTreeViewer) viewer);
			collapse.setViewer((AbstractTreeViewer) viewer);
		}
	}

	/**
	 * Creates the pages of this multi-page editor.
	 * <p>
	 * Subclasses of <code>MultiPageEditor</code> must implement this method.
	 * </p>
	 */
	protected void createPages() {
		try {
			// source page MUST be created before design page, now
			createSourcePage();

			createAndAddDesignPage();
			addSourcePage();
			connectDesignPage();

			// set the active editor in the action bar contributor first
			// before setactivepage calls action bar contributor's
			// setactivepage (bug141013 - remove when bug151488 is fixed)
			IEditorActionBarContributor contributor = getEditorSite().getActionBarContributor();
			if (contributor instanceof MultiPageEditorActionBarContributor) {
				((MultiPageEditorActionBarContributor) contributor).setActiveEditor(this);
			}

			int activePageIndex = getPreferenceStore().getInt(IXMLPreferenceNames.LAST_ACTIVE_PAGE);
			if ((activePageIndex >= 0) && (activePageIndex < getPageCount())) {
				setActivePage(activePageIndex);
			}
			else {
				setActivePage(fSourcePageIndex);
			}
		}
		catch (PartInitException e) {
			Logger.logException(e);
			throw new RuntimeException(e);
		}
	}

	/**
	 * @see org.eclipse.ui.part.MultiPageEditorPart#createSite(org.eclipse.ui.IEditorPart)
	 */
	protected IEditorSite createSite(IEditorPart editor) {
		IEditorSite site = null;
		if (editor == fTextEditor) {
			site = new MultiPageEditorSite(this, editor) {
				/**
				 * @see org.eclipse.ui.part.MultiPageEditorSite#getActionBarContributor()
				 */
				public IEditorActionBarContributor getActionBarContributor() {
					IEditorActionBarContributor contributor = super.getActionBarContributor();
					IEditorActionBarContributor multiContributor = XMLMultiPageEditorPart.this.getEditorSite().getActionBarContributor();
					if (multiContributor instanceof XMLMultiPageEditorActionBarContributor) {
						contributor = ((XMLMultiPageEditorActionBarContributor) multiContributor).sourceViewerActionContributor;
					}
					return contributor;
				}

				public String getId() {
					// sets this id so nested editor is considered xml source
					// page
					return ContentTypeIdForXML.ContentTypeID_XML + ".source"; //$NON-NLS-1$;
				}
			};
		}
		else {
			site = super.createSite(editor);
		}
		return site;
	}

	/**
	 * Creates the source page of the multi-page editor.
	 */
	protected void createSourcePage() throws PartInitException {
		fTextEditor = createTextEditor();
		fTextEditor.setEditorPart(this);

		/*
		 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=134301 - XML editor
		 * does not remember font settings
		 * 
		 * @see
		 * org.eclipse.ui.texteditor.AbstractTextEditor#getSymbolicFontName()
		 */
		fPageInitializer.sendInitializationData(fTextEditor);

		if (fPropertyListener == null) {
			fPropertyListener = new PropertyListener();
		}
		fTextEditor.addPropertyListener(fPropertyListener);
	}

	/**
	 * Method createTextEditor.
	 * 
	 * @return StructuredTextEditor
	 */
	private StructuredTextEditor createTextEditor() {
		return new StructuredTextEditor();
	}

	private void disconnectDesignPage() {
		if (fDesignViewer != null) {
			fDesignViewer.setDocument(null);
		}
	}

	public void dispose() {
		Logger.trace("Source Editor", "XMLMultiPageEditorPart::dispose entry"); //$NON-NLS-1$ //$NON-NLS-2$

		disconnectDesignPage();

		if (fActivationListener != null) {
			fActivationListener.dispose();
			fActivationListener = null;
		}

		if ((fTextEditor != null) && (fPropertyListener != null)) {
			fTextEditor.removePropertyListener(fPropertyListener);
		}
		
		// moved to last when added window ... seems like
		// we'd be in danger of losing some data, like site,
		// or something.
		super.dispose();

		Logger.trace("Source Editor", "StructuredTextMultiPageEditorPart::dispose exit"); //$NON-NLS-1$ //$NON-NLS-2$

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void doSave(IProgressMonitor monitor) {
		fTextEditor.doSave(monitor);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.ISaveablePart#doSaveAs()
	 */
	public void doSaveAs() {
		fTextEditor.doSaveAs();
		/*
		 * Update the design viewer since the editor input would have changed
		 * to the new file.
		 */
		if (fDesignViewer != null) {
			fDesignViewer.setDocument(getDocument());
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class key) {
		Object result = null;

		// we extend superclass, not override it, so allow it first
		// chance to satisfy request.
		result = super.getAdapter(key);

		if (result == null) {
			if (key == IDesignViewer.class) {
				result = fDesignViewer;

			}
			else if (key.equals(IGotoMarker.class)) {
				result = new IGotoMarker() {
					public void gotoMarker(IMarker marker) {
						XMLMultiPageEditorPart.this.gotoMarker(marker);
					}
				};
			}
			else {
				/*
				 * DMW: I'm bullet-proofing this because its been reported (on
				 * very early versions) a null pointer sometimes happens here
				 * on startup, when an editor has been left open when
				 * workbench shutdown.
				 */
				if (fTextEditor != null) {
					result = fTextEditor.getAdapter(key);
				}
			}
		}
		return result;
	}

	private IDocument getDocument() {
		IDocument document = null;
		if (fTextEditor != null) {
			document = fTextEditor.getDocumentProvider().getDocument(fTextEditor.getEditorInput());
		}
		return document;
	}

	private IPreferenceStore getPreferenceStore() {
		return XMLUIPlugin.getDefault().getPreferenceStore();
	}

	StructuredTextEditor getTextEditor() {
		return fTextEditor;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPart#getTitle()
	 */
	public String getTitle() {
		String title = null;
		if (getTextEditor() == null) {
			if (getEditorInput() != null) {
				title = getEditorInput().getName();
			}
		}
		else {
			title = getTextEditor().getTitle();
		}
		if (title == null) {
			title = getPartName();
		}
		return title;
	}

	void gotoMarker(IMarker marker) {
		setActivePage(fSourcePageIndex);
		IDE.gotoMarker(fTextEditor, marker);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite,
	 * org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		try {
			super.init(site, input);
			// we want to listen for our own activation
			fActivationListener = new ActivationListener(site.getWorkbenchWindow().getPartService());
		}
		catch (Exception e) {
			Logger.logException("exception initializing " + getClass().getName(), e); //$NON-NLS-1$
		}
		setPartName(input.getName());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
	 */
	public boolean isSaveAsAllowed() {
		return (fTextEditor != null) && fTextEditor.isSaveAsAllowed();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.ISaveablePart#isSaveOnCloseNeeded()
	 */
	public boolean isSaveOnCloseNeeded() {
		// overriding super class since it does a lowly isDirty!
		if (fTextEditor != null) {
			return fTextEditor.isSaveOnCloseNeeded();
		}
		return isDirty();
	}
	
	/**
	 * Prevents the creation of the in-editor toolbar, if called before
	 * createPageContainer() during editor initialization.
	 */
	protected final void noToolbar() {
		fAllocateToolbar = false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.MultiPageEditorPart#pageChange(int)
	 */
	protected void pageChange(int newPageIndex) {
		super.pageChange(newPageIndex);
		saveLastActivePageIndex(newPageIndex);

		if (newPageIndex == fDesignPageIndex) {
			// design page isn't an IEditorPart, therefore we have to send
			// selection changes ourselves
			ISelectionProvider selectionProvider = fDesignViewer.getSelectionProvider();
			if (selectionProvider != null) {
				SelectionChangedEvent event = new SelectionChangedEvent(selectionProvider, selectionProvider.getSelection());
				((MultiPageSelectionProvider) getSite().getSelectionProvider()).fireSelectionChanged(event);
				((MultiPageSelectionProvider) getSite().getSelectionProvider()).firePostSelectionChanged(event);
			}
		}
	}

	private void saveLastActivePageIndex(int newPageIndex) {
		// save the last active page index to preference manager
		getPreferenceStore().setValue(IXMLPreferenceNames.LAST_ACTIVE_PAGE, newPageIndex);
	}

	public void setFocus() {
		super.setFocus();
		Control control = fDesignViewer.getControl();
		control.setFocus();
		// 271382 - Focus not set properly after activating XML editor
		control.forceFocus();
	}

	public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data) {
		super.setInitializationData(cfig, propertyName, data);
		fPageInitializer = new PageInitializationData(cfig, propertyName, data);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
	 */
	protected void setInput(IEditorInput input) {
		/*
		 * If driven from the Source page, it's "model" may not be up to date
		 * with (or even exist for) the input just yet. Later notification
		 * from the TextViewer could set us straight, although it's not
		 * guaranteed to happen after the model has been created.
		 */
		super.setInput(input);
		if (fDesignViewer != null) {
			fDesignViewer.setDocument(getDocument());
		}
		setPartName(input.getName());
	}

	void updateStatusLine(ISelection selection) {
		IStatusLineManager statusLineManager = getEditorSite().getActionBars().getStatusLineManager();
		if (fStatusLineLabelProvider != null && statusLineManager != null) {
			String text = null;
			Image image = null;
			if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
				Object firstElement = ((IStructuredSelection) selection).getFirstElement();
				if (firstElement != null) {
					text = fStatusLineLabelProvider.getText(firstElement);
					image = fStatusLineLabelProvider.getImage((firstElement));
				}
			}
			if (image == null) {
				statusLineManager.setMessage(text);
			}
			else {
				statusLineManager.setMessage(image, text);
			}
		}
	}
}