package brn.gui.fwdgraph.diagram.part;

import brn.gui.fwdgraph.diagram.edit.parts.FwdLinkEditPart;
import brn.gui.fwdgraph.diagram.edit.parts.FwdLinkNoPacketsEditPart;
import brn.gui.fwdgraph.diagram.edit.parts.GraphEditPart;
import brn.gui.fwdgraph.diagram.edit.parts.NodeEditPart;
import brn.gui.fwdgraph.diagram.edit.parts.NodeIdEditPart;

import brn.gui.graph.model.FwdLink;
import brn.gui.graph.model.Graph;
import brn.gui.graph.model.ModelPackage;
import brn.gui.graph.model.Node;

import org.eclipse.core.runtime.Platform;

import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;

import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.View;

/**
 * This registry is used to determine which type of visual object should be
 * created for the corresponding Diagram, Node, ChildNode or Link represented 
 * by a domain model object.
 *
 * @generated
 */
public class ModelVisualIDRegistry {

  /**
   * @generated
   */
  private static final String DEBUG_KEY = FwdGraphDiagramEditorPlugin
      .getInstance().getBundle().getSymbolicName()
      + "/debug/visualID"; //$NON-NLS-1$

  /**
   * @generated
   */
  public static int getVisualID(View view) {
    if (view instanceof Diagram) {
      if (GraphEditPart.MODEL_ID.equals(view.getType())) {
        return GraphEditPart.VISUAL_ID;
      } else {
        return -1;
      }
    }
    return getVisualID(view.getType());
  }

  /**
   * @generated
   */
  public static String getModelID(View view) {
    View diagram = view.getDiagram();
    while (view != diagram) {
      EAnnotation annotation = view.getEAnnotation("Shortcut"); //$NON-NLS-1$
      if (annotation != null) {
        return (String) annotation.getDetails().get("modelID"); //$NON-NLS-1$
      }
      view = (View) view.eContainer();
    }
    return diagram != null ? diagram.getType() : null;
  }

  /**
   * @generated
   */
  public static int getVisualID(String type) {
    try {
      return Integer.parseInt(type);
    } catch (NumberFormatException e) {
      if (Boolean.TRUE.toString().equalsIgnoreCase(
          Platform.getDebugOption(DEBUG_KEY))) {
        FwdGraphDiagramEditorPlugin.getInstance().logError(
            "Unable to parse view type as a visualID number: " + type);
      }
    }
    return -1;
  }

  /**
   * @generated
   */
  public static String getType(int visualID) {
    return String.valueOf(visualID);
  }

  /**
   * @generated
   */
  public static int getDiagramVisualID(EObject domainElement) {
    if (domainElement == null) {
      return -1;
    }
    EClass domainElementMetaclass = domainElement.eClass();
    return getDiagramVisualID(domainElement, domainElementMetaclass);
  }

  /**
   * @generated
   */
  private static int getDiagramVisualID(EObject domainElement,
      EClass domainElementMetaclass) {
    if (ModelPackage.eINSTANCE.getGraph().isSuperTypeOf(domainElementMetaclass)
        && isDiagramGraph_79((Graph) domainElement)) {
      return GraphEditPart.VISUAL_ID;
    }
    return getUnrecognizedDiagramID(domainElement);
  }

  /**
   * @generated
   */
  public static int getNodeVisualID(View containerView, EObject domainElement) {
    if (domainElement == null) {
      return -1;
    }
    EClass domainElementMetaclass = domainElement.eClass();
    return getNodeVisualID(containerView, domainElement,
        domainElementMetaclass, null);
  }

