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

  /*
  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 {
  		Definition def = portType.getEnclosingDefinition();	
		
  		// 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(), 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;
	}
}