package org.eclipse.stem.ui.grapheditor.handlers;


import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.edit.provider.DelegatingWrapperItemProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.stem.adapters.file.File;
import org.eclipse.stem.core.common.Identifiable;
import org.eclipse.stem.core.graph.Graph;
import org.eclipse.stem.core.graph.impl.GraphImpl;
import org.eclipse.stem.core.model.Model;
import org.eclipse.stem.ui.Activator;
import org.eclipse.stem.ui.grapheditor.GraphCanvas;
import org.eclipse.stem.ui.views.explorer.IdentifiableTreeNode;
import org.eclipse.ui.handlers.HandlerUtil;


public class GraphDisplay extends AbstractHandler
implements IHandler {
	
	IProject project;
	
	

	public Object execute(final ExecutionEvent executionEvent)
	throws ExecutionException {
		
		final ISelection selection = HandlerUtil
		.getCurrentSelectionChecked(executionEvent);
		
		
		if(selection instanceof TreeSelection) {
			TreeSelection ts = (TreeSelection)selection;
			TreePath[] paths =  ts.getPaths();
			if(paths.length > 0) {
				TreePath parent = paths[0].getParentPath();
				Object projectSegment = parent.getFirstSegment();
				
				//Object parentSeg = parent.getLastSegment();
				if(projectSegment != null) {
					project = null;					
					if(projectSegment instanceof IdentifiableTreeNode)  
						project =((IdentifiableTreeNode)projectSegment).getProject();					 
					if(projectSegment instanceof IProject) 
						project = (IProject)projectSegment;
					
				}
			}
		}
	
		// Structured Selection?
		if (selection instanceof StructuredSelection) 
		{
			Identifiable retValue = null;
			// Yes
			// Iterate through everything that's in the selection and put each
			// object into the appropriate collection.
			for (final Object obj : ((StructuredSelection) selection).toList()) {
				// IExecutable executable = (IExecutable) ExecutableAdapterFactory.INSTANCE
				// .adapt(obj, IExecutable.class)
				if (obj instanceof GraphImpl)
				{
					retValue = (GraphImpl) obj;
				}
				else
				{
					DelegatingWrapperItemProvider dWIP = (DelegatingWrapperItemProvider) obj;			
					
					if (dWIP.getValue() instanceof Identifiable) {
						// Yes
						retValue = (Identifiable) dWIP.getValue();
					} // if Identifiable
					else {
						// No
						// Keep adapting...
						retValue = (Identifiable) Platform.getAdapterManager()
								.getAdapter(dWIP.getValue(), Identifiable.class);
					}
				}
				
				
				File file = (File) Platform
				.getAdapterManager().getAdapter(retValue, File.class); 		
				
				Graph stemGraph = (Graph) Platform
				.getAdapterManager().getAdapter(retValue, Graph.class);
				
				//File file = (File) Platform
				//.getAdapterManager().getAdapter(obj, File.class); 
				
				//Graph stemGraph = (Graph) Platform
				//.getAdapterManager().getAdapter(obj, Graph.class);
		
				// Were we successful in adapting?
				if (stemGraph == null) {
					//No: Internal error
					Activator.logError(
							"STEM Internal error display command applied to \""
									+ obj.getClass().getName() + "\"", null);
				} // Yes, successfully adapted Graph
				else 
					{
					if (project == null){	
						List<IProject> projects = org.eclipse.stem.ui.Utility.getSTEMProjectsFromWorkspace(ResourcesPlugin.getWorkspace());
						for (IProject stemProject : projects)
						{		
							//System.err.println("project: " + project.getName()+ " graph:" + stemGraph.getURI());
							//TODO contain is not enough, must be identical segment!
							if (stemGraph.getURI().toString().contains(stemProject.getName()) )
							{
								project = stemProject;
							}
						}	
					}
					
					//start Display
					doit(stemGraph, file, project);												
					
					//update graphs in all models of the project 
					
					/*
					IContainer modelFolder = null;
					IResource[] models = null;
					
					try {
						if (project != null) 
							{ 	modelFolder = project.getFolder("models");	
								models = modelFolder.members();
							}
					} catch(Exception e) {
						e.printStackTrace();
					}
					
					
					
					if (models != null) {
						
						for(IResource r:models) {
							// ignore system files
							if(r.getName().startsWith(".")) continue;
							
							try {
								URI uri = URI.createURI(r.getLocationURI().toString());
								Identifiable id = Utility.getIdentifiable(uri);				
								if(id instanceof Model)
								{ 
									List<Graph> modelGraphs = new ArrayList<Graph>();
									Model model = (Model) id;							
									modelGraphs = getGraphs(modelGraphs, model);
									for (Graph modelGraph : modelGraphs)
									{
										if (modelGraph.getURI().lastSegment().equals(stemGraph.getURI().lastSegment()))
										{					
											modelGraph = stemGraph;
										}
									}
									
									
								}

								//Graph g = ((Model)id).getCanonicalGraph(STEMURI.createURI(""), null, null);
								//if(id instanceof Model) latlongs.putAll(getGraphSpacials(g, location));
									
							}
							// Skip bad file
							catch(Exception e) { e.printStackTrace(); }															
						} // models iterator
					} // models != null, end updating graphs
					*/
					
				} // Graph successfully adapted, "doit" called, project models updated
				
			} // for each selection
			
			
		} // if StructuredSelection 
					
		return null;
	}
	
	
	
	protected void doit(Graph stemGraph, File file, IProject project) {
		
		if (stemGraph != null)
		{
			GraphCanvas graphCanvas = new GraphCanvas();
			List<Graph> graphList = new ArrayList<Graph>();
			graphList.add(stemGraph);
			graphCanvas.display(graphList, file, project);	
		}

		
	}
	
	

	
	protected List<Graph> getGraphs(List<Graph> parentgraphs, Model parentmodel)
	{
		EList<Model> models = parentmodel.getModels();
		List<Graph> graphs = parentmodel.getGraphs();
	
		for (Model model : models)
		{	
			graphs.addAll(getGraphs(graphs, model));
		}

		parentgraphs.addAll(graphs);
		return parentgraphs;
	}
	
	

				
}


