package org.camunda.bpm.modeler.ui.diagram.editor;

import org.camunda.bpm.modeler.core.Activator;
import org.camunda.bpm.modeler.core.files.FileService;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.part.MultiPageEditorSite;
import org.eclipse.wst.sse.ui.StructuredTextEditor;

/**
 * A multi page editor for BPMN 2.0 files showing the diagram file
 * and the (editable) xml source.
 * 
 * This editor is able to handle all kinds of {@link IEditorInput} that
 * have a resource uri and may be converted to {@link FileEditorInput}.
 * 
 * It shows the BPMN editors part name and tooltip and displays the dirty
 * state of the currently active editor. To save, it delegates that to the
 * currently active editor, too.
 * 
 * @author nico.rehwaldt
 */
public class Bpmn2MultiPageEditor extends MultiPageEditorPart {

	private Bpmn2Editor bpmnEditor;
	private StructuredTextEditor xmlEditor;
	
	@Override
	protected IEditorSite createSite(IEditorPart editor) {
		IEditorSite site = null;
		if (editor == xmlEditor) {
			site = new MultiPageEditorSite(this, editor) {
				public String getId() {
					// sets this id so nested editor is considered xml source page
					return "org.eclipse.core.runtime.xml.source";
				}
			};
		}	else {
			site = super.createSite(editor);
		}
		return site;
	}

	@Override
	protected void setInput(IEditorInput input) {
		// convert input to a file input
		// to unify handling
		if (!(input instanceof FileEditorInput)) {
			input = convertToFileInput(input);
		}

		super.setInput(input);
	}

	@Override
	protected void createPages() {

		IConfigurationElement configurationElement = getConfigurationElement();
		
		bpmnEditor = new Bpmn2Editor();
		bpmnEditor.setInitializationData(configurationElement, null, null);
		
		xmlEditor = new StructuredTextEditor();
		xmlEditor.setInitializationData(configurationElement, null, null);

		IEditorInput input = getEditorInput();
		
		try {
			addPage(bpmnEditor, input);
		} catch (PartInitException e) {
			Activator.logError(e);
		}
		
		setPageText(0, "Design");
		
		try {
			addPage(xmlEditor, input);
		} catch (PartInitException e) {
			Activator.logError(e);
		}
		
		setPageText(1, "Source");
		
		setPartName(bpmnEditor.getTitle());
	}
	
	@Override
	public String getTitleToolTip() {
		if (bpmnEditor != null) {
			return bpmnEditor.getTitleToolTip();
		} else {
			return super.getTitleToolTip();
		}
	}
	
	@Override
	public String getPartName() {
		if (bpmnEditor != null) {
			return bpmnEditor.getPartName();
		} else {
			return super.getPartName();
		}
	}
	
	/**
	 * Converts an editor input to a file input
	 * 
	 * @param input
	 * @return
	 */
	protected IEditorInput convertToFileInput(IEditorInput input) {
		try {
			URI workspaceUri = FileService.resolveAsWorkspaceResource(FileService.getInputUri(input));
			IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(workspaceUri.toPlatformString(true)));
			return new FileEditorInput(file);
		} catch (CoreException e) {
			throw new IllegalStateException("Failed to resolve input", e);
		}
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		getActiveEditor().doSave(monitor);
	}

	@Override
	public void doSaveAs() {
		getActiveEditor().doSaveAs();
	}

	@Override
	public boolean isSaveAsAllowed() {
		IEditorPart activeEditor = getActiveEditor();
		return activeEditor != null && activeEditor.isSaveAsAllowed();
	}
}

@@ -387,24 +387,77 @@
 essMonitor;%0A
+import org.eclipse.core.runtime.NullProgressMonitor;%0A
 import org.e
@@ -559,79 +559,21 @@
 ogs.
-IPageChangedListener;%0Aimport org.eclipse.jface.dialogs.PageChangedEvent
+MessageDialog
 ;%0Aim
@@ -709,32 +709,66 @@
 tInitException;%0A
+import org.eclipse.ui.PlatformUI;%0A
 import org.eclip
@@ -2895,32 +2895,725 @@
 %09%7D%0A%09%0A%09@Override%0A
+%09protected void pageChange(int newPageIndex) %7B%0A%09%09%0A%09%09int index = Math.abs(newPageIndex - 1);%0A%09%09%0A%09%09String editorName = getPageText(index);%0A%09%09IEditorPart editor = getEditor(index);%0A%09%09%0A%09%09if (editor != null && editor.isSaveOnCloseNeeded()) %7B%0A%09%09%09%0A%09%09%09boolean save = MessageDialog.openQuestion(%0A%09%09%09%09%09PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),%0A%09%09%09%09%09%22Unsaved changes in %22 + editorName + %22 view%22, %0A%09%09%09%09%09%22You have unsaved changes in the %22 + editorName + %22 view that may lead to editing conflicts. Would you like to save these changes before you continue?%22);%0A%09%09%09%0A%09%09%09if (save) %7B%0A%09%09%09%09editor.doSave(new NullProgressMonitor());%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09super.pageChange(newPageIndex);%0A%09%7D%0A%09%0A%09@Override%0A
 %09public String g

add conflict warning on page change