/*******************************************************************************
 *  Copyright (c) 2012-2014 SAP SE.
 *  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:
 *  SAP SE - initial API and implementation and/or initial documentation
 *
 *******************************************************************************/
package org.eclipse.ogee.designer;

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.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.graphiti.ui.editor.DiagramEditorInput;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DecorationOverlayIcon;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.ogee.designer.messages.Messages;
import org.eclipse.ogee.designer.pages.EDMXReferencePage;
import org.eclipse.ogee.designer.utils.ArtifactUtil;
import org.eclipse.ogee.designer.utils.IODataEditorConstants;
import org.eclipse.ogee.model.api.IModelContext;
import org.eclipse.ogee.model.api.ModelAPIException;
import org.eclipse.ogee.model.odata.EDMXSet;
import org.eclipse.ogee.utils.logger.Logger;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabFolder2Listener;
import org.eclipse.swt.custom.CTabFolderEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ogee.help.IHelpConstants;

/**
 * The following class implements a MultiPageEditor with an OData Model Editor &
 * EDMX Reference page.
 * 
 */
public class ODataMultiPageEditor extends MultiPageEditorPart {

	private CTabFolder tabFolder;
	private int defaultTabHeight;
	private ODataEditor designEditor = null;
	private IFile modelFile;
	private boolean isSourceDeleted = false;
	private IFile resource;
	private Image odataTitleImage;
	private ODataDiagramListener odataListener;
	private EDMXReferencePage edmxReferencePage;

	private boolean isReadOnly = false;

	/**
	 * Creates a multi-page editor.
	 */
	public ODataMultiPageEditor() {
		super();
	}

	/**
	 * The resource listener updates the receiver when a change has occurred.
	 */
	private IResourceChangeListener resourceListener = new IResourceChangeListener() {

		/*
		 * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent)
		 */
		@Override
		public void resourceChanged(IResourceChangeEvent event) {

			final IResourceDelta mainDelta = event.getDelta();
			if (mainDelta == null) {
				return;
			}
			final IResourceDelta affectedElement = mainDelta
					.findMember(getResource().getFullPath());
			if (affectedElement != null) {
				this.processDelta(affectedElement);
			}
			if (isMarkerChangedForResource(event)) {
				// Changes in markers on this resource, so re-decorate title
				// image
				decorateTitleImage();
			}
		}

		/*
		 * Checks if there is any change in marker for the resource.
		 */
		private boolean isMarkerChangedForResource(
				final IResourceChangeEvent event) {

			boolean isMarkerChangeForThisResource = false;

			if (ResourceUtil.getResource(getEditorInput()) != null) {
				final IPath path = ResourceUtil.getResource(getEditorInput())
						.getFullPath();
				final IResourceDelta delta = event.getDelta().findMember(path);
				isMarkerChangeForThisResource = (delta != null)
						&& ((delta.getFlags() & IResourceDelta.MARKERS) != 0);
			}

			return isMarkerChangeForThisResource;
		}

		/*
		 * Process the delta for the receiver
		 */
		private boolean processDelta(final IResourceDelta delta) {

			Runnable changeRunnable = null;

			switch (delta.getKind()) {
			case IResourceDelta.REMOVED:
				if ((IResourceDelta.MOVED_TO & delta.getFlags()) != 0) {
					changeRunnable = new Runnable() {
						@Override
						public void run() {
							final IPath path = delta.getMovedToPath();
							final IFile newFile = delta.getResource()
									.getWorkspace().getRoot().getFile(path);
							if (newFile != null) {
								sourceChanged(newFile);
							}
						}
					};
				} else {
					changeRunnable = new Runnable() {
						@Override
						public void run() {
							setSourceDeleted(true);
							getSite().getPage().closeEditor(
									ODataMultiPageEditor.this, true);
							setDesignEditor(null);
						}
					};
				}
				break;
			case IResourceDelta.CHANGED:
				if ((IResourceDelta.MARKERS & delta.getFlags()) != 0) {
					changeRunnable = new Runnable() {
						@Override
						public void run() {
							if (getDesignEditor() != null) {
								getDesignEditor().getDiagramBehavior();
							}
						}
					};
				}
				break;
			default:
				break;
			}
			if (changeRunnable != null) {
				update(changeRunnable);
			}

			return true;
		}
	};

