/*******************************************************************************
 * Copyright (c) 2001, 2004 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.wst.wsdl.ui.internal.xsd;
                                      
import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.core.resources.IFile;
import org.eclipse.gef.EditPart;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.wst.wsdl.Types;
import org.eclipse.wst.wsdl.XSDSchemaExtensibilityElement;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditor;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin;
import org.eclipse.wst.wsdl.ui.internal.extension.IMenuActionContributor;
import org.eclipse.wst.wsdl.ui.internal.graph.WSDLComponentViewer;
import org.eclipse.wst.wsdl.ui.internal.model.WSDLGroupObject;
import org.eclipse.wst.wsdl.ui.internal.xsd.actions.AddSchemaAction;
import org.eclipse.wst.wsdl.ui.internal.xsd.actions.BackAction;
import org.eclipse.wst.xml.core.internal.document.DocumentImpl;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xsd.ui.internal.XSDEditorPlugin;
import org.eclipse.wst.xsd.ui.internal.XSDMenuListener;
import org.eclipse.wst.xsd.ui.internal.actions.CreateElementAction;
import org.eclipse.wst.xsd.ui.internal.actions.CreateGroupAction;
import org.eclipse.wst.xsd.ui.internal.actions.DOMAttribute;
import org.eclipse.wst.xsd.ui.internal.gef.util.editparts.AbstractComponentViewerRootEditPart;
import org.eclipse.wst.xsd.ui.internal.graph.editparts.TopLevelComponentEditPart;
import org.eclipse.wst.xsd.ui.internal.graph.model.Category;
import org.eclipse.wst.xsd.ui.internal.provider.CategoryAdapter;
import org.eclipse.wst.xsd.ui.internal.util.XSDDOMHelper;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.util.XSDConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XSDMenuActionContributor implements IMenuActionContributor
{
  Element currElement;
  Document currDocument;
//  XSDSchema xsdSchema;
//  protected ISelectionProvider iSelectionProvider;
  WSDLEditor wsdlEditor;

  public XSDMenuActionContributor(WSDLEditor wsdlEditor)
  {
    this.wsdlEditor = wsdlEditor;
  }

  public void contributeMenuActions(IMenuManager manager, Node node, Object object)
  {
    XSDMenuExtensionListener xsdMenuListener = new XSDMenuExtensionListener(wsdlEditor.getSelectionManager());
    xsdMenuListener.contributeMenuActions(manager, node, object);
  }

  class XSDMenuExtensionListener extends XSDMenuListener
  {
    public XSDMenuExtensionListener(ISelectionProvider selectionProvider)
    {
      super(selectionProvider);
    }
    
    protected boolean isSchemaReadOnly()
    {
    	Iterator eeIt = wsdlEditor.getDefinition().getETypes().getEExtensibilityElements().iterator();
    	while (eeIt.hasNext()) {
    		XSDSchemaExtensibilityElement ee = (XSDSchemaExtensibilityElement) eeIt.next();
    		XSDSchema schema = ee.getSchema();
    		if (schema == xsdSchema) {
    			return false;
    		}
    	}
    	
    	
    	return true;
    }

    /*
     * TODO: For now, just return the first inline schema we have.
     */
    protected XSDSchema getCurrentSchemaInEditor()
    {
    	Iterator eeIt = wsdlEditor.getDefinition().getETypes().getEExtensibilityElements().iterator();
    	while (eeIt.hasNext()) {
    		XSDSchemaExtensibilityElement ee = (XSDSchemaExtensibilityElement) eeIt.next();
    		return ee.getSchema();    		
    	}
    
      return null;
    }
    
    public void contributeMenuActions(IMenuManager manager, Node node, Object object)
    {
      updateXSDSchema();
      AbstractComponentViewerRootEditPart editPart = (AbstractComponentViewerRootEditPart)wsdlEditor.getGraphViewer().getComponentViewer().getRootEditPart().getContents();
//    iSelectionProvider = ((WSDLContentOutlinePage)(wsdlEditor.getWSDLTextEditor().getContentOutlinePage())).getTreeViewer();
      EditPart focusEditPart = wsdlEditor.getGraphViewer().getComponentViewer().getFocusEditPart();

      if (object instanceof WSDLGroupObject)
      {
        WSDLGroupObject group = (WSDLGroupObject)object;
        if (group.getType() == WSDLGroupObject.TYPES_GROUP)
        {
          boolean typesExist = group.getParent().getTypes() != null;
          
          Element typesElement = null;
          if (typesExist)
          {
            Types types = group.getParent().getETypes();
            typesElement = types.getElement();
          }
          if (manager != null)
          {
            Document document = null;
            if (editPart.getViewer() instanceof WSDLComponentViewer) {
              WSDLComponentViewer wsdlComponentViewer = (WSDLComponentViewer) editPart.getViewer();
              document = wsdlComponentViewer.getWSDLEditor().getXMLDocument();
            }

            manager.add(new AddSchemaAction(group.getDefinition(), (Element)node, typesElement, document));
          }
        }
      } 
      else if (object instanceof Types)
      {
        // IMenuManager menu = manager.findMenuUsingPath("addchild");

        if (manager != null)
        {
          Types types = (Types)object;
          manager.add(new AddSchemaAction(types.getEnclosingDefinition(), (Element)node));
        }
      }
      
      if (xsdSchema == null)
      {
        return;
      }
      
      ArrayList attributes = null;
      Node relativeNode = null;
      
      BackAction backAction;
      
      if (object instanceof XSDSchema || focusEditPart instanceof TopLevelComponentEditPart || object instanceof Category)
      {
        backAction = new BackAction(WSDLEditorPlugin.getWSDLString("_UI_BACK_TO_DEFINITION"));
        backAction.setDefinition(wsdlEditor.getDefinition());
        backAction.setSelectionProvider(selectionProvider);
        backAction.setRootEditPart(editPart);
        backAction.setGraphViewer(wsdlEditor.getGraphViewer());
        manager.add(backAction);
        manager.add(new Separator());
      }
      else if (object instanceof XSDConcreteComponent)
      {
        backAction = new BackAction(XSDEditorPlugin.getXSDString("_UI_ACTION_BACK_TO_SCHEMA_VIEW"));
        // backAction.setXSDSchema(((XSDConcreteComponent)object).getSchema());
        backAction.setXSDSchema(xsdSchema);
        backAction.setSelectionProvider(selectionProvider);
        backAction.setRootEditPart(editPart);
        backAction.setGraphViewer(wsdlEditor.getGraphViewer());
        manager.add(backAction);
        manager.add(new Separator());
      }

      // CS: I'm removing the 'object instanceof Element' case from this test
      // for now the menu actions are driven from 'model' objects
      if (object instanceof XSDConcreteComponent || (object instanceof org.eclipse.wst.wsdl.XSDSchemaExtensibilityElement))
      {
        Element parent;
        if (object instanceof XSDConcreteComponent)
        {
          parent = ((XSDConcreteComponent)object).getElement();
          xsdSchema = ((XSDConcreteComponent)object).getSchema();
        }
        else if (object instanceof Element)
        {
          manager.add(new Separator());
          parent = (Element)object; 
        }
        else if (object instanceof org.eclipse.wst.wsdl.XSDSchemaExtensibilityElement)
        {
          XSDSchemaExtensibilityElement schema = (XSDSchemaExtensibilityElement)object;
          xsdSchema = schema.getSchema();
          manager.add(new Separator());
          parent = xsdSchema.getElement();
        }
        else
        {
          return;
        }
        
        currElement = parent;
        currDocument = parent.getOwnerDocument();
        
//        if (!(currDocument instanceof DocumentImpl))
//        {
//          return;
//        }
        
        addContextItems(manager, currElement, null);

        if (!(object instanceof XSDSchema) ||
           	(object instanceof XSDSchema && !(wsdlEditor.getGraphViewer().getComponentViewer().getInput() instanceof XSDSchema))) {
           	IStructuredSelection selections = (IStructuredSelection) wsdlEditor.getSelectionManager().getSelection();
           	manager.add(new Separator());
           	org.eclipse.wst.wsdl.ui.internal.actions.DeleteWSDLAndXSDAction deleteWSDLAndXSDAction = new org.eclipse.wst.wsdl.ui.internal.actions.DeleteWSDLAndXSDAction(selections.toList(), currElement, wsdlEditor);
           	deleteWSDLAndXSDAction.setEnabled(!isReadOnly);
           	manager.add(deleteWSDLAndXSDAction);
        }
      }
      else if (object instanceof Category
            || object instanceof CategoryAdapter)
      {
        int groupType = -1;

        if (object instanceof Category)
        {
          Category cg = (Category)object;
          xsdSchema = cg.getXSDSchema();
          groupType = cg.getGroupType();
        }
        else  // CategoryAdapter
        {
          CategoryAdapter category = (CategoryAdapter)object;
          groupType = category.getGroupType();
          xsdSchema = category.getXSDSchema();
        }
        Element parent = xsdSchema.getElement();
        currElement = parent;
        currDocument = parent.getOwnerDocument();
        switch (groupType)
        {
          case Category.TYPES:
          {
            attributes = new ArrayList();
            attributes.add(new DOMAttribute(XSDConstants.NAME_ATTRIBUTE, getNewGlobalTypeName("ComplexType")));
            Action action = addCreateElementAction(manager, XSDConstants.COMPLEXTYPE_ELEMENT_TAG, XSDEditorPlugin.getXSDString("_UI_ACTION_ADD_COMPLEX_TYPE"), attributes, parent, relativeNode);
            ((CreateElementAction)action).setIsGlobal(true);
            attributes = new ArrayList();
            attributes.add(new DOMAttribute(XSDConstants.NAME_ATTRIBUTE, getNewGlobalTypeName("SimpleType")));
            Action action2 = addCreateSimpleTypeAction(manager, XSDConstants.SIMPLETYPE_ELEMENT_TAG, XSDEditorPlugin.getXSDString("_UI_ACTION_ADD_SIMPLE_TYPE"), attributes, parent, relativeNode);
            ((CreateElementAction)action2).setIsGlobal(true);
            break;
          }
          case Category.ELEMENTS:
          {
            attributes = new ArrayList();
            attributes.add(new DOMAttribute(XSDConstants.NAME_ATTRIBUTE,
                                            getNewGlobalName(XSDConstants.ELEMENT_ELEMENT_TAG, "GlobalElement")));
            attributes.add(new DOMAttribute(XSDConstants.TYPE_ATTRIBUTE, getBuiltInStringQName()));
            Action action = addCreateElementAction(manager, XSDConstants.ELEMENT_ELEMENT_TAG, XSDEditorPlugin.getXSDString("_UI_ACTION_ADD_ELEMENT"), attributes, parent, relativeNode);
            ((CreateElementAction)action).setIsGlobal(true);
            break;
          }
          case Category.GROUPS:
          {
            attributes = new ArrayList();
            attributes.add(new DOMAttribute(XSDConstants.NAME_ATTRIBUTE,
                                            getNewGlobalName(XSDConstants.GROUP_ELEMENT_TAG, "Group")));
            CreateGroupAction groupAction = addCreateGroupAction(manager, XSDConstants.GROUP_ELEMENT_TAG, XSDEditorPlugin.getXSDString("_UI_ACTION_ADD_GROUP"), attributes, parent, relativeNode);
            groupAction.setIsGlobal(true);
            break;
          }
          case Category.ATTRIBUTES:
          {
            attributes = new ArrayList();
            attributes.add(new DOMAttribute(XSDConstants.NAME_ATTRIBUTE,
                                            getNewGlobalName(XSDConstants.ATTRIBUTE_ELEMENT_TAG, "GlobalAttribute")));
            attributes.add(new DOMAttribute(XSDConstants.TYPE_ATTRIBUTE, getBuiltInStringQName()));
            Action action = addCreateElementAction(manager, XSDConstants.ATTRIBUTE_ELEMENT_TAG, XSDEditorPlugin.getXSDString("_UI_ACTION_ADD_GLOBAL_ATTRIBUTE"), attributes, parent, relativeNode);
            ((CreateElementAction)action).setIsGlobal(true);
            break;
          }
          case Category.ATTRIBUTE_GROUPS:
          {
            attributes = new ArrayList();
            attributes.add(new DOMAttribute(XSDConstants.NAME_ATTRIBUTE,
                                            getNewGlobalName(XSDConstants.ATTRIBUTEGROUP_ELEMENT_TAG, "AttributeGroup")));
            Action action = addCreateElementAction(manager, XSDConstants.ATTRIBUTEGROUP_ELEMENT_TAG, XSDEditorPlugin.getXSDString("_UI_ACTION_ADD_ATTRIBUTE_GROUP"), attributes, parent, relativeNode);
            ((CreateElementAction)action).setIsGlobal(true);
            break; 
          }
          case Category.NOTATIONS:
          {
            attributes = new ArrayList();
            attributes.add(new DOMAttribute(XSDConstants.NAME_ATTRIBUTE, 
                           getNewGlobalName(XSDConstants.NOTATION_ELEMENT_TAG, "Notation")));
            attributes.add(new DOMAttribute(XSDConstants.PUBLIC_ATTRIBUTE, ""));
            Action action = addCreateElementAction(manager, XSDConstants.NOTATION_ELEMENT_TAG, XSDEditorPlugin.getXSDString("_UI_ACTION_ADD_NOTATION"), attributes, parent, relativeNode);
            ((CreateElementAction)action).setIsGlobal(true);
            break;
          }
          case Category.DIRECTIVES:
          {
            boolean b = true;
            NodeList children = parent.getChildNodes();
            Node effectiveRelativeNode = parent.getFirstChild();
            for (int i=0; i < children.getLength() && b; i++)
            {
              Node child = children.item(i);
              if (child != null && child instanceof Element)
              {
                if (XSDDOMHelper.inputEquals((Element)child, XSDConstants.INCLUDE_ELEMENT_TAG, false) ||
                    XSDDOMHelper.inputEquals((Element)child, XSDConstants.IMPORT_ELEMENT_TAG, false) ||
                    XSDDOMHelper.inputEquals((Element)child, XSDConstants.REDEFINE_ELEMENT_TAG, false) ||
                    XSDDOMHelper.inputEquals((Element)child, XSDConstants.ANNOTATION_ELEMENT_TAG, false))
                {
                  effectiveRelativeNode = child;
                }
                else
                {
                  b = false;
                }
              }
            }
            relativeNode = effectiveRelativeNode != null ? effectiveRelativeNode.getNextSibling() : null;
            attributes = new ArrayList();
            attributes.add(new DOMAttribute(XSDConstants.SCHEMALOCATION_ATTRIBUTE, ""));

            addCreateElementAction(manager, XSDConstants.INCLUDE_ELEMENT_TAG,XSDEditorPlugin.getXSDString("_UI_ACTION_ADD_INCLUDE"), attributes, parent, relativeNode);
            addCreateElementAction(manager, XSDConstants.IMPORT_ELEMENT_TAG,XSDEditorPlugin.getXSDString("_UI_ACTION_ADD_IMPORT"), null, parent, relativeNode);
            addCreateElementAction(manager, XSDConstants.REDEFINE_ELEMENT_TAG,XSDEditorPlugin.getXSDString("_UI_ACTION_ADD_REDEFINE"), attributes, parent, relativeNode);
            
            
            break;
          }
        }
      }
    }    

    protected IFile getFileResource()
    {
  ///// WSDL TODO
  //    if (getEditor() != null)
  //      return getEditor().getFileResource();
      return null;
    }

//    protected Object getSelectedElement()
//    {
//      return currElement;
//    }

    protected XSDSchema getXSDSchema()
    {
      return xsdSchema;
    }
  
    protected IDOMModel getXMLModel()
    {
      if (currElement != null)
      {
        Object obj = currElement.getOwnerDocument();
        if (obj instanceof DocumentImpl)
        {
          DocumentImpl xmlDoc = (DocumentImpl) currElement.getOwnerDocument();
          return xmlDoc.getModel();
        }
      }
      return null;
    }
  }

}