/*******************************************************************************
 * 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.Map;

import org.eclipse.gef.EditPartViewer;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.wst.wsdl.Binding;
import org.eclipse.wst.wsdl.BindingOperation;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Fault;
import org.eclipse.wst.wsdl.Import;
import org.eclipse.wst.wsdl.Input;
import org.eclipse.wst.wsdl.Message;
import org.eclipse.wst.wsdl.Operation;
import org.eclipse.wst.wsdl.Output;
import org.eclipse.wst.wsdl.Part;
import org.eclipse.wst.wsdl.Port;
import org.eclipse.wst.wsdl.PortType;
import org.eclipse.wst.wsdl.Service;
import org.eclipse.wst.wsdl.WSDLElement;
import org.eclipse.wst.wsdl.internal.impl.WSDLElementImpl;
import org.eclipse.wst.wsdl.internal.util.WSDLSwitch;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditor;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin;
import org.eclipse.wst.wsdl.ui.internal.commands.AddInputCommand;
import org.eclipse.wst.wsdl.ui.internal.commands.AddMessageCommand;
import org.eclipse.wst.wsdl.ui.internal.commands.AddOperationCommand;
import org.eclipse.wst.wsdl.ui.internal.commands.AddOutputCommand;
import org.eclipse.wst.wsdl.ui.internal.extension.IMenuActionContributor;
import org.eclipse.wst.wsdl.ui.internal.graph.editparts.WSDLTreeNodeEditPart;
import org.eclipse.wst.wsdl.ui.internal.model.WSDLGroupObject;
import org.eclipse.wst.wsdl.ui.internal.util.ComponentReferenceUtil;
import org.eclipse.wst.wsdl.ui.internal.util.CreateWSDLElementHelper;
import org.eclipse.wst.wsdl.ui.internal.util.NameUtil;
import org.eclipse.wst.wsdl.ui.internal.util.WSDLEditorUtil;
import org.eclipse.wst.wsdl.ui.internal.widgets.NewComponentWithChildDialog;
import org.eclipse.wst.wsdl.ui.internal.wizards.BindingWizard;
import org.eclipse.wst.wsdl.ui.internal.wizards.PortWizard;
import org.eclipse.wst.wsdl.util.WSDLConstants;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xsd.ui.internal.XSDEditorPlugin;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class WSDLMenuActionContributor implements IMenuActionContributor
{
  protected AddEEMenuActionContributor addEEMenuActionContributor;
  IEditorPart editorPart;

  public WSDLMenuActionContributor(IEditorPart editorPart)
  {
    addEEMenuActionContributor = new AddEEMenuActionContributor();
    this.editorPart = editorPart;
  }

  protected static List createList(Action action)
  {
    List list = new ArrayList();
    list.add(action);
    return list;
  }
  
	private class OpenSchemaOnSelectionHelper extends Action {
		Object object;
		
		public OpenSchemaOnSelectionHelper(Object object) {
			setText(WSDLEditorPlugin.getWSDLString("_UI_OPEN_IMPORT"));
			this.object = object;
			
			if (object instanceof Import) {
				String location = ((Import) object).getLocationURI();
				
				if (location == null || location.trim().equals(""))
					setEnabled(false);
			}
		}
		
		public void run() {
			Definition definition = ((WSDLElement) object).getEnclosingDefinition();
			org.eclipse.wst.wsdl.ui.internal.util.OpenOnSelectionHelper helper = new org.eclipse.wst.wsdl.ui.internal.util.OpenOnSelectionHelper(definition);
		    helper.openEditor((org.eclipse.emf.ecore.EObject) object);
		}
	}

  public void contributeMenuActions(final IMenuManager menu, final Node node, Object object)
  {
    final IMenuManager addMenu;
    boolean addEditAction = false;
    final boolean isEditable = (node instanceof IDOMNode);
    if (object instanceof WSDLElement && node != null && isEditable)
    {
      addEditAction = true;
      addMenu = new MenuManager(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_CHILD"), "addchild"); //$NON-NLS-1$ //$NON-NLS-2$
      menu.add(addMenu);
      Definition definition = ((WSDLElement) object).getEnclosingDefinition();

      final String prefix = definition.getPrefix(WSDLConstants.WSDL_NAMESPACE_URI);

      if (object instanceof Import) {
      	menu.add(new OpenSchemaOnSelectionHelper(object));
      }
      
      WSDLSwitch wsdlSwitch = new WSDLSwitch()
      {
        public Object caseBinding(Binding binding)
        {
          if (isEditable)
          {
            menu.add(new AddBindingOperationAction(node, "NewBindingOperation", prefix)); //$NON-NLS-1$
            menu.add(new Separator());
          }
          
          menu.add(createSetPortTypeMenu(binding, isEditable));
          menu.add(new GenerateBindingContentAction(binding, isEditable));
          return null;
        }

        public Object caseBindingOperation(BindingOperation bindingOperation)
        {
          if (isEditable)
          {
            menu.add(new AddBindingInputAction(editorPart, node, prefix));
            menu.add(new AddBindingOutputAction(editorPart, node, prefix));
            menu.add(new AddBindingFaultAction(node, prefix));
          }
          return null;
        }

        public Object caseDefinition(Definition definition)
        {
           menu.add(new EditNamespacesAction(definition));
           menu.add(new Separator());
        	
          if (isEditable)
          {
            menu.add(new AddMessageAction(definition, null, node, prefix, ((WSDLEditor) editorPart).getXMLDocument()));
            menu.add(new AddServiceAction(definition, null, node, prefix, ((WSDLEditor) editorPart).getXMLDocument()));
            menu.add(new AddPortTypeAction(definition, null, node, prefix, ((WSDLEditor) editorPart).getXMLDocument()));
            menu.add(new AddBindingAction(definition, ((WSDLEditor) editorPart).getXMLDocument()));//, null, node, prefix));
            menu.add(new AddImportAction(editorPart, definition, node, prefix));
          }
          return null;
        }

        public Object caseFault(Fault fault)
        {
          menu.add(createSetMessageMenu(fault, isEditable));
          //menu.add(createAddBindingMenuForIOF(fault));
          return null;
        }

        public Object caseInput(Input input)
        {
          menu.add(createSetMessageMenu(input, isEditable));
          //menu.add(createAddBindingMenuForIOF(input));
          return null;
        }

        public Object caseOutput(Output output)
        {
          menu.add(createSetMessageMenu(output, isEditable));
          //menu.add(createAddBindingMenuForIOF(output));
          return null;
        }

        public Object caseMessage(Message message)
        {
          if (isEditable)
          {
            menu.add(new AddPartAction(editorPart, message, node, prefix));
          }
          return null;
        }

        public Object caseOperation(Operation operation)
        {
          if (isEditable)
          {
            menu.add(new AddInputAction(editorPart, node, operation, prefix));
            menu.add(new AddOutputAction(editorPart, node, operation, prefix));
            menu.add(new AddFaultAction(editorPart, node, operation, prefix));
          }
          //menu.add(createAddBindingMenuForOperation(operation));
          return null;
        }

        public Object casePart(Part part)
        {
          menu.add(createSetPartMenu(part, (Element) node, "element", isEditable)); //$NON-NLS-1$
          menu.add(createSetPartMenu(part, (Element) node, "type", isEditable)); //$NON-NLS-1$
          return null;
        }

        public Object casePort(Port port)
        {
          if (node instanceof Element)
          {
            menu.add(createSetBindingMenu(port, (Element) node, isEditable));
            if (port.getEBinding() != null)
            {
              menu.add(createSetPortTypeMenu(port.getEBinding(), isEditable));
            }
          }
          return null;
        }

        public Object casePortType(PortType portType)
        {
          if (isEditable)
          {
            menu.add(new AddOperationAction(editorPart, portType, node, prefix));
          }
          return null;
        }

        public Object caseService(Service service)
        {
          if (isEditable)
          {
            menu.add(new AddPortAction(service));
          }
          return null;
        }

        //public Object caseTypes(Types types)
        //{   
        //  return createTypesAdapter();
        // } 
      };
      wsdlSwitch.doSwitch((WSDLElement) object);
    }
    else if (object instanceof WSDLGroupObject)
    {
      addMenu = new MenuManager(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_CHILD"), "addchild"); //$NON-NLS-1$ //$NON-NLS-2$
      menu.add(addMenu);
      
      WSDLGroupObject groupObject = (WSDLGroupObject) object;
      Definition definition = groupObject.getDefinition();

      final String prefix = definition.getPrefix(WSDLConstants.WSDL_NAMESPACE_URI);

      //for (Iterator i = actionList.iterator(); i.hasNext(); )
      //{                           
      //  Action action = (Action)i.next();
      //  manager.add(action); 
      //}

      switch (groupObject.getType())
      {
        case WSDLGroupObject.MESSAGES_GROUP :
          {
            menu.add(new AddMessageAction(groupObject.getDefinition(), null, node, prefix, ((WSDLEditor) editorPart).getXMLDocument()));
            break;
          }
        case WSDLGroupObject.SERVICES_GROUP :
          {
            menu.add(new AddServiceAction(groupObject.getDefinition(), null, node, prefix, ((WSDLEditor) editorPart).getXMLDocument()));
            break;
          }
        case WSDLGroupObject.PORT_TYPES_GROUP :
          {
            menu.add(new AddPortTypeAction(groupObject.getDefinition(), null, node, prefix, ((WSDLEditor) editorPart).getXMLDocument()));
            break;
          }
        case WSDLGroupObject.BINDINGS_GROUP :
          {
            menu.add(new AddBindingAction(groupObject.getDefinition(), ((WSDLEditor) editorPart).getXMLDocument()));//, null, node, prefix));
            break;
          }
        case WSDLGroupObject.IMPORTS_GROUP :
          {
            menu.add(new AddImportAction(editorPart, groupObject.getDefinition(), node, prefix));
            break;
          }
      }
    }

    menu.add(new Separator());
    
   	addEEMenuActionContributor.contributeMenuActions(menu, node, object);

    menu.add(new Separator());

    if (object instanceof WSDLElement && node != null && addEditAction && node != null && isEditable)
    {
      //////////////////////////////////////// Currently, only allow Copy and Paste on Operations
    	if (object instanceof Operation) {
    		// Add Cut, Copy Actions
    		// Note:  The Cut, Copy, Paste Actions are Model Driven.  The Delete Action is still
    		// currently DOM driven.
    		//      menu.add(new CutAction((WSDLElement) object, editorPart));
   		 	menu.add(new CopyGlobalAction((WSDLElement) object, editorPart));
    	}

   	 	Action pasteAction = new PasteGlobalAction((WSDLElement) object, editorPart);
   	 	if (pasteAction.isEnabled()) {
   	 		menu.add(pasteAction);
   	 	}
   	 	
	 	menu.add(new Separator());
      //////////////////////////////////////// Currently, only allow Copy and Paste on Operations
		
		// Get the list of selected elements.  Use this list for the DeleteAction.		
		IStructuredSelection selectionList = (IStructuredSelection) ((WSDLEditor) editorPart).getSelectionManager().getSelection();	
		Action deleteAtion = new DeleteWSDLAndXSDAction(selectionList.toList(), node, (WSDLEditor) editorPart);
		menu.add(deleteAtion);
		deleteAtion.setEnabled(isEditable);
    }
       
    // insertion point for popupMenus extension
    menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
  }

  /*
  protected MenuManager createAddBindingMenuForOperation(Operation operation) 
  {
    MenuManager subMenu = new MenuManager("Add Binding");                    
  
    Definition definition = operation.getEnclosingDefinition(); 
    ComponentReferenceUtil util = new ComponentReferenceUtil(definition);
  
    String operationName = operation.getName();
    if (operationName != null)
    {       
      for (Iterator i = util.getBindings(operation).iterator(); i.hasNext(); )
      {   
        Binding binding = (Binding)i.next();
            
        BindingOperation matchingBindingOperation = null;
  
        for (Iterator j = binding.getBindingOperations().iterator(); j.hasNext(); )
        {
          BindingOperation bindingOperation = (BindingOperation)j.next();
          if (operationName.equals(bindingOperation.getName()))
          { 
            matchingBindingOperation = bindingOperation;
            break;
          }
        }         
  
        if (matchingBindingOperation == null)
        {                                                                            
          Element bindingElement = WSDLUtil.getInstance().getElementForObject(binding);
          subMenu.add(new AddBindingOperationAction(bindingElement, operation, prefix));
        }    
      }
    }
    return subMenu;
  }*/

  /*
  protected MenuManager createAddBindingMenuForIOF(WSDLElement iof) 
  {
    MenuManager subMenu = new MenuManager("Add Binding");                    
  
    Definition definition = iof.getEnclosingDefinition(); 
    Operation operation = (Operation)iof.eContainer();
  
    ComponentReferenceUtil util = new ComponentReferenceUtil(definition);
  
    String operationName = operation.getName();
    if (operationName != null)
    {  
      for (Iterator i = util.getBindings(operation).iterator(); i.hasNext(); )
      {   
        Binding binding = (Binding)i.next();
  
        boolean hasName = false;
        for (Iterator j = binding.getBindingOperations().iterator(); j.hasNext(); )
        {
          BindingOperation bindingOperation = (BindingOperation)j.next();
          if (operationName.equals(bindingOperation.getName()))
          {
            hasName = true;
            break;
          }
        }         
  
        if (!hasName)
        {                                                                            
          // TODO... should we add the operation to all of the bindings?
          //
          Element bindingElement = WSDLUtil.getInstance().getElementForObject(binding);
          subMenu.add(new AddBindingOperationAction(bindingElement, operationName));
        }
      }
    }
    return subMenu;
  }
  */

  protected MenuManager createSetBindingMenu(Port port, Element portElement, boolean isEditable)
  {
    MenuManager submenu = new MenuManager(WSDLEditorPlugin.getWSDLString("_UI_ACTION_SET_BINDING"));

    Definition definition = port.getEnclosingDefinition();
    String prefix = definition.getPrefix(WSDLConstants.WSDL_NAMESPACE_URI);
    Element definitionElement = WSDLEditorUtil.getInstance().getElementForObject(definition);

    SetNewComponentAction setNewAction = new SetNewComponentAction(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_BINDING"), definitionElement, prefix, "binding", port);
    setNewAction.setEditor(editorPart);
    setNewAction.setEnabled(true);
    submenu.add(setNewAction);     
    
    SetExistingComponentAction action = new SetExistingComponentAction(WSDLEditorPlugin.getWSDLString("_UI_ACTION_EXISTING_BINDING"), definitionElement, prefix, "binding", port);
    action.setEditor(editorPart);
    action.setEnabled(isEditable);
    submenu.add(action);
    
    return submenu;
  }

  protected MenuManager createSetPortTypeMenu(Binding binding, boolean isEditable)
  {      
    MenuManager submenu = new MenuManager(WSDLEditorPlugin.getWSDLString("_UI_ACTION_SET_PORTTYPE"));

    if (binding != null)
    {
      Definition definition = binding.getEnclosingDefinition();
      Element definitionElement = WSDLEditorUtil.getInstance().getElementForObject(definition);
      String prefix = definition.getPrefix(WSDLConstants.WSDL_NAMESPACE_URI);
	  
      SetNewComponentAction setNewAction = new SetNewComponentAction(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_PORTTYPE"), definitionElement, prefix, "portType", binding);
      setNewAction.setEditor(editorPart);
      setNewAction.setEnabled(true);
      submenu.add(setNewAction);      

      SetExistingComponentAction action = new SetExistingComponentAction(WSDLEditorPlugin.getWSDLString("_UI_ACTION_EXISTING_PORTTYPE"), definitionElement, prefix, "portType", binding);
      action.setEditor(editorPart);
      action.setEnabled(isEditable);      
      submenu.add(action);
    }
    return submenu;
  }

  protected MenuManager createSetMessageMenu(WSDLElement wsdlElement, boolean isEditable)
  {
    Definition definition = wsdlElement.getEnclosingDefinition();
    Element definitionElement = WSDLEditorUtil.getInstance().getElementForObject(definition);
    Element referencingElement = WSDLEditorUtil.getInstance().getElementForObject(wsdlElement);
	
    MenuManager submenu = new MenuManager(WSDLEditorPlugin.getWSDLString("_UI_ACTION_SET_MESSAGE"));
    if (definitionElement != null && referencingElement != null)
    {
      String prefix = definition.getPrefix(WSDLConstants.WSDL_NAMESPACE_URI);
      
      SetNewComponentAction setNewAction = new SetNewComponentAction(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_MESSAGE"), definitionElement, prefix, "message", wsdlElement);
      setNewAction.setEditor(editorPart);
      setNewAction.setEnabled(true);
      submenu.add(setNewAction);  
      
      SetExistingComponentAction action = new SetExistingComponentAction(WSDLEditorPlugin.getWSDLString("_UI_ACTION_EXISTING_MESSAGE"), definitionElement, prefix, "message", wsdlElement);
      action.setEditor(editorPart);
      action.setEnabled(isEditable);
      submenu.add(action);
    }
    
    return submenu;
  }

  protected MenuManager createSetPartMenu(Part part, Element portElement, String referenceKind, boolean isEditable)
  {
    Definition definition = part.getEnclosingDefinition();
    String prefix = definition.getPrefix(WSDLConstants.WSDL_NAMESPACE_URI);
    Element definitionElement = WSDLEditorUtil.getInstance().getElementForObject(definition);

    String actionName;
    MenuManager submenu = null;
    if (referenceKind.equalsIgnoreCase("element")) // NON NLS
    {
      actionName = WSDLEditorPlugin.getWSDLString("_UI_ACTION_EXISTING_ELEMENT");
      submenu = new MenuManager(WSDLEditorPlugin.getWSDLString("_UI_ACTION_SET_ELEMENT"));
	  
      SetNewComponentAction setNewElementAction = new SetNewComponentAction(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_ELEMENT"), definitionElement, prefix, "element", part);
      setNewElementAction.setEditor(editorPart);
      setNewElementAction.setEnabled(true);
      setNewElementAction.setReferenceKind(referenceKind);
      submenu.add(setNewElementAction);
    }
    else
    {
      actionName = WSDLEditorPlugin.getWSDLString("_UI_ACTION_EXISTING_TYPE");
      submenu = new MenuManager(WSDLEditorPlugin.getWSDLString("_UI_ACTION_SET_TYPE"));
      
      SetNewComponentAction setNewComplexAction = new SetNewComponentAction(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_COMPLEX_TYPE"), definitionElement, prefix, "complex type", part);
      setNewComplexAction.setEditor(editorPart);
      setNewComplexAction.setEnabled(true);
      setNewComplexAction.setReferenceKind(referenceKind);
      setNewComplexAction.setTypeKind("complex");
      Image image = XSDEditorPlugin.getXSDImage("icons/XSDComplexType.gif");
      setNewComplexAction.setImageDescriptor(ImageDescriptor.createFromImage(image));
      submenu.add(setNewComplexAction);
      
      SetNewComponentAction setNewSimpleAction = new SetNewComponentAction(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_SIMPLE_TYPE"), definitionElement, prefix, "simple type", part);
      setNewSimpleAction.setEditor(editorPart);
      setNewSimpleAction.setEnabled(true);
      setNewSimpleAction.setReferenceKind(referenceKind);
      setNewSimpleAction.setTypeKind("simple");
      image = XSDEditorPlugin.getXSDImage("icons/XSDSimpleType.gif");
      setNewSimpleAction.setImageDescriptor(ImageDescriptor.createFromImage(image));

      submenu.add(setNewSimpleAction); 
    }

    
    SetExistingComponentAction action = new SetExistingComponentAction(actionName, definitionElement, prefix, actionName, part);
    action.setReferenceKind(referenceKind);
    action.setEditor(editorPart);
    action.setEnabled(isEditable);
    submenu.add(action);
    
    return submenu;
  }
  
//  private WSDLElement showPasteAction(WSDLElement element, IEditorPart ePart) {
//  	WSDLElement parentElement = null;
//  	
//  	if (ePart instanceof WSDLEditor) {
//  		WSDLElement clipboardElement = ((WSDLEditor) ePart).getClipboardContents();
//  		
//  		if (element instanceof PortType) {
//  			if (clipboardElement instanceof Operation) {
//  				parentElement = element;
//  			}
//  		}
//  		if (element instanceof Operation) {
//  			if (clipboardElement instanceof Operation) {
//  				parentElement = (WSDLElement) ((Operation) element).eContainer();
//  			}
//  		}
//  	}
//  	
//  	return parentElement;
//  }
}

class AddBindingOperationAction extends AddElementAction
{
  protected String name;
  protected Operation operation;

  public AddBindingOperationAction(Node parentNode, String name, String prefix)
  {
    // super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD") + " " + WSDLEditorPlugin.getWSDLString("_UI_LABEL_BINDING_OPERATION"), "icons/operationbinding_obj.gif", parentNode, prefix, "operation");
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_BINDING_OPERATION"), "icons/operationbinding_obj.gif", parentNode, prefix, "operation");
    this.name = name;
  }

  public AddBindingOperationAction(Node parentNode, Operation operation, String prefix)
  {
    this(parentNode, operation.getName(), prefix);
    this.operation = operation;
  }

  protected void addAttributes(Element newElement)
  {
    newElement.setAttribute("name", name);
  }

  protected void performAddElement()
  {
    super.performAddElement();

    if (operation != null)
    {
      if (operation.getInput() != null)
      {
        new AddBindingInputAction(editorPart, newElement, prefix).run();
      }
      if (operation.getOutput() != null)
      {
        new AddBindingOutputAction(editorPart, newElement, prefix).run();
      }
      for (Iterator i = operation.getEFaults().iterator(); i.hasNext();)
      {
        Fault fault = (Fault) i.next();
        new AddBindingFaultAction(newElement, fault, prefix).run();
      }
      format(operation.getElement());
    }
  }
}


class AddOperationAction extends AddElementAction
{
  protected String name = "NewOperation";
  protected PortType portType;
  protected boolean createSubComponents = false;

  public AddOperationAction(IEditorPart editorPart, PortType portType, Node parentNode, String prefix)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_OPERATION"), "icons/operation_obj.gif", parentNode, prefix, "operation");
    setEditorPart(editorPart);
    setDefinition(portType.getEnclosingDefinition());
    this.portType = portType;
  }

  public boolean showDialog()
  {
    name = NameUtil.buildUniqueOperationName(portType);
    name = showDialogHelper(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_OPERATION"), name, NameUtil.getUsedOperationNames(portType));
    return name != null;
  }

//  protected void addAttributes(Element newElement)
//  {
//    newElement.setAttribute("name", name);
//  }

  protected void performAddElement()
  {
  	if (createSubComponents) {
  	  	CreateWSDLElementHelper.operationName = name;
  	  	CreateWSDLElementHelper.PART_TYPE_OR_DEFINITION = CreateWSDLElementHelper.getPartInfo(portType);
  		Operation operation = CreateWSDLElementHelper.createOperation(portType);
  		format(operation.getElement());  		
  		selectObject(operation);
  		expandEditParts(operation,true);
  	}
  	else {
  		// Add Operation
  		AddOperationCommand opAction = new AddOperationCommand(portType, name);
		opAction.run();
		Operation operation = (Operation) opAction.getWSDLElement();
		
		// Add Output
  		AddOutputCommand outAction = new AddOutputCommand(operation, NameUtil.buildUniqueInputName(portType, operation.getName(), ""));
  		outAction.run();
  		
		// Add Input
		AddInputCommand inAction = new AddInputCommand(operation, NameUtil.buildUniqueOutputName(portType, operation.getName(), ""));
  		inAction.run();

  		format(operation.getElement());

 	  	selectObject(operation);
 	  	expandEditParts(operation, true);
  	}
  }

	private void expandEditParts(Object element, boolean expandChildren) {
	    if (element != null) {
	    	EditPartViewer editPartViewer = ((WSDLEditor) editorPart).getGraphViewer().getComponentViewer();
	    	Map editPartMap = editPartViewer.getEditPartRegistry();
	    	WSDLTreeNodeEditPart wsdlEditPart = (WSDLTreeNodeEditPart) editPartMap.get(element);
			wsdlEditPart.setExpanded(true);
			
			if (expandChildren) {
				Iterator iterator = WSDLEditorUtil.getModelGraphViewChildren(element).iterator();
				
				while (iterator.hasNext()) {
					expandEditParts(iterator.next(), expandChildren);
				}
			}
	    }
	}

  public String showDialogHelper(String title, String defaultName, List usedNames)
  {   
    String result = defaultName; 
    NewComponentWithChildDialog dialog = new NewComponentWithChildDialog(WSDLEditorPlugin.getShell(), title, defaultName, usedNames);
    int rc = dialog.createAndOpen();
    if (rc == IDialogConstants.OK_ID)
    {
      result = dialog.getName();  
      createSubComponents = dialog.createSubComponents();
    }
    else
    {
      result = null;
    }               
    return result;
  }
}

abstract class AddIOFAction extends AddElementAction
{
  protected Operation operation;

  public AddIOFAction(IEditorPart editorPart, String text, String imageDescriptorKey, Node parentNode, String prefix, String localName, Operation operation)
  {
    super(text, imageDescriptorKey, parentNode, prefix, localName);
    this.operation = operation;
    setEditorPart(editorPart);
    setDefinition(operation.getEnclosingDefinition());
  }

  abstract protected void performAddElementToBindingOperation(BindingOperation bindingOperation, Element bindingOperationElement);

  /*
  protected void addAttributes(Element newElement)
  {
    newElement.setAttribute("message", "");
  }
  */

  protected void performAddElement()
  {
    if (operation != null)
    {
      Definition definition = operation.getEnclosingDefinition();
      ComponentReferenceUtil util = new ComponentReferenceUtil(definition);

      for (Iterator i = util.getBindingOperations(operation).iterator(); i.hasNext();)
      {
        BindingOperation bindingOperation = (BindingOperation) i.next();
        Element bindingOperationElement = WSDLEditorUtil.getInstance().getElementForObject(bindingOperation);
        if (bindingOperationElement != null)
        {
          performAddElementToBindingOperation(bindingOperation, bindingOperationElement);
        }
      }
      format(operation.getElement());
    }
  }
}

class AddInputAction extends AddIOFAction
{
  public AddInputAction(IEditorPart editorPart, Node parentNode, Operation operation, String prefix)
  {
    super(editorPart, WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_INPUT"), "icons/input_obj.gif", parentNode, prefix, "input", operation);
  }

  protected void performAddElementToBindingOperation(BindingOperation bindingOperation, Element bindingOperationElement)
  {
    if (bindingOperation.getBindingInput() == null)
    {
      new AddBindingInputAction(editorPart, bindingOperationElement, prefix).run();
    }
  }
  
  protected void performAddElement() {
  	PortType portType = (PortType) ((WSDLElementImpl) operation).getContainer();
  	CreateWSDLElementHelper.PART_TYPE_OR_DEFINITION = CreateWSDLElementHelper.getPartInfo(portType);
  	Input input = CreateWSDLElementHelper.createInput(portType, operation, null); 
  	format(input.getElement());
  	selectObject(input);
  }
}

class AddOutputAction extends AddIOFAction
{
  public AddOutputAction(IEditorPart editorPart, Node parentNode, Operation operation, String prefix)
  {
    super(editorPart, WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_OUTPUT"), "icons/output_obj.gif", parentNode, prefix, "output", operation);
  }

  protected void performAddElementToBindingOperation(BindingOperation bindingOperation, Element bindingOperationElement)
  {
    if (bindingOperation.getBindingOutput() == null)
    {
      new AddBindingOutputAction(editorPart, bindingOperationElement, prefix).run();
    }
  }
  
  protected void performAddElement() {
  	// Determine Part info
  	PortType portType = (PortType) ((WSDLElementImpl) operation).getContainer();
  	CreateWSDLElementHelper.PART_TYPE_OR_DEFINITION = CreateWSDLElementHelper.getPartInfo(portType);
  	Output output = CreateWSDLElementHelper.createOutput(portType, operation); 
  	format(output.getElement());
  	selectObject(output);
  }
}

class AddFaultAction extends AddIOFAction
{
  protected String name = "NewFault";
  public AddFaultAction(IEditorPart editorPart, Node parentNode, Operation operation, String prefix)
  {
    super(editorPart, WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_FAULT"), "icons/fault_obj.gif", parentNode, prefix, "fault", operation);
    name = NameUtil.buildUniqueFaultName(operation);
  }

  public boolean showDialog()
  {
    name = NameUtil.buildUniqueFaultName(operation);
    name = showDialogHelper(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_FAULT"), name, NameUtil.getUsedFaultNames(operation));
    return name != null;
  }

  /*
  protected void addAttributes(Element newElement)
  {
    newElement.setAttribute("message", "");
    newElement.setAttribute("name", name);
  }
  */

  protected void performAddElementToBindingOperation(BindingOperation bindingOperation, Element bindingOperationElement)
  {
    if (bindingOperation.getBindingFault(name) == null)
    {
      new AddBindingFaultAction(bindingOperationElement, prefix).run();
    }
  }
  
  protected void performAddElement() {
  	CreateWSDLElementHelper.faultName = name;
  	CreateWSDLElementHelper.PART_TYPE_OR_DEFINITION = CreateWSDLElementHelper.getPartInfo(operation);
  	Fault fault = CreateWSDLElementHelper.createFault(operation);
  	format(fault.getElement());  	
  	selectObject(fault);
  }
}

class AddBindingInputAction extends AddElementAction
{
  public AddBindingInputAction(IEditorPart editorPart, Node parentNode, String prefix)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_INPUT"), "icons/input_obj.gif", parentNode, prefix, "input");
    setEditorPart(editorPart);
  }
}

class AddBindingOutputAction extends AddElementAction
{
  public AddBindingOutputAction(IEditorPart editorPart, Node parentNode, String prefix)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_OUTPUT"), "icons/output_obj.gif", parentNode, prefix, "output");
    setEditorPart(editorPart);
  }
}

class AddBindingFaultAction extends AddElementAction
{
  protected Fault fault;

  public AddBindingFaultAction(Node parentNode, String prefix)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_FAULT"), "icons/fault_obj.gif", parentNode, prefix, "fault");
  }

  public AddBindingFaultAction(Node parentNode, Fault fault, String prefix)
  {
    this(parentNode, prefix);
    this.fault = fault;
  }

  protected void addAttributes(Element newElement)
  {
    if (fault == null)
    {
      newElement.setAttribute("name", "NewFault");
    }
    else
    {
      newElement.setAttribute("name", fault.getName());
    }
  }
}

class AddMessageAction extends AddElementAction
{
  protected Definition definition;
  protected String name;

  public AddMessageAction(Definition definition, String name, Node parentNode, String prefix)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_MESSAGE"), "icons/message_obj.gif", parentNode, prefix, "message");
    this.definition = definition;
    this.name = name;
    setComputeTopLevelRefChild(true);
  }

  public AddMessageAction(Definition definition, String name, Node parentNode, String prefix, Document document)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_MESSAGE"), "icons/message_obj.gif", parentNode, prefix, "message");
    this.definition = definition;
    this.name = name;
    this.setDefinition(definition);
    this.document = document;
    setComputeTopLevelRefChild(true);
  }
  
  public boolean showDialog()
  {
    name = NameUtil.buildUniqueMessageName(definition, name);
    name = showDialogHelper(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_MESSAGE"), name, NameUtil.getUsedMessageNames(definition));
    return name != null;
  }

//  protected void addAttributes(Element newElement)
//  {
//    newElement.setAttribute("name", name);
//  }
  
  protected void performAddElement() {
  	NodeList list = document.getChildNodes();
  	if (parentNode == null|| list.getLength() == 0) {
  		createDefinitionStub();
  	}
  	
  	AddMessageCommand action = new AddMessageCommand(definition, name);
	action.run();
	Message message = (Message) action.getWSDLElement();
	CreateWSDLElementHelper.createPart(message);
	format(message.getElement());
	selectObject(message);
  }

  public String getName()
  {
    return name;
  }
}

class AddPartAction extends AddElementAction
{
  protected Message message;
  protected String name;

  public AddPartAction(IEditorPart editorPart, Message message, Node parentNode, String prefix)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_PART"), "icons/part_obj.gif", parentNode, prefix, "part");
    this.message = message;
    setEditorPart(editorPart);
    setDefinition(message.getEnclosingDefinition());
  }

  public boolean showDialog()
  {
    name = NameUtil.buildUniquePartName(message, message.getQName().getLocalPart());
    name = showDialogHelper(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_PART"), name, NameUtil.getUsedPartNames(message));
    return name != null;
  }

  protected void addAttributes(Element newElement)
  {
    newElement.setAttribute("name", name);
    String xsdPrefix = message.getEnclosingDefinition().getPrefix(WSDLConstants.XSD_NAMESPACE_URI);
    if (xsdPrefix == null)
    {
    	Element definitionElement = WSDLEditorUtil.getInstance().getElementForObject(message.getEnclosingDefinition());    	
        new AddNamespaceDeclarationsAction(definitionElement, WSDLConstants.XSD_NAMESPACE_URI, "xsd").run();
		xsdPrefix = message.getEnclosingDefinition().getPrefix(WSDLConstants.XSD_NAMESPACE_URI);
    }
			
    String defaultTypeName = "string";
    if (xsdPrefix != null && xsdPrefix.length() > 0)
    {
      defaultTypeName = xsdPrefix + ":" + defaultTypeName;
    }
    newElement.setAttribute("type", defaultTypeName);
  }
}

class AddServiceAction extends AddElementAction
{
  protected String name;
  protected Definition definition;

  public AddServiceAction(Definition definition, String name, Node parentNode, String prefix)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_SERVICE"), "icons/service_obj.gif", parentNode, prefix, "service");
    this.definition = definition;
    this.name = name;
    setComputeTopLevelRefChild(true);
  }

  public AddServiceAction(Definition definition, String name, Node parentNode, String prefix, Document document)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_SERVICE"), "icons/service_obj.gif", parentNode, prefix, "service");
    this.definition = definition;
    this.name = name;
    this.setDefinition(definition);
    this.document = document;
    setComputeTopLevelRefChild(true);
  }

  public boolean showDialog()
  {
    if (name == null)
    {
      name = NameUtil.buildUniqueServiceName(definition);
    }
    name = showDialogHelper(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_SERVICE"), name, NameUtil.getUsedServiceNames(definition));
    return name != null;
  }

  protected void addAttributes(Element newElement)
  {
    newElement.setAttribute("name", name);
  }
  
  protected void performAddElement() {  	
  	NodeList list = document.getChildNodes();
  	if (parentNode == null || list.getLength() == 0) {
  		createDefinitionStub();
  	}
  	
  	super.performAddElement();
  }
}

class AddPortTypeAction extends AddElementAction
{
  protected String name;
  protected Definition definition;

  public AddPortTypeAction(Definition definition, String name, Node parentNode, String prefix)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_PORTTYPE"), "icons/porttype_obj.gif", parentNode, prefix, "portType");
    this.definition = definition;
    this.name = name;
    setComputeTopLevelRefChild(true);
  }

  public AddPortTypeAction(Definition definition, String name, Node parentNode, String prefix, Document document)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_PORTTYPE"), "icons/porttype_obj.gif", parentNode, prefix, "portType");
    this.definition = definition;
    this.name = name;
    this.setDefinition(definition);
    this.document = document;
    setComputeTopLevelRefChild(true);
  }
  
  public boolean showDialog()
  {
    name = NameUtil.buildUniquePortTypeName(definition, name);
    name = showDialogHelper(WSDLEditorPlugin.getWSDLString("_UI_ACTION_NEW_PORTTYPE"), name, NameUtil.getUsedPortTypeNames(definition));
    return name != null;
  }

  protected void addAttributes(Element newElement)
  {
    newElement.setAttribute("name", name);
  }

  public String getPortTypeName()
  {
    return name;
  }
  
  protected void performAddElement() {
  	NodeList list = document.getChildNodes();
  	if (parentNode == null || list.getLength() == 0) {
  		createDefinitionStub();
  	}
  	
  	super.performAddElement();
  }
}

class AddBindingAction extends Action
{
  protected Definition definition;
  protected Document document;

  public AddBindingAction(Definition definition, Document document)
  {
    super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_BINDING"), ImageDescriptor.createFromFile(WSDLEditorPlugin.class, "icons/binding_obj.gif")); //$NON-NLS-1$
    //setToolTipText(WSDLEditorPlugin.getInstance().getWSDLString("_UI_LABEL_BINDING_WIZARD")); //$NON-NLS-1$
    this.definition = definition;
    this.document = document;
  }

  public void run()
  {
    BindingWizard wizard = new BindingWizard(definition, document);
    WizardDialog wizardDialog = new WizardDialog(Display.getCurrent().getActiveShell(), wizard);
    wizardDialog.create();

    int result = wizardDialog.open();

    if (result == Window.OK)
    {
      //todo...      
    }
  }
}

class AddPortAction extends Action
{
	protected Service service;

	public AddPortAction(Service service)
	{
		super(WSDLEditorPlugin.getWSDLString("_UI_ACTION_ADD_PORT"), ImageDescriptor.createFromFile(WSDLEditorPlugin.class, "icons/binding_obj.gif")); //$NON-NLS-1$
		//setToolTipText(WSDLEditorPlugin.getInstance().getWSDLString("_UI_LABEL_BINDING_WIZARD")); //$NON-NLS-1$
		this.service = service;
	}

	public void run()
	{
		PortWizard wizard = new PortWizard(service);
		WizardDialog wizardDialog = new WizardDialog(Display.getCurrent().getActiveShell(), wizard);
		wizardDialog.create();

		int result = wizardDialog.open();
		if (result == Window.OK)
		{
			//todo...      
		}
	}
}

class GenerateBindingContentAction extends Action
{
	protected Binding binding;
	public GenerateBindingContentAction(Binding binding, boolean isEditable)
	{
		super(WSDLEditorPlugin.getWSDLString("_UI_GENERATE_BINDING_CONTENT"));
		this.binding = binding;
		setEnabled(isEditable);
	}
	
	public void run()
	{
		BindingWizard wizard = new BindingWizard(binding.getEnclosingDefinition(), binding, BindingWizard.KIND_REGENERATE_BINDING);
		wizard.setBindingName(ComponentReferenceUtil.getName(binding));
		wizard.setPortTypeName(ComponentReferenceUtil.getPortTypeReference(binding));
		WizardDialog wizardDialog = new WizardDialog(Display.getCurrent().getActiveShell(), wizard);
		wizardDialog.create();
		wizardDialog.open();	
	}
}