/*******************************************************************************
 * 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 org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.wst.wsdl.Binding;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Fault;
import org.eclipse.wst.wsdl.Input;
import org.eclipse.wst.wsdl.Message;
import org.eclipse.wst.wsdl.MessageReference;
import org.eclipse.wst.wsdl.Output;
import org.eclipse.wst.wsdl.Part;
import org.eclipse.wst.wsdl.Port;
import org.eclipse.wst.wsdl.WSDLElement;
import org.eclipse.wst.wsdl.binding.soap.internal.util.SOAPConstants;
import org.eclipse.wst.wsdl.internal.generator.BindingGenerator;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditor;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin;
import org.eclipse.wst.wsdl.ui.internal.commands.AddMessageCommand;
import org.eclipse.wst.wsdl.ui.internal.commands.AddXSDElementDeclarationCommand;
import org.eclipse.wst.wsdl.ui.internal.commands.AddXSDTypeDefinitionCommand;
import org.eclipse.wst.wsdl.ui.internal.commands.WSDLElementCommand;
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.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/*
 * TODO: Need to clean up this class.... We probably don't use quite a few of these
 * methods/instance variables.
 */
public class SetNewComponentAction extends AddElementAction
{
  Object input;
  protected IEditorPart editorPart;
  protected String kind;
  private String typeKind = "complex";      // TODO: Refactor code to handle this better

  public SetNewComponentAction(
    String text,
    Node parentNode,
    String prefix,
    String localName,
    Object input)
  {
    super(text, parentNode, prefix, localName);
    this.input = input;
  }

  public void setEditor(IEditorPart editorPart)
  {
    this.editorPart = editorPart; 
  }

  public void setReferenceKind(String kind)
  {
    this.kind = kind;
  }
  
  public void setTypeKind(String typeKind)
  {
      this.typeKind = typeKind;
  }

  // TODO: Clean up next methods below!!!
  private WSDLElementCommand command;
  private String newDialogTitle = WSDLEditorPlugin.getWSDLString("_UI_LABEL_NEW_COMPONENT");
  