	/**
	 * decorates the title image with error decorators.
	 */
	public void decorateTitleImage() {

		final Shell shell = this.getEditorSite().getShell();
		if (shell != null && !shell.isDisposed()) {
			shell.getDisplay().syncExec(new Runnable() {
				@Override
				public void run() {
					final Image decoratedImage = decorateImage(getTitleImage(),
							getSeverity());
					if (decoratedImage != null) {
						updateTitleImage(decoratedImage);
					}
				}
			});
		}
	}

	/**
	 * @param image
	 *            - updated title image with error decorator if any.
	 */
	public void updateTitleImage(final Image image) {

		setTitleImage(image);
	}

	protected Image decorateImage(Image titleImage, int severity) {

		ImageDescriptor descriptor = null;
		Image decoratedTitleImage = null;

		if (severity == IMarker.PRIORITY_HIGH) {
			descriptor = ImageDescriptor.createFromURL(FileLocator.find(
					Activator.getDefault().getBundle(), new Path(
							"/icons/error_co.gif"), null)); //$NON-NLS-1$
		}
		if (severity == IMarker.PRIORITY_NORMAL) {
			descriptor = ImageDescriptor.createFromURL(FileLocator.find(
					Activator.getDefault().getBundle(), new Path(
							"/icons/warning_co.gif"), null)); //$NON-NLS-1$
		}
		if (decoratedTitleImage == null
				&& (severity == IMarker.PRIORITY_HIGH || severity == IMarker.PRIORITY_NORMAL)) {
			decoratedTitleImage = new DecorationOverlayIcon(titleImage,
					descriptor, IDecoration.BOTTOM_LEFT).createImage();
		} else {
			descriptor = ImageDescriptor.createFromURL(FileLocator.find(
					Activator.getDefault().getBundle(), new Path(
							"/icons/odata.png"), null)); //$NON-NLS-1$
			if (descriptor != null) {
				decoratedTitleImage = descriptor.createImage();
			}
		}

		if (decoratedTitleImage == null) {
			decoratedTitleImage = titleImage;
		}

		return decoratedTitleImage;
	}

	protected int getSeverity() {

		int severity = 0;

		try {
			if (ResourceUtil.getResource(getEditorInput()) != null) {
				severity = ResourceUtil.getResource(getEditorInput())
						.findMaxProblemSeverity(IMarker.PROBLEM, true,
								IResource.DEPTH_INFINITE);
			}
		} catch (CoreException e) {
			// Might be a project that is not open
		}

		return severity;
	}

	/**
	 * The source has changed to the newFile. Update editors and set any
	 * required flags
	 * 
	 * @param newFile
	 *            The file to get the new contents from.
	 */
	protected void sourceChanged(IFile newFile) {

		this.modelFile = newFile;
		final FileEditorInput newInput = new FileEditorInput(newFile);
		setInputWithNotify(newInput);
		setPartName(newInput.getName());
		setTitleToolTip(newFile.getFullPath().makeRelative().toString());
		if (getDesignEditor() != null) {
			getDesignEditor().setModelFile(newFile);
			getDesignEditor().getDiagramBehavior().refresh();
		}
	}

	/**
	 * Posts the update code "behind" the running operation.
	 * 
	 * @param runnable
	 *            the update code
	 */
	protected void update(Runnable runnable) {

		final IWorkbench workbench = PlatformUI.getWorkbench();
		final IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
		if (windows != null && windows.length > 0) {
			final Display display = windows[0].getShell().getDisplay();
			display.asyncExec(runnable);
		} else {
			runnable.run();
		}
	}

