package it.mice.voila2.plugin.handlers;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.papyrus.uml.diagram.common.handlers.CmdHandler;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.uml2.uml.Actor;
import org.eclipse.uml2.uml.Model;

import it.micegroup.voila2.cartridge.library.javaservice.ModelCategory;
import it.micegroup.voila2.cartridge.library.javaservice.ModelUtils;
import it.mice.voila2.plugin.transformer.BasicTransformer;

public class VoilaGenerationHandler extends CmdHandler {

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);

		Model model = getModel();
		URI uri = selectedEObject.eResource().getURI();

		// URIConverter uriConverter = resource.getResourceSet().getURIConverter();
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		if (uri.segmentCount() < 2 || model == null) {
			return false;
		}
		IProject rootProject = root.getProject(uri.segment(1));

		String selection = null;
		if (model == selectedEObject) {
			selection = "Model: '" + rootProject.getName() + "'";
		} else {
			selection = "Transformation of : '" + rootProject.getName() + "'";
		}

		try {
			boolean confirm = MessageDialog.openConfirm(null, "JF transformation confirm",
					"A new transformation will be executed based on selected: " + selection
							+ ". Press OK to continue.");

			if (!confirm) {
				return null;
			}

			IWorkbench wb = PlatformUI.getWorkbench();
			IProgressService ps = wb.getProgressService();

			ps.busyCursorWhile(new BasicTransformer(selectedEObject, rootProject));
//			ps.runInUI(new ProgressMonitorDialog(org.eclipse.swt.widgets.Display.getCurrent().getActiveShell()),
//					new BasicTransformer(selectedEObject, rootProject), null);
		} catch (Exception e) {
			raiseErrorDialog(e);
		}
		return null;
	}

	private void raiseErrorDialog(Exception e) {
		e.printStackTrace();
		Display.getDefault().asyncExec(new Runnable() {
			@Override
			public void run() {
				MessageDialog.openError(null, "JF generation error", e.getCause().getMessage());
			}
		});
	}

	@Override
	public boolean isEnabled() {
		updateSelectedEObject();
		return (selectedEObject instanceof Model || selectedEObject instanceof Actor);
	}

	/**
	 * @return EObject adapted from current selection
	 */
	protected EObject getSelectedEObject() {
//	    if (selectedEObject instanceof StructuredSelection == false) {
//	        return null;
//	    }
//	    Object selection = ((StructuredSelection) selectedEObject).getFirstElement();
//	    if (selection == null) {
//	        return null;
//	    }

		return (EObject) Platform.getAdapterManager().getAdapter(selectedEObject, EObject.class);
	}

	public Model getModel() {
		Model model = null;
		if (selectedEObject instanceof Actor) {
			model = ((Actor) selectedEObject).getModel();
			return model;
		} else if (selectedEObject instanceof Model) {
			model = (Model) selectedEObject;
			if (ModelUtils.hasActor(model)) {
				return model;
			}
			// Root Component diagram
			if (ModelUtils.isInCategory(model, ModelCategory.root)) {
				return model;
			}
		}
		MessageDialog.openConfirm(null, "Transformation Status",
				"To start transformation please select an Actor" + ". Press OK to continue.");
		return null;
	}
}