  /**
   * @generated
   */
  public static int getNodeVisualID(View containerView, EObject domainElement,
      EClass domainElementMetaclass, String semanticHint) {
    String containerModelID = getModelID(containerView);
    if (!GraphEditPart.MODEL_ID.equals(containerModelID)) {
      return -1;
    }
    int containerVisualID;
    if (GraphEditPart.MODEL_ID.equals(containerModelID)) {
      containerVisualID = getVisualID(containerView);
    } else {
      if (containerView instanceof Diagram) {
        containerVisualID = GraphEditPart.VISUAL_ID;
      } else {
        return -1;
      }
    }
    int nodeVisualID = semanticHint != null ? getVisualID(semanticHint) : -1;
    switch (containerVisualID) {
    case NodeEditPart.VISUAL_ID:
      if (NodeIdEditPart.VISUAL_ID == nodeVisualID) {
        return NodeIdEditPart.VISUAL_ID;
      }
      return getUnrecognizedNode_1001ChildNodeID(domainElement, semanticHint);
    case GraphEditPart.VISUAL_ID:
      if ((semanticHint == null || NodeEditPart.VISUAL_ID == nodeVisualID)
          && ModelPackage.eINSTANCE.getNode().isSuperTypeOf(
              domainElementMetaclass)
          && (domainElement == null || isNodeNode_1001((Node) domainElement))) {
        return NodeEditPart.VISUAL_ID;
      }
      return getUnrecognizedGraph_79ChildNodeID(domainElement, semanticHint);
    case FwdLinkEditPart.VISUAL_ID:
      if (FwdLinkNoPacketsEditPart.VISUAL_ID == nodeVisualID) {
        return FwdLinkNoPacketsEditPart.VISUAL_ID;
      }
      return getUnrecognizedFwdLink_3001LinkLabelID(semanticHint);
    }
    return -1;
  }

  /**
   * @generated
   */
  public static int getLinkWithClassVisualID(EObject domainElement) {
    if (domainElement == null) {
      return -1;
    }
    EClass domainElementMetaclass = domainElement.eClass();
    return getLinkWithClassVisualID(domainElement, domainElementMetaclass);
  }

  /**
   * @generated
   */
  public static int getLinkWithClassVisualID(EObject domainElement,
      EClass domainElementMetaclass) {
    if (ModelPackage.eINSTANCE.getFwdLink().isSuperTypeOf(
        domainElementMetaclass)
        && (domainElement == null || isLinkWithClassFwdLink_3001((FwdLink) domainElement))) {
      return FwdLinkEditPart.VISUAL_ID;
    } else {
      return getUnrecognizedLinkWithClassID(domainElement);
    }
  }

  /**
   * User can change implementation of this method to check some additional 
   * conditions here.
   *
   * @generated
   */
  private static boolean isDiagramGraph_79(Graph element) {
    return true;
  }

  /**
   * User can change implementation of this method to handle some specific
   * situations not covered by default logic.
   *
   * @generated
   */
  private static int getUnrecognizedDiagramID(EObject domainElement) {
    return -1;
  }

  /**
   * User can change implementation of this method to check some additional 
   * conditions here.
   *
   * @generated
   */
  private static boolean isNodeNode_1001(Node element) {
    return true;
  }

  /**
   * User can change implementation of this method to handle some specific
   * situations not covered by default logic.
   *
   * @generated
   */
  private static int getUnrecognizedNode_1001ChildNodeID(EObject domainElement,
      String semanticHint) {
    return -1;
  }

  /**
   * User can change implementation of this method to handle some specific
   * situations not covered by default logic.
   *
   * @generated
   */
  private static int getUnrecognizedGraph_79ChildNodeID(EObject domainElement,
      String semanticHint) {
    return -1;
  }

  /**
   * User can change implementation of this method to handle some specific
   * situations not covered by default logic.
   *
   * @generated
   */
  private static int getUnrecognizedFwdLink_3001LinkLabelID(String semanticHint) {
    return -1;
  }

  /**
   * User can change implementation of this method to handle some specific
   * situations not covered by default logic.
   *
   * @generated
   */
  private static int getUnrecognizedLinkWithClassID(EObject domainElement) {
    return -1;
  }

  /**
   * User can change implementation of this method to check some additional 
   * conditions here.
   *
   * @generated
   */
  private static boolean isLinkWithClassFwdLink_3001(FwdLink element) {
    return true;
  }
}