  protected void performAddElement()
  {
    Shell shell = Display.getCurrent().getActiveShell();
    String defaultName = getDefaultName();
    NewComponentDialog dialog = new NewComponentDialog(shell, newDialogTitle, defaultName, getUsedNames());

    int dialogCode = dialog.createAndOpen();
    
    if (dialogCode == Window.OK) {
        if (input instanceof Port) {
            Definition definition = ((Port) input).getEnclosingDefinition();
            String newName = dialog.getName();
            
            // TODO: We should be smarter in choosing some default options/settings for generating a new Binding
//            BindingGenerator bindingGenerator = new BindingGenerator(definition);
//            bindingGenerator.setName(newName);
//            bindingGenerator.setProtocol("SOAP");
//            bindingGenerator.generate();
			BindingGenerator bindingGenerator = new BindingGenerator(definition, null, SOAPConstants.SOAP_NAMESPACE_URI);
			bindingGenerator.setName(newName);
			bindingGenerator.generateBinding();
            
          String itemPrefix = definition.getPrefix(definition.getTargetNamespace());
          if (itemPrefix == null)
          {
            itemPrefix = "";
          }
          org.w3c.dom.Element wsdlElement = WSDLEditorUtil.getInstance().getElementForObject((WSDLElement) input);
          wsdlElement.setAttribute("binding", itemPrefix.length() == 0 ? newName : itemPrefix + ":" + newName);     
          
        }
        else if (input instanceof Binding) {            
            Definition definition = ((Binding) input).getEnclosingDefinition();
            Element definitionElement = WSDLEditorUtil.getInstance().getElementForObject(definition);
            
            String newName = dialog.getName();
            String prefix = definitionElement.getPrefix();
            // Use AddMessageAction in WSDLMenuActionContributor
            AddElementAction addPortTypeAction = new AddElementAction("", "icons/message_obj.gif", definitionElement, prefix, "portType"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            addPortTypeAction.setComputeTopLevelRefChild(true);
            addPortTypeAction.run();
            org.w3c.dom.Element newMessage = addPortTypeAction.getNewElement();
            newMessage.setAttribute("name", newName); //$NON-NLS-1$
            // need to get the prefix for the item
            // could get list of updated messages and then select but currently we only have the local name
            String itemPrefix = definition.getPrefix(definition.getTargetNamespace());
            if (itemPrefix == null)
            {
              itemPrefix = ""; //$NON-NLS-1$
            }
            String portTypeValue = itemPrefix.length() == 0 ? newName : itemPrefix + ":" + newName; //$NON-NLS-1$ //$NON-NLS-2$

            // Set the component
            if (input != null && portTypeValue != null) {
                org.w3c.dom.Element wsdlElement = WSDLEditorUtil.getInstance().getElementForObject((WSDLElement) input);
                wsdlElement.setAttribute("type", portTypeValue);
            } 
        }
        else if (input instanceof Input || input instanceof Output || input instanceof Fault) {
            Definition definition = ((MessageReference) input).getEnclosingDefinition();
            String newName = dialog.getName();

            AddMessageCommand action = new AddMessageCommand(definition, newName);
            action.run();
            Message message = (Message) action.getWSDLElement();
            CreateWSDLElementHelper.PART_TYPE_OR_DEFINITION = CreateWSDLElementHelper.getPartInfo(message); 
            CreateWSDLElementHelper.createPart(message);

          // need to get the prefix for the item
          // could get list of updated messages and then select but currently we only have the local name
          String itemPrefix = definition.getPrefix(definition.getTargetNamespace());
          if (itemPrefix == null)
          {
            itemPrefix = ""; //$NON-NLS-1$
          }
          org.w3c.dom.Element wsdlElement = WSDLEditorUtil.getInstance().getElementForObject((WSDLElement) input);
          wsdlElement.setAttribute("message", itemPrefix.length() == 0 ? newName : itemPrefix + ":" + newName); //$NON-NLS-1$ //$NON-NLS-2$
        }
        else if (input instanceof Part) {
            Definition definition = ((Part) input).getEnclosingDefinition();
            String referencingPrefix = definition.getPrefix(definition.getTargetNamespace());
            String newName = dialog.getName();
            
            if (kind.equalsIgnoreCase("type")) {
                if (typeKind.equalsIgnoreCase("complex")) {
                    ((AddXSDTypeDefinitionCommand) command).isComplexType(true);    
                }
                else {
                    ((AddXSDTypeDefinitionCommand) command).isComplexType(false);
                }                
                ((AddXSDTypeDefinitionCommand) command).run(newName);
                ComponentReferenceUtil.setComponentReference((Part) input, true, referencingPrefix.equals("") ? newName : referencingPrefix + ":" + newName);
            }
            else if (kind.equalsIgnoreCase("element")) {
                ((AddXSDElementDeclarationCommand) command).run(newName);
                ComponentReferenceUtil.setComponentReference((Part) input, false, referencingPrefix.equals("") ? newName : referencingPrefix + ":" + newName);
            }
        }
        
        // We shouldn't know about the editor in this class
      WSDLEditor editor = (WSDLEditor) editorPart;
      editor.getSelectionManager().setSelection(new StructuredSelection(input));
    }
  }
  
  private List getUsedNames() {
      if (input instanceof Port) {
          Definition definition = ((Port) input).getEnclosingDefinition();
          return NameUtil.getUsedBindingNames(definition);
      }
      else if (input instanceof Binding) {
          Definition definition = ((Binding) input).getEnclosingDefinition();
          return NameUtil.getUsedPortTypeNames(definition);
      }
      else if (input instanceof Input || input instanceof Output || input instanceof Fault) {
          Definition definition = ((MessageReference) input).getEnclosingDefinition();
          return NameUtil.getUsedMessageNames(definition);
      }
      else if (input instanceof Part) {
          Definition definition = ((Part) input).getEnclosingDefinition();
          if (kind.equalsIgnoreCase("element")) {
              if (command == null) {
                  command = new AddXSDElementDeclarationCommand(definition, "NewElement");
              }
              XSDSchema parentSchema = ((AddXSDElementDeclarationCommand) command).getSchema();
              
              return getUsedElementNames(parentSchema);
          }
          else if (kind.equalsIgnoreCase("type")) {
              if (command == null) {
                  command = new AddXSDTypeDefinitionCommand(definition, "NewType");
              }
              XSDSchema parentSchema = ((AddXSDTypeDefinitionCommand) command).getSchema();
              
              List usedNames;
              if (typeKind.equalsIgnoreCase("complex")) {
                  usedNames = getUsedComplexTypeNames(parentSchema);    
              }
              else {
                  usedNames = getUsedSimpleTypeNames(parentSchema);
              }
              
              return usedNames;
          }
      }
      
      return (new ArrayList());
  }

  private String getDefaultName() {
      if (input instanceof Port) {
          newDialogTitle = WSDLEditorPlugin.getWSDLString("_UI_LABEL_NEW_BINDING");       // TODO: Ugly Hack... remove
          Definition def = ((Port) input).getEnclosingDefinition();
          return NameUtil.getUniqueNameHelper("NewBinding", NameUtil.getUsedBindingNames(def));
      }
      else if (input instanceof Binding) {
          newDialogTitle = WSDLEditorPlugin.getWSDLString("_UI_LABEL_NEW_PORTTYPE");       // TODO: Ugly Hack... remove
          Definition def = ((Binding) input).getEnclosingDefinition();
          return NameUtil.getUniqueNameHelper("NewPortType", NameUtil.getUsedPortTypeNames(def));
      }
      else if (input instanceof Input || input instanceof Output || input instanceof Fault) {
          newDialogTitle = WSDLEditorPlugin.getWSDLString("_UI_LABEL_NEW_MESSAGE");       // TODO: Ugly Hack... remove
          Definition def = ((MessageReference) input).getEnclosingDefinition();
          return NameUtil.getUniqueNameHelper("NewMessage", NameUtil.getUsedMessageNames(def));
      }
      else if (input instanceof Part) {
          Definition def = ((Part) input).getEnclosingDefinition();
          
          if (kind.equalsIgnoreCase("element")) {
              newDialogTitle = WSDLEditorPlugin.getWSDLString("_UI_LABEL_NEW_ELEMENT");      // TODO: Ugly Hack... remove
              if (command == null) {
                  command = new AddXSDElementDeclarationCommand(def, "NewElement");
              }
              XSDSchema parentSchema = ((AddXSDElementDeclarationCommand) command).getSchema();
              
              List usedNames = getUsedElementNames(parentSchema);
              return NameUtil.getUniqueNameHelper("NewElement", usedNames);
          }
          else if (kind.equalsIgnoreCase("type")) {
              if (command == null) {
                  command = new AddXSDTypeDefinitionCommand(def, "NewType");
              }
              XSDSchema parentSchema = ((AddXSDTypeDefinitionCommand) command).getSchema();

              String newItemName = "NewComplexType";
              List usedNames = null;
              if (typeKind.equalsIgnoreCase("complex")) {
                  newDialogTitle = WSDLEditorPlugin.getWSDLString("_UI_LABEL_NEW_COMPLEX_TYPE");       // TODO: Ugly Hack... remove
                  usedNames = getUsedComplexTypeNames(parentSchema);    
              }
              else {
                  newDialogTitle = WSDLEditorPlugin.getWSDLString("_UI_LABEL_NEW_SIMPLE_TYPE");       // TODO: Ugly Hack... remove
                  usedNames = getUsedSimpleTypeNames(parentSchema);
                  newItemName = "NewSimpleType";
              }
              
              return newItemName = NameUtil.getUniqueNameHelper(newItemName, usedNames);
          }
      }
      
      return "NewComponent";
  }
  
  private List getUsedSimpleTypeNames(XSDSchema schema) {
      List namesList = new ArrayList();
      
      Iterator typesIt = schema.getTypeDefinitions().iterator();
      while (typesIt.hasNext()) {
          XSDTypeDefinition type = (XSDTypeDefinition) typesIt.next();
          if (type instanceof XSDSimpleTypeDefinition) {
              namesList.add(type.getName());
          }
      }
      
      return namesList;
  }
  
  private List getUsedComplexTypeNames(XSDSchema schema) {
      List namesList = new ArrayList();
      
      Iterator typesIt = schema.getTypeDefinitions().iterator();
      while (typesIt.hasNext()) {
          XSDTypeDefinition type = (XSDTypeDefinition) typesIt.next();
          if (type instanceof XSDComplexTypeDefinition) {
              namesList.add(type.getName());
          }
      }
      
      return namesList;
  }
  
  private List getUsedElementNames(XSDSchema schema) {
      List namesList = new ArrayList();
      
      Iterator elementsIt = schema.getElementDeclarations().iterator();
      while (elementsIt.hasNext()) {
          XSDElementDeclaration element = (XSDElementDeclaration) elementsIt.next();
          namesList.add(element.getName());
      }
      
      return namesList;
  }
}