/*******************************************************************************
 * 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.NewComponentDialog;
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);
    }
    
    // Allow Rename through a dialog mechanism.....  This should be changed when
    // direct editing is ready
    if (object instanceof WSDLElement && isEditable) {
    	RenameDialogAction renameDialog = new RenameDialogAction((WSDLElement) object);
    	if (renameDialog.showRenameDialog())
    		menu.add(renameDialog);
    }
    
    // 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();	
	}
}

//This is a temporary class to allow renaming.  This should be replaced when direct
//renaming is ready
class RenameDialogAction extends Action {
	private WSDLElement element;
	private String defaultName = "NewName";
	private List usedNames = new ArrayList();
	private boolean useSmartRename = false;
	private boolean showDialog = false;
	
	public RenameDialogAction(WSDLElement selection) {
		setText(WSDLEditorPlugin.getWSDLString("_UI_ACTION_RENAME"));
		element = selection;
		initialize();
	}
	
	public void run() {
		String result;

		NewComponentDialog dialog = new NewComponentDialog(WSDLEditorPlugin.getShell(), WSDLEditorPlugin.getWSDLString("_UI_ACTION_RENAME"), defaultName, usedNames);
		int rc = dialog.createAndOpen();
		if (rc == IDialogConstants.OK_ID)
		{
		  result = dialog.getName();
		  if (useSmartRename) {
		  	SmartRenameAction smartRename = new SmartRenameAction(element, result);	
		  	smartRename.run();
		  }
		  else {
		  	RenameAction rename = new RenameAction(element, result);
		  	rename.run();
		  }
		}
	}
	
	public void initialize() {
		if (element instanceof Fault) {
			usedNames = NameUtil.getUsedFaultNames((Operation) ((Fault) element).eContainer());
			defaultName = ((Fault) element).getName();
			
			showDialog = true;
			useSmartRename = true;
		}
		else if (element instanceof Message) {
			usedNames = NameUtil.getUsedMessageNames(element.getEnclosingDefinition());
			defaultName = ((Message) element).getQName().getLocalPart();
			
			showDialog = true;
			useSmartRename = true;
		}
		else if (element instanceof Operation) {
			usedNames = NameUtil.getUsedOperationNames((PortType) ((Operation) element).eContainer());		
			defaultName = ((Operation) element).getName();
			
			showDialog = true;
			useSmartRename = true;
		}
		else if (element instanceof Part) {
			usedNames = NameUtil.getUsedPartNames((Message) ((Part) element).eContainer());			
			defaultName = ((Part) element).getName();
			
			showDialog = true;
			useSmartRename = true;
		}
		else if (element instanceof PortType) {
			usedNames = NameUtil.getUsedPortTypeNames(element.getEnclosingDefinition());
			defaultName = ((PortType) element).getQName().getLocalPart();
			
			showDialog = true;
			useSmartRename = false;
		}
		else if (element instanceof Port) {
			usedNames = NameUtil.getUsedPortNames((Service) ((Port) element).eContainer());
			defaultName = ((Port) element).getName();
			
			showDialog = true;
			useSmartRename = true;
		}
		else if (element instanceof Binding) {
			usedNames = NameUtil.getUsedBindingNames(element.getEnclosingDefinition());			
			defaultName = ((Binding) element).getQName().getLocalPart();
			
			showDialog = true;
			useSmartRename = false;
		}
		else if (element instanceof Service) {
			usedNames = NameUtil.getUsedServiceNames(element.getEnclosingDefinition());
			defaultName = ((Service) element).getQName().getLocalPart();
			
			showDialog = true;
			useSmartRename = false;
		}
		usedNames.remove(defaultName);
	}
	
	public boolean showRenameDialog() {
		return showDialog;
	}
}