/*******************************************************************************
 * 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.common.contentmodel.CMDocument;
import org.eclipse.wst.common.contentmodel.CMElementDeclaration;
import org.eclipse.wst.common.contentmodel.CMNode;
import org.eclipse.wst.common.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.common.contentmodel.modelquery.ModelQueryAction;
import org.eclipse.wst.common.contentmodel.util.DOMContentBuilder;
import org.eclipse.wst.common.contentmodel.util.DOMContentBuilderImpl;
import org.eclipse.wst.common.contentmodel.util.DOMNamespaceHelper;
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.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.internal.util.WSDLConstants;
import org.eclipse.wst.wsdl.internal.util.WSDLSwitch;
import org.eclipse.wst.xml.core.document.XMLNode;
import org.eclipse.wst.xml.core.format.FormatProcessorXML;
import org.eclipse.wst.xml.core.modelquery.ModelQueryUtil;
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 XMLNode)
      {
        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((XMLNode)newNode);
        }  
      }                      
	    //setViewerSelection(list);
    }   

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