	/**
	 * Initializes the editor when created from scratch.
	 * 
	 * This method is called soon after part construction and marks the start of
	 * the extension lifecycle. At the end of the extension lifecycle
	 * <code>shutdown will be invoked
	 * to terminate the lifecycle.
	 * 
	 * @param site
	 * @param input
	 *            - The initial input element for the editor. In most cases it
	 *            is an <code>IFile but other types are acceptable.
	 */
	@Override
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {

		try {
			if (input instanceof IFileEditorInput) {
				this.modelFile = ((IFileEditorInput) input).getFile();
				// OData file is read only
				this.isReadOnly = ((IFileEditorInput) input).getFile()
						.isReadOnly();

			} else if (input instanceof DiagramEditorInput) {
				URI uri = ((DiagramEditorInput) input).getUri();
				String uriString = uri.trimFragment().toPlatformString(true);
				this.modelFile = this.getModelFile(new Path(uriString));
				// OData file is read only
				this.isReadOnly = getModelFile(new Path(uriString))
						.isReadOnly();
			}
			setSite(site);
			setInput(input);
			setInputWithNotify(input);
			// Update titles.
			setTitleToolTip(input.getToolTipText());
			final ImageDescriptor imageDesc = input.getImageDescriptor();
			if (imageDesc != null) {
				this.odataTitleImage = imageDesc.createImage();
				setTitleImage(this.odataTitleImage);
			}
			decorateTitleImage();
			super.init(site, input);
		} catch (PartInitException e) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(e);
			throw new PartInitException(new Status(IStatus.ERROR,
					Activator.PLUGIN_ID, e.getMessage(), e));
		} catch (Exception t) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(t);
			throw new PartInitException(new Status(IStatus.ERROR,
					Activator.PLUGIN_ID, t.getMessage(), t));
		}
	}

	@Override
	protected void setInputWithNotify(IEditorInput input) {

		if (input instanceof IFileEditorInput
				|| input instanceof DiagramEditorInput
				|| input instanceof ODataEditorInput) {
			if (this.getResource() == null) {
				ResourcesPlugin.getWorkspace().addResourceChangeListener(
						this.resourceListener);
			}
			this.setResource(this.modelFile);
		}

		super.setInputWithNotify(input);
	}

	@Override
	public void doSave(IProgressMonitor monitor) {

		if (this.designEditor != null) {
			this.designEditor.doSave(monitor);
		}
		try {
			if (this.resource != null) {
				this.resource.refreshLocal(IResource.DEPTH_ZERO, monitor);
			}
		} catch (CoreException ex) {
			// Do nothing on a failed refresh
		}
	}

	@Override
	public void doSaveAs() {

		final IEditorPart activeEditor = getActiveEditor();
		if (activeEditor != null) {
			activeEditor.doSaveAs();
		}
	}

	@Override
	public boolean isSaveAsAllowed() {

		boolean isSaveAsAllowed = false;

		/*
		 * Depending upon the active page in multi-page editor, call the
		 * saveAsAllowed. It helps to see whether a particular editor allows
		 * 'save as' feature
		 */
		final IEditorPart activeEditor = getActiveEditor();
		if (activeEditor != null) {
			isSaveAsAllowed = activeEditor.isSaveAsAllowed();
		}

		return isSaveAsAllowed;
	}

	/*
	 * See IEditorPart.isSaveOnCloseNeeded()
	 */
	@Override
	public boolean isSaveOnCloseNeeded() {

		return !this.isSourceDeleted() && super.isSaveOnCloseNeeded();
	}

	@Override
	public void dispose() {

		super.dispose();

		if (this.getResource() != null) {
			ResourcesPlugin.getWorkspace().removeResourceChangeListener(
					this.resourceListener);
			this.resourceListener = null;
			this.setResource(null);
		}
		// can dispose the title image because it was created in init
		if (this.odataTitleImage != null) {
			this.odataTitleImage.dispose();
			this.odataTitleImage = null;
		}
		if (this.odataListener != null) {
			this.odataListener.removeListeners();
			this.odataListener = null;
		}
		this.modelFile = null;
		this.designEditor = null;
		this.tabFolder = null;
		if (this.edmxReferencePage != null) {
			this.edmxReferencePage.dispose();
			this.edmxReferencePage = null;
		}
	}

	@Override
	public String getTitle() {

		if (this.designEditor != null) {

			return this.designEditor.getTitle();

		}

		return super.getTitle();
	}

	@Override
	public String getPartName() {

		if (this.modelFile != null) {
			// if odata file is read-only
			if (this.modelFile.isReadOnly()) {
				String title = this.modelFile.getName()
						+ Messages.ODataMultiPageEditor_0;
				return title;
			} else {
				if (IODataEditorConstants.TEMPFILE_EXTENSION
						.equals(this.modelFile.getFileExtension())) {
					return this.modelFile.getFullPath().removeFileExtension()
							.lastSegment();
				}
				return this.modelFile.getName();
			}
		}

		return super.getPartName();
	}

	@Override
	public String getTitleToolTip() {

		if (this.modelFile != null) {
			if (IODataEditorConstants.TEMPFILE_EXTENSION.equals(this.modelFile
					.getFileExtension())) {
				if (this.getEditorInput() instanceof ODataEditorInput) {
					final ODataEditorInput input = (ODataEditorInput) this
							.getEditorInput();
					final String titleToolTip = input.getGWConnectionName()
							+ "/" + this.modelFile.getFullPath().removeFileExtension().lastSegment(); //$NON-NLS-1$
					return titleToolTip;
				}
				return this.modelFile.getFullPath().removeFileExtension()
						.lastSegment();
			}
			return this.modelFile.getFullPath().makeRelative().toString();
		}

		return super.getTitleToolTip();
	}

	@Override
	public void removePage(int pageIndex) {

		Object page = this.tabFolder.getItem(pageIndex).getData();
		if (page instanceof EditorPart) {
			// make sure the editor gets disposed - neither CTabFolder nor super
			// does this for us!
			((EditorPart) page).dispose();
		}
		super.removePage(pageIndex);
		updateTabs();
	}

	/**
	 * remove Source Viewer
	 */
	public void removeSourceViewer() {

	}

	@Override
	protected void createPages() {

		this.tabFolder = (CTabFolder) getContainer();
		this.tabFolder.addCTabFolder2Listener(new CTabFolder2Listener() {
			@Override
			public void close(CTabFolderEvent event) {
			}

			@Override
			public void minimize(CTabFolderEvent event) {
			}

			@Override
			public void maximize(CTabFolderEvent event) {
			}

			@Override
			public void restore(CTabFolderEvent event) {
			}

			@Override
			public void showList(CTabFolderEvent event) {
			}
		});
		try {
			createDesignEditor();
			// TODO Start - Enable with OData V4 support
			// createEDMXReferencePage();
			// End - Enable with OData V4 support
		} catch (CoreException e) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(e);
		}
	}

	/**
	 * @return ODataEditor
	 */
	public ODataEditor getDesignEditor() {
		return this.designEditor;
	}

	/**
	 * @param designEditor
	 */
	public void setDesignEditor(final ODataEditor designEditor) {
		this.designEditor = designEditor;
	}

	private void updateTabs() {
		if (this.tabFolder.getItemCount() == 1) {
			this.tabFolder.setTabHeight(0);
		} else {
			this.tabFolder.setTabHeight(this.defaultTabHeight);
		}
		this.tabFolder.layout();
	}

	private IFile getModelFile(IPath fullPath) {
		return ResourcesPlugin.getWorkspace().getRoot()
				.getFile(fullPath.makeAbsolute());
	}

	private void createDesignEditor() throws CoreException {

		if (this.designEditor == null) {
			this.designEditor = new DesignEditor();
			try {
				int pageIndex = this.tabFolder.getItemCount();
				addPage(pageIndex, this.designEditor,
						ODataMultiPageEditor.this.getEditorInput());
				this.defaultTabHeight = this.tabFolder.getTabHeight();
				setPageText(pageIndex,
						Messages.ODATA_MULTIPAGE_EDITOR_MODEL_TAB);
				this.defaultTabHeight = this.tabFolder.getTabHeight();
				updateTabs();
				this.odataListener = new ODataDiagramListener(this.designEditor);
				this.odataListener.registerListeners();

			} catch (Exception e) {
				Logger.getLogger(Activator.PLUGIN_ID).logError(e);
				throw new CoreException(new Status(IStatus.ERROR,
						Activator.PLUGIN_ID, e.getMessage(), e));
			}
		}
	}

	/*
	 * EDMX References Page.
	 */
	private void createEDMXReferencePage() {

		EDMXSet edmxSet = null;
		// boolean isReadOnly = false;

		final IEditorInput editorInput = getEditorInput();
		// Editor is invoked from IODataDiagramCreator#createDiagram() API.
		if (editorInput instanceof ODataEditorInput) {
			final ODataEditorInput odataEditorInput = (ODataEditorInput) getEditorInput();
			edmxSet = odataEditorInput.getDiagramInput().getEDMXSet();
			isReadOnly = odataEditorInput.getDiagramInput().isReadOnlyMode();
		}
		// Editor is invoked from Project Explorer or when eclipse IDE is
		// launched.
		else if (editorInput instanceof FileEditorInput
				|| editorInput instanceof DiagramEditorInput) {
			try {
				final TransactionalEditingDomain editingDomain = IModelContext.INSTANCE
						.getTransaction(this.modelFile);
				final String path = this.modelFile.getFullPath().toString();
				final URI uri = URI.createPlatformResourceURI(path, true);
				ResourceSet resourceSet = null;
				if (editingDomain != null) {
					resourceSet = editingDomain.getResourceSet();
				} else {
					resourceSet = new ResourceSetImpl();
				}
				final Resource model = resourceSet.getResource(uri, true);
				if (model instanceof XMIResource) {
					edmxSet = ArtifactUtil.getEDMXSetFromModel(model);
				}

				// OData file is read only
				if (editorInput instanceof FileEditorInput) {
					final FileEditorInput fileEditorInput = (FileEditorInput) getEditorInput();
					this.isReadOnly = fileEditorInput.getFile().isReadOnly();

				}
				if (editorInput instanceof DiagramEditorInput) {
					final DiagramEditorInput diagramEditorInput = (DiagramEditorInput) getEditorInput();
					final URI uriDiagram = diagramEditorInput.getUri();
					final String uriString = uriDiagram.trimFragment()
							.toPlatformString(true);
					this.isReadOnly = getModelFile(new Path(uriString))
							.isReadOnly();
				}

			} catch (ModelAPIException e) {
				Logger.getLogger(Activator.PLUGIN_ID).logError(e);
			}
		}
		final int pageIndex = this.tabFolder.getItemCount();
		this.edmxReferencePage = new EDMXReferencePage(this.getContainer(),
				edmxSet, isReadOnly, getEditorSite(), getDesignEditor());
		addPage(this.edmxReferencePage);
		this.tabFolder.getItem(pageIndex).setShowClose(false);
		setPageText(pageIndex, Messages.ODATA_MULTIPAGE_EDITOR_REF_TAB);
		updateTabs();
	}

	/**
	 * @return an instance of IFile
	 */
	public IFile getResource() {

		return this.resource;
	}

	/**
	 * @param resource
	 *            - IFile
	 */
	public void setResource(final IFile resource) {

		this.resource = resource;
	}

	/**
	 * The isSourceDeleted flag makes sure that the receiver is not dirty when
	 * shutting down.
	 * 
	 * @return boolean is Source Deleted
	 */
	public boolean isSourceDeleted() {

		return this.isSourceDeleted;
	}

	/**
	 * The isSourceDeleted flag makes sure that the receiver is not dirty when
	 * shutting down.
	 * 
	 * @param isSourceDeleted
	 *            - boolean
	 */
	public void setSourceDeleted(boolean isSourceDeleted) {

		this.isSourceDeleted = isSourceDeleted;
	}

	/**
	 * @author I057523
	 * 
	 */
	public class DesignEditor extends ODataEditor {

		@Override
		protected void createActions() {
			super.createActions();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.MultiPageEditorPart#setFocus()
	 */
	@Override
	public void setFocus() {

		super.setFocus();
		int activePage = getActivePage();
		switch (activePage) {
		case 0:

			if (this.designEditor != null) {
				final GraphicalViewer graphicalViewer = this.designEditor
						.getGraphicalViewer();
				if (graphicalViewer != null) {
					final Control control = graphicalViewer.getControl();
					/*PlatformUI
							.getWorkbench()
							.getHelpSystem()
							.setHelp(control,
									IODataEditorConstants.HELP_CONTEXT_ID);*/
					PlatformUI.getWorkbench().getHelpSystem()
					.setHelp(control, IHelpConstants.HELP_CONTEXT_ID);
				}
			}
			break;
		case 1:
			/*PlatformUI
					.getWorkbench()
					.getHelpSystem()
					.setHelp(
							this.edmxReferencePage,
							IODataEditorConstants.HELP_CONTEXT_ID_EDMXREFERENCES);*/
			PlatformUI
			.getWorkbench()
			.getHelpSystem()
			.setHelp(this.edmxReferencePage,
					IHelpConstants.HELP_CONTEXT_ID_EDMXREFERENCES);

			break;
		default:
			break;
		}

	}

	/**
	 * @return instance of EDMXReferencePage.
	 */
	public EDMXReferencePage getEdmxReferencePage() {

		return this.edmxReferencePage;
	}

}
