/*******************************************************************************
 * Copyright (c) 2010, 2012 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.ui.internal.e4.compatibility;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.di.Persist;
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.ISaveablePart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPart2;
import org.eclipse.ui.IWorkbenchPartConstants;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.internal.ErrorEditorPart;
import org.eclipse.ui.internal.ErrorViewPart;
import org.eclipse.ui.internal.PartSite;
import org.eclipse.ui.internal.SaveableHelper;
import org.eclipse.ui.internal.ViewSite;
import org.eclipse.ui.internal.WorkbenchPage;
import org.eclipse.ui.internal.WorkbenchPartReference;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.util.Util;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;

public abstract class CompatibilityPart {

	public static final String COMPATIBILITY_EDITOR_URI = "bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor"; //$NON-NLS-1$

	public static final String COMPATIBILITY_VIEW_URI = "bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView"; //$NON-NLS-1$

	@Inject
	Composite composite;

	@Inject
	Logger logger;

	IWorkbenchPart wrapped;

	MPart part;

	@Inject
	private IEventBroker eventBroker;

	private boolean beingDisposed = false;

	private boolean alreadyDisposed = false;

	/**
	 * This handler will be notified when the part's widget has been un/set.
	 */
	private EventHandler widgetSetHandler = new EventHandler() {
		public void handleEvent(Event event) {
			// check that we're looking at our own part and that the widget is
			// being unset
			if (event.getProperty(UIEvents.EventTags.ELEMENT) == part
					&& event.getProperty(UIEvents.EventTags.NEW_VALUE) == null) {
				 Assert.isTrue(!composite.isDisposed(),
										"The widget should not have been disposed at this point"); //$NON-NLS-1$
				beingDisposed = true;
				WorkbenchPartReference reference = getReference();
				// notify the workbench we're being closed
				((WorkbenchPage) reference.getPage()).firePartHidden(part);
				((WorkbenchPage) reference.getPage()).firePartClosed(CompatibilityPart.this);
			}
		}
	};

	/**
	 * This handler will be notified when the part's client object has been
	 * un/set.
	 */
	private EventHandler objectSetHandler = new EventHandler() {
		public void handleEvent(Event event) {
			// check that we're looking at our own part and that the object is
			// being set
			if (event.getProperty(UIEvents.EventTags.ELEMENT) == part
					&& event.getProperty(UIEvents.EventTags.NEW_VALUE) != null) {
				WorkbenchPartReference reference = getReference();
				// notify the workbench we've been opened
				((WorkbenchPage) reference.getPage()).firePartOpened(CompatibilityPart.this);
			}
		}
	};

	CompatibilityPart(MPart part) {
		this.part = part;
	}

	public abstract WorkbenchPartReference getReference();

	protected boolean createPartControl(final IWorkbenchPart legacyPart, Composite parent) {
		try {
			legacyPart.createPartControl(parent);
		} catch (RuntimeException e) {
			logger.error(e);

			try {
				// couldn't create the part, dispose of it
				legacyPart.dispose();
			} catch (Exception ex) {
				// client code may have errors so we need to catch it
				logger.error(ex);
			}

			// dispose the site that was originally initialized for this part
			internalDisposeSite();

			// create a new error part notifying the user of the failure
			IStatus status = new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH,
					"Failed to create the part's controls", e); //$NON-NLS-1$
			WorkbenchPartReference reference = getReference();
			wrapped = reference.createErrorPart(status);
			try {
				reference.initialize(wrapped);
				wrapped.createPartControl(parent);
			} catch (RuntimeException ex) {
				// failed to create the error part, log it
				logger.error(ex);
			} catch (PartInitException ex) {
				WorkbenchPlugin.log("Unable to initialize error part", ex.getStatus()); //$NON-NLS-1$
			}
		}
		return true;
	}

	@Focus
	void delegateSetFocus() {
		try {
			wrapped.setFocus();
		} catch (Exception e) {
			if (logger != null) {
				String msg = "Error setting focus to : " + part.getClass().getName(); //$NON-NLS-1$
				msg += ' ' + part.getLocalizedLabel();
				logger.error(e, msg);
			}
		}
	}

	private void invalidate() {
		WorkbenchPartReference reference = getReference();
		reference.invalidate();

		if (wrapped != null) {
			try {
				wrapped.dispose();
			} catch (Exception e) {
				// client code may have errors so we need to catch it
				logger.error(e);
			}
		}

		internalDisposeSite();
		alreadyDisposed = true;
	}

	private String computeLabel() {
		if (wrapped instanceof IWorkbenchPart2) {
			String label = ((IWorkbenchPart2) wrapped).getPartName();
			return Util.safeString(label);
		}

		IWorkbenchPartSite site = wrapped.getSite();
		if (site != null) {
			return Util.safeString(site.getRegisteredName());
		}
		return Util.safeString(wrapped.getTitle());
	}

	/**
	 * Returns whether this part is being disposed. This is used for
	 * invalidating this part so that it is not returned when a method expects a
	 * "working" part.
	 * <p>
	 * See bug 308492.
	 * </p>
	 * 
	 * @return if the part is currently being disposed
	 */
	public boolean isBeingDisposed() {
		return beingDisposed;
	}

	IWorkbenchPart createPart(WorkbenchPartReference reference) throws PartInitException {
		// ask our reference to instantiate the part through the registry
		return reference.createPart();
	}

	boolean handlePartInitException(PartInitException e) {
		WorkbenchPartReference reference = getReference();
		reference.invalidate();
		if (wrapped instanceof IEditorPart) {
			try {
				wrapped.dispose();
			} catch (Exception ex) {
				// client code may have errors so we need to catch it
				logger.error(ex);
			}
		}
		internalDisposeSite();

		alreadyDisposed = false;
		WorkbenchPlugin.log("Unable to create part", e.getStatus()); //$NON-NLS-1$

		wrapped = reference.createErrorPart(e.getStatus());
		try {
			reference.initialize(wrapped);
		} catch (PartInitException ex) {
			WorkbenchPlugin.log("Unable to initialize error part", ex.getStatus()); //$NON-NLS-1$
			return false;
		}
		return true;
	}

	@PostConstruct
	public void create() {
		eventBroker.subscribe(UIEvents.UIElement.TOPIC_WIDGET, widgetSetHandler);
		eventBroker.subscribe(UIEvents.Contribution.TOPIC_OBJECT, objectSetHandler);

		WorkbenchPartReference reference = getReference();

		try {
			wrapped = createPart(reference);
			// invoke init methods
			reference.initialize(wrapped);
		} catch (PartInitException e) {
			if (!handlePartInitException(e)) {
				return;
			}
		}

		// hook reference listeners to the part
		// reference.hookPropertyListeners();

		Composite parent = new Composite(composite, SWT.NONE);
		parent.setLayout(new FillLayout());
		if (!createPartControl(wrapped, parent)) {
			return;
		}

		// Only update 'valid' parts
		if (!(wrapped instanceof ErrorEditorPart) && !(wrapped instanceof ErrorViewPart)) {
			part.setLabel(computeLabel());
			part.setTooltip(wrapped.getTitleToolTip());
			updateImages(part);
		}

		if (wrapped instanceof ISaveablePart) {
			part.setDirty(((ISaveablePart) wrapped).isDirty());
		}

		wrapped.addPropertyListener(new IPropertyListener() {
			public void propertyChanged(Object source, int propId) {
				switch (propId) {
				case IWorkbenchPartConstants.PROP_TITLE:
					part.setLabel(computeLabel());
					part.setTooltip(wrapped.getTitleToolTip());
					part.getTransientData().put(IPresentationEngine.OVERRIDE_TITLE_TOOL_TIP_KEY,
							wrapped.getTitle());

					updateImages(part);
					break;
				case IWorkbenchPartConstants.PROP_DIRTY:
					if (wrapped instanceof ISaveablePart) {
						((MDirtyable) part).setDirty(((ISaveablePart) wrapped).isDirty());
					}
					break;
				case IWorkbenchPartConstants.PROP_INPUT:
					WorkbenchPartReference ref = getReference();
					((WorkbenchPage) ref.getSite().getPage()).firePartInputChanged(ref);
					break;
				}
			}
		});
	}

	void updateTabImages(MUIElement element) {
		// Try to update the image if we're using a CTF
		MUIElement refParent = element.getParent();
		if (!(refParent instanceof MPartStack)) {
			return;
		}

		if (!(refParent.getWidget() instanceof CTabFolder)) {
			return;
		}

		CTabFolder ctf = (CTabFolder) refParent.getWidget();
		if (ctf.isDisposed()) {
			return;
		}

		CTabItem[] items = ctf.getItems();
		for (CTabItem item : items) {
			if (item.getData(AbstractPartRenderer.OWNING_ME) == element) {
				item.setImage(wrapped.getTitleImage());
			}
		}
	}

	abstract void updateImages(MPart part);

	public void deactivateActionBars(boolean forceHide) {
		PartSite site = getReference().getSite();
		site.deactivateActionBars(forceHide);
	}

	@PreDestroy
	void destroy() {
		if (!alreadyDisposed) {
			invalidate();
		}

		eventBroker.unsubscribe(widgetSetHandler);
		eventBroker.unsubscribe(objectSetHandler);
	}

	/**
	 * Disposes of the 3.x part's site if it has one. Subclasses may override
	 * but must call <code>super.disposeSite()</code> in its implementation.
	 */
	private void internalDisposeSite() {
		PartSite site = getReference().getSite();
		if (site != null) {
			disposeSite(site);
		}
	}

	/**
	 * Disposes of the 3.x part's site if it has one. Subclasses may override
	 * but must call <code>super.disposeSite()</code> in its implementation.
	 */
	void disposeSite(PartSite site) {
		deactivateActionBars(site instanceof ViewSite);
		site.dispose();
	}

	@Persist
	void doSave() {
		if (wrapped instanceof ISaveablePart) {
			SaveableHelper.savePart((ISaveablePart) wrapped, wrapped, getReference().getSite()
					.getWorkbenchWindow(), false);
		}
	}

	public IWorkbenchPart getPart() {
		return wrapped;
	}

	public MPart getModel() {
		return part;
	}
}
