/*******************************************************************************
 * 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.actions; 
                      
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.wst.wsdl.Binding;
import org.eclipse.wst.wsdl.BindingFault;
import org.eclipse.wst.wsdl.BindingInput;
import org.eclipse.wst.wsdl.BindingOperation;
import org.eclipse.wst.wsdl.BindingOutput;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Port;
import org.eclipse.wst.wsdl.UnknownExtensibilityElement;
import org.eclipse.wst.wsdl.WSDLElement;
import org.eclipse.wst.wsdl.internal.util.WSDLSwitch;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin;
import org.eclipse.wst.wsdl.ui.internal.extension.IMenuActionContributor;
import org.eclipse.wst.wsdl.ui.internal.model.WSDLGroupObject;
import org.eclipse.wst.wsdl.ui.internal.util.WSDLEditorUtil;
import org.eclipse.wst.wsdl.util.WSDLConstants;
import org.eclipse.wst.xml.core.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQueryAction;
import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilder;
import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMNamespaceHelper;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML;
import org.eclipse.wst.xml.ui.actions.MenuBuilder;
import org.eclipse.wst.xml.ui.util.XMLCommonResources;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

                             
/**
 * TODO... there are likely several places where we can refactor code from  AbstractNodeActionManager
 */
public class AddEEMenuActionContributor implements IMenuActionContributor
{                   
  protected MenuBuilder menuBuilder = new MenuBuilder();

  public void contributeMenuActions(final IMenuManager menu, Node node, Object object)
  {
    boolean isSubmenuRequired = false;
    Element element = null;

    if (object instanceof WSDLElement)
    {     
      WSDLSwitch wsdlSwitch = new WSDLSwitch()
      {                   
      	public Object caseBinding(Binding binding)
        {                                          
          return Boolean.TRUE;
	      } 

      	public Object caseBindingOperation(BindingOperation bindingOperation)
        {                                          
          return Boolean.TRUE;
	      } 

      	public Object caseBindingInput(BindingInput bindingInput)
        {                                          
          return Boolean.TRUE;
	      } 

      	public Object caseBindingOutput(BindingOutput bindingOutput)
        {                                          
          return Boolean.TRUE;
	      }

      	public Object caseBindingFault(BindingFault bindingFault)
        {                                          
          return Boolean.TRUE;
	      } 
 
      	public Object caseDefinition(Definition definition)
        {      
          return Boolean.TRUE;
	      }           
     
      	public Object casePort(Port port)
        {                                         
          return Boolean.TRUE;
        } 
      	public Object caseUnknownExtensibilityElement(UnknownExtensibilityElement unknownExtensibilityElement)
      	{
      		if (getExtensibilityElementActions(unknownExtensibilityElement.getElement()).size() > 0)
      		{      		
      			return Boolean.TRUE;
      		}
      		else
      		{
      			return Boolean.FALSE;
      		}
      	}
      };        
      isSubmenuRequired = wsdlSwitch.doSwitch((WSDLElement)object) != null;
      element = WSDLEditorUtil.getInstance().getElementForObject(object);      
    }
    else if (object instanceof WSDLGroupObject)
    {
      WSDLGroupObject groupObject = (WSDLGroupObject)object;
     
      switch (groupObject.getType())
      {   
        case WSDLGroupObject.EXTENSIBILITY_ELEMENTS_GROUP : 
        {
          isSubmenuRequired = true;
          element = WSDLEditorUtil.getInstance().getElementForObject(groupObject.getDefinition());    
          break;
        }
      }   
    }

    if (isSubmenuRequired)
    {
      MenuManager submenu = new MenuManager(WSDLEditorPlugin.getWSDLString("_UI_ADD_EXTENSIBILITY_ELEMENT"));  //$NON-NLS-1$
      // here I'm attempting to add the menu item in a 'good' place in the exisiting menu
      // todo add menu groups to avoid the need for this test
      //
//      if (menu.find("addchild") != null)
//      {
//      	menu.insertAfter("addchild", submenu);
//      }
//      else
//      {
//      	menu.add(submenu);
//      }	 
    	menu.add(submenu);
      if (element != null && element instanceof IDOMNode)
      {
        addExtensibilityElementActions(submenu, element);
      }
    }
  }

  public void addExtensibilityElementActions(IMenuManager menu, Element element)
  {                 
    ModelQuery modelQuery = ModelQueryUtil.getModelQuery(element.getOwnerDocument());
    CMElementDeclaration ed = modelQuery.getCMElementDeclaration(element);
    
    if (ed != null)
    {
      addActionHelper(menu, getExtensibilityElementActions(element));
    }
  }
  
  public List getExtensibilityElementActions(Element element) {
    List modelQueryActionList = new ArrayList();
  	ModelQuery modelQuery = ModelQueryUtil.getModelQuery(element.getOwnerDocument());
    CMElementDeclaration ed = modelQuery.getCMElementDeclaration(element);                                                                                                                            

    if (ed != null)
    {                                                                                    
      // add insert child node actions
      //
      int ic = ModelQuery.INCLUDE_CHILD_NODES;
      int vc = ModelQuery.VALIDITY_STRICT;

      modelQuery.getInsertActions(element, ed, -1, ic, vc, modelQueryActionList);
    }
    
    return modelQueryActionList;
  }
  

