package brn.gui.fwdgraph.diagram.custom.editors;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.core.services.ViewService;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditorInput;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.core.GMFEditingDomainFactory;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;

import brn.gui.datasource.Source;
import brn.gui.diagram.SimulatorDiagramEditorInput;
import brn.gui.diagram.SimulatorResource;
import brn.gui.diagram.SimulatorResourceFactory;
import brn.gui.fwdgraph.diagram.part.ModelDiagramEditorPlugin;
import brn.gui.graph.model.Graph;
import brn.gui.graph.model.ModelFactory;

public class FwdGraphDiagramEditorUtil {

  public static final Resource createAndOpenDiagram(Source simulator, int id,
      String[] path, String kind, IWorkbenchWindow window, boolean openEditor, String editorId) {

    SimulatorResource resource = FwdGraphDiagramEditorUtil.createNewDiagram(
        simulator, id, path, kind);

    if (resource != null && openEditor)
      FwdGraphDiagramEditorUtil.openDiagram(resource, window, editorId);

    return resource;
  }

  public static final DiagramEditPart openDiagram(SimulatorResource resouce,
      IWorkbenchWindow dWindow, String editorId) {
    DiagramEditorInput input = new SimulatorDiagramEditorInput(resouce);

    IEditorPart editorPart = null;
    try {
      IWorkbenchPage page = dWindow.getActivePage();
      if (page != null) {
        editorPart = dWindow.getActivePage().openEditor(input, editorId);
        return ((IDiagramWorkbenchPart) editorPart).getDiagramEditPart();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    return null;
  }

  public static final SimulatorResource createNewDiagram(Source simulator,
      int id, final String[] path, String kind) {

    TransactionalEditingDomain editingDomain = GMFEditingDomainFactory.INSTANCE
        .createEditingDomain();
    ResourceSet resourceSet = editingDomain.getResourceSet();

    SimulatorResourceFactory factory =
      new SimulatorResourceFactory();
    final SimulatorResource resource = (SimulatorResource) factory
        .createResource(simulator, id);
    resourceSet.getResources().add(resource);

    final String kindParam = kind;
    AbstractTransactionalCommand command = new AbstractTransactionalCommand(
        editingDomain, "Creating diagram and model", null) { //$NON-NLS-1$
      protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
          IAdaptable info) throws ExecutionException {
        Graph model = createInitialModel();
        resource.getContents().add(createInitialRoot(model));
        resource.setID(model, "model");

        String title = "";
        for (int i = 0; i < path.length; i++)
          title += path[i] + ", ";

        Diagram diagram = ViewService.createDiagram(model, kindParam,
            ModelDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT);
        if (diagram != null) {
          resource.getContents().add(diagram);
          resource.setID(diagram, "diagram");
          diagram.setName(title);
          diagram.setElement(model);
        }
        return CommandResult.newOKCommandResult();
      }
    };

    try {
      OperationHistoryFactory.getOperationHistory().execute(command,
          null/* new SubProgressMonitor(null, 1) */, null);
    } catch (ExecutionException e) {
      ModelDiagramEditorPlugin.getInstance().logError(
          "Unable to create model and diagram", e); //$NON-NLS-1$
    }

    return (resource);
  }

  private static Graph createInitialModel() {
    return ModelFactory.eINSTANCE.createGraph();
  }

  private static EObject createInitialRoot(Graph model) {
    return model;
  }
}