  protected void addActionHelper(IMenuManager menu, List modelQueryActionList)
  {                          
    List actionList = new Vector();

    for (Iterator i = modelQueryActionList.iterator(); i.hasNext(); )
    {                                                   
      ModelQueryAction action = (ModelQueryAction)i.next();
      CMNode cmnode = action.getCMNode();
      if (cmnode != null)
      {                                       
        boolean isOtherNamespace = false;
        CMDocument cmDocument = (CMDocument)cmnode.getProperty("CMDocument");
        if (cmDocument != null)          
        {             
          String namespaceURI = (String)cmDocument.getProperty("http://org.eclipse.wst/cm/properties/targetNamespaceURI"); 
          isOtherNamespace = namespaceURI != null && !namespaceURI.equals(WSDLConstants.WSDL_NAMESPACE_URI);
        }

        if (isOtherNamespace)
        {
          int cmNodeType = cmnode.getNodeType();
          if (action.getKind() == ModelQueryAction.INSERT)
          {                                                 
            switch (cmNodeType)                             
            {
              case CMNode.ELEMENT_DECLARATION :
              {
                actionList.add(new AddNodeAction((CMElementDeclaration)cmnode, action.getParent(), action.getStartIndex()));
                break;
              }
            }
          }           
        }
      }   
    }  
    menuBuilder.populateMenu(menu, actionList, false);
  }   

  /**
   * AddNodeAction
   */
  public class AddNodeAction extends BaseNodeAction
  {
    protected String description;
    protected String undoDescription; 
    protected CMNode cmnode;
    protected int index;
    protected Node parent;


    public AddNodeAction(CMNode cmnode, Node parent,  int index)
    {                                 
      this.cmnode = cmnode;
      this.parent = parent;
      this.index = index;                                   
                                                                                                
      String text = getLabel(parent, cmnode);
      setText(text);     
      description = text;
      undoDescription = XMLCommonResources.getInstance().getString("_UI_MENU_ADD") + " " + text;
      //setImageDescriptor(imageDescriptorCache.getImageDescriptor(cmnode)); 
    }

    public String getLabel(Node parent, CMNode cmnode)
    {                                                
      String result = "?" + cmnode + "?";
      if (cmnode != null)
      {                
        result = DOMNamespaceHelper.computeName(cmnode, parent, null);         
      }
      return result;   
    }  

    public Node getNode()
    {
      return parent;
    }

    public String getUndoDescription()
    {
      return undoDescription;
    }

    public void run()
    {
      beginRecording();

      if (cmnode != null && parent != null)
      {
        Document document = parent.getNodeType() == Node.DOCUMENT_NODE ? (Document)parent : parent.getOwnerDocument();        

        DOMContentBuilder builder = new DOMContentBuilderImpl(document); 
        builder.setProperty(DOMContentBuilder.PROPERTY_BUILD_BLANK_TEXT_NODES, Boolean.TRUE);
        builder.setBuildPolicy(DOMContentBuilder.BUILD_ONLY_REQUIRED_CONTENT);
        builder.build(parent, cmnode);
        insertNodesAtIndex(parent, builder.getResult(), index, true);
      }

      endRecording();
    } 

    public void insertNodesAtIndex(Node parent, List list, int index, boolean format)
    {                   
      NodeList nodeList = parent.getChildNodes();
      if (index == -1)
      {
        index = nodeList.getLength();
      }
      Node refChild = (index < nodeList.getLength()) ? nodeList.item(index) : null;
    
      // here we consider the case where the previous node is a 'white space' Text node
      // we should really do the insert before this node
      //
      int prevIndex = index - 1;
      Node prevChild = (prevIndex < nodeList.getLength()) ? nodeList.item(prevIndex) : null;
	    if (isWhitespaceTextNode(prevChild)) 
      {
	  	  refChild = prevChild;
	    }
    
      for (Iterator i = list.iterator(); i.hasNext(); )
      {
        Node newNode = (Node)i.next();
    
        if (newNode.getNodeType() == Node.ATTRIBUTE_NODE)
        {
          Element parentElement = (Element)parent;
          parentElement.setAttributeNode((Attr)newNode);
        }
        else
        {
          parent.insertBefore(newNode, refChild);
        }  
      }
    
      for (Iterator i = list.iterator(); i.hasNext(); )
      {
        Node newNode = (Node)i.next();
        if (format)
        {                                                             
		      FormatProcessorXML formatProcessorXML = new FormatProcessorXML();
		      formatProcessorXML.formatNode((IDOMNode)newNode);
        }  
      }                      
	    //setViewerSelection(list);
    }   

    protected boolean isWhitespaceTextNode(Node node) 
    {
	    return (node != null) && (node.getNodeType() == Node.TEXT_NODE) && (node.getNodeValue().trim().length() == 0);
    } 
  }                                       
}    