/*******************************************************************************
 * Copyright (c) 2001, 2010 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.wizards;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.dialogs.WizardNewFileCreationPage;
import org.eclipse.ui.part.PageBook;
import org.eclipse.wst.ws.service.policy.IServicePolicy;
import org.eclipse.wst.wsdl.internal.generator.BindingGenerator;
import org.eclipse.wst.wsdl.ui.internal.Messages;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin;
import org.eclipse.wst.wsdl.ui.internal.asd.ASDEditorCSHelpIds;
import org.eclipse.wst.wsdl.ui.internal.asd.contentgenerator.ui.extension.ContentGeneratorUIExtension;
import org.eclipse.wst.wsdl.ui.internal.asd.contentgenerator.ui.extension.ContentGeneratorUIExtensionRegistry;
import org.eclipse.wst.wsdl.ui.internal.contentgenerator.ui.BaseContentGeneratorOptionsPage;
import org.eclipse.wst.wsdl.ui.internal.contentgenerator.ui.ISoapStyleInfo;
import org.eclipse.wst.wsdl.ui.internal.util.ServicePolicyHelper;
import org.eclipse.wst.wsdl.ui.internal.util.ValidateHelper;
import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
import org.eclipse.wst.xml.ui.internal.dialogs.UpdateListener;

public class WSDLNewFileOptionsPage extends WizardPage implements ModifyListener, UpdateListener, SelectionListener
{
  protected WizardNewFileCreationPage newFileCreationPage;
  protected Text targetNamespaceText;
  protected Text prefixText;
  protected boolean updatePortOpFieldBoolean = true;
  
  protected PageBook protocolPageBook;
  protected Combo protocolCombo;
  protected Link WSIPreferenceLink;
  
  private BindingGenerator generator;
  private Map pageMap = new HashMap();
  private IServicePolicy activeServicePolicy;

  /**
   * Constructor for WSDLNewFileOptionsPage.
   * @param pageName
   */
  public WSDLNewFileOptionsPage(String pageName)
  {
    super(pageName);
  }
  
  public void setBindingGenerator(BindingGenerator generator) {
	  this.generator = generator;
  }
  
  /**
   * Constructor for WSDLNewFileOptionsPage.
   * @param pageName
   * @param title
   * @param titleImage
   */
  public WSDLNewFileOptionsPage(String pageName, String title, ImageDescriptor titleImage)
  {
    super(pageName, title, titleImage);
    setDescription(Messages._UI_DESCRIPTION_NEW_WSDL_FILE);
  }

  public WSDLNewFileOptionsPage(String pageName, String title, ImageDescriptor titleImage, WizardNewFileCreationPage newFilePage)
  {
    super(pageName, title, titleImage);
    setDescription(Messages._UI_DESCRIPTION_NEW_WSDL_FILE);
    newFileCreationPage = newFilePage;
  }

  /**
   * @see org.eclipse.jface.dialogs.IDialogPage#createControl(Composite)
   */
  public void createControl(Composite parent)
  {
    Composite base = new Composite(parent, SWT.NONE);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(base, Messages._UI_HELP); //$NON-NLS-1$
    base.setLayout(new GridLayout());

    //  Group wsdlGroup = ViewUtility.createGroup(base, 2, "WSDL", false);
    Composite wsdlGroup = new Composite(base, SWT.NONE);
    GridLayout layout = new GridLayout();
    layout.numColumns = 2;
    wsdlGroup.setLayout(layout);

    GridData data = new GridData();
    data.verticalAlignment = GridData.FILL;
    data.horizontalAlignment = GridData.FILL;
    wsdlGroup.setLayoutData(data);
    
    GridData gd = (GridData)wsdlGroup.getLayoutData();
    gd.grabExcessHorizontalSpace = true;

    Label targetNamespace = new Label(wsdlGroup, SWT.LEFT);
    targetNamespace.setText(Messages._UI_LABEL_TARGET_NAMESPACE);
    GridData nsData = new GridData();
    nsData.horizontalAlignment = GridData.FILL;
    targetNamespace.setLayoutData(nsData);
    
    targetNamespaceText = new Text(wsdlGroup, SWT.SINGLE | SWT.BORDER);
    GridData textData = new GridData();
    textData.horizontalAlignment = GridData.FILL;
    textData.grabExcessHorizontalSpace = true;
    textData.widthHint = 10;
    targetNamespaceText.setLayoutData(textData);
    
    targetNamespaceText.addModifyListener(this);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(targetNamespaceText, ASDEditorCSHelpIds.WSDL_WIZARD_OPTIONS_PAGE_TNS_TEXT);

    Label prefix = new Label(wsdlGroup, SWT.LEFT);
    prefix.setText(Messages._UI_LABEL_PREFIX_WITH_COLON);

    GridData prefixData = new GridData();
    prefixData.horizontalAlignment = GridData.FILL;
    prefix.setLayoutData(prefixData);
    
    prefixText = new Text(wsdlGroup, SWT.SINGLE | SWT.BORDER);
    GridData prefixTextData = new GridData();
    prefixTextData.horizontalAlignment = GridData.FILL;
    prefixTextData.grabExcessHorizontalSpace = true;
    prefixTextData.widthHint = 10;
    prefixText.setLayoutData(prefixTextData);

    prefixText.addModifyListener(this);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(prefixText, ASDEditorCSHelpIds.WSDL_WIZARD_OPTIONS_PAGE_PREFIX_TEXT);
    
    //    XMLCatalog xmlCatalog = XMLCatalogRegistry.getInstance().lookupOrCreateXMLCatalog("default");
    //    SelectXMLCatalogIdPanel catalog = new SelectXMLCatalogIdPanel(base, xmlCatalog);

//  Determine if the user wishes to create a skeleton WSDL.  If yes, present the user with input fields.
    createSkeletonCheckBox = new Button(base, SWT.CHECK);
    createSkeletonCheckBox.setText(Messages._UI_LABEL_CREATE_WSDL_SKELETON);
    createSkeletonCheckBox.setSelection(true);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(createSkeletonCheckBox, ASDEditorCSHelpIds.WSDL_WIZARD_OPTIONS_PAGE_CREATE_SKELETON_CHECKBOX);
    
    wsdlSkeletonGroup = new Composite(base, SWT.NONE);
    GridLayout layout2 = new GridLayout();
    layout2.numColumns = 2;
    wsdlSkeletonGroup.setLayout(layout2);

    GridData data2 = new GridData();
    data2.verticalAlignment = GridData.FILL;
    data2.horizontalAlignment = GridData.FILL;
    wsdlSkeletonGroup.setLayoutData(data2);

   createLabel(wsdlSkeletonGroup, Messages._UI_LABEL_BINDING_PROTOCOL);
   protocolCombo = new Combo(wsdlSkeletonGroup, SWT.READ_ONLY);
   GridData dataC = new GridData();
   dataC.horizontalAlignment = GridData.FILL;
   dataC.grabExcessHorizontalSpace = true;
   protocolCombo.setLayoutData(dataC);

    IProject project = getProject();
    activeServicePolicy = ServicePolicyHelper.getActivePolicyWithProtocol(project);
    String defaultProtocolNS = ServicePolicyHelper.getDefaultBinding(project, activeServicePolicy);
    String defaultProtocolLabel = null;
    ContentGeneratorUIExtensionRegistry registry = WSDLEditorPlugin.getInstance().getContentGeneratorUIExtensionRegistry();
    ContentGeneratorUIExtension extension = registry.getExtensionForNamespace(defaultProtocolNS);
    if (extension != null)
      defaultProtocolLabel = extension.getLabel();

    Iterator it = registry.getBindingExtensionNames().iterator();
    int defaultIndex = 0;
    boolean defaultFound = false;
    while (it.hasNext()) {
      String protocolName = (String) it.next();
      String protocolLabel = null;
      ContentGeneratorUIExtension ext = registry.getExtensionForName(protocolName);
      if (ext != null) {
        String label = ext.getLabel();
        if (label != null) {
          protocolLabel = label;
          protocolCombo.add(protocolLabel);
        }
      }

      if (!defaultFound && protocolLabel != null)
      {
        defaultFound = protocolLabel.equals(defaultProtocolLabel);
        if (!defaultFound) {
          ++defaultIndex;
        }
      }
    }
    if (!defaultFound) {    	
      defaultIndex = 0;
    }

    protocolCombo.addModifyListener(this);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(protocolCombo, ASDEditorCSHelpIds.WSDL_WIZARD_OPTIONS_PAGE_PROTOCOL_COMBO);

    // Create PageBook and pages/controls for the PageBook
    protocolPageBook = new PageBook(base, SWT.NONE);
    GridData gdFill = new GridData();
    gdFill.horizontalAlignment = GridData.FILL;
    gdFill.grabExcessHorizontalSpace = true;
    gdFill.verticalAlignment = GridData.FILL;
    gdFill.grabExcessVerticalSpace = true;
    protocolPageBook.setLayoutData(gdFill);

    if (protocolCombo.getItemCount() > 0) {
      String protocol = protocolCombo.getItem(defaultIndex);
      ContentGeneratorUIExtension ext = registry.getExtensionForLabel(protocol);
      ContentGeneratorOptionsPage page = ext.getBindingContentGeneratorOptionsPage();
      page.init(generator);

      protocolPageBook.showPage(page.getControl());
      protocolPageBook.setVisible(true);
      protocolCombo.select(defaultIndex);
      updatePageBook(protocol);
    }

    wsdlSkeletonGroup.setVisible(true);

    WSIPreferenceLink = new Link(base, SWT.NONE);
    WSIPreferenceLink.setText("<A>" + Messages._WSI_COMPLIANCE_LINK_TEXT + "</A>"); //$NON-NLS-1$ //$NON-NLS-2$
    WSIPreferenceLink.addSelectionListener(new SelectionAdapter()
    {
      public void widgetSelected(SelectionEvent e)
      {
        getNewWSDLWizard().openProjectWSIProperties();
        IProject project = getProject();
        activeServicePolicy = ServicePolicyHelper.getActivePolicyWithProtocol(project);
        setPageComplete(validatePage());
      }
    });

    WSIPreferenceLink.setLayoutData(new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_END));

    // Modify default values setting link
	Link preferencesLink = new Link(base, SWT.NONE);
	preferencesLink.setText("<a>" + Messages._UI_LINK_TEXT_MODIFY_DEFAULT_VALUES_SETTING  + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$
	preferencesLink.addSelectionListener(new SelectionAdapter(){
		public void widgetSelected(SelectionEvent selectionEvent) {
			PreferenceDialog preferenceDialog = PreferencesUtil.createPreferenceDialogOn(getShell(), WSDLEditorPlugin.WSDL_PREFERENCE_PAGE, new String[]{WSDLEditorPlugin.WSDL_PREFERENCE_PAGE}, null);
			if (preferenceDialog != null)
				preferenceDialog.open();
		}
	});
    
    createSkeletonCheckBox.addSelectionListener(this);

    PlatformUI.getWorkbench().getHelpSystem().setHelp(base, ASDEditorCSHelpIds.WSDL_WIZARD_OPTIONS_PAGE);

    base.layout();
    setControl(base);

  }

  private NewWSDLWizard getNewWSDLWizard()
  {
    return (NewWSDLWizard)getWizard();
  }

  private String computeDefaultDefinitionName()
  {
    String name = "DefaultName"; //$NON-NLS-1$
    IPath path = getNewWSDLWizard().getNewFilePath();
    if (path != null)
    {
      name = path.removeFileExtension().lastSegment().toString();
    }
    return name;
  }

  private String computeDefaultNamespaceName()
  {
    String namespace = WSDLEditorPlugin.getInstance().getPreferenceStore().getString(WSDLEditorPlugin.DEFAULT_TARGET_NAMESPACE_ID);
    if (!namespace.endsWith("/")) { //$NON-NLS-1$
    	namespace = namespace.concat("/"); //$NON-NLS-1$
    }
    
    IPath path = getNewWSDLWizard().getNewFilePath();
    if (path != null)
    {
      namespace += path.removeFileExtension().toString() + "/"; //$NON-NLS-1$
    }
    return namespace;
  }
  
  private String computeDefaultPrefix() 
  {
	  return WSDLEditorPlugin.getInstance().getPreferenceStore().getString(WSDLEditorPlugin.DEFAULT_TARGET_NAMESPACE_PREFIX_PREFERENCE_ID);
  }

  public void setVisible(boolean visible)
  {
    super.setVisible(visible);

    if (visible)
    {
      // prime the fields    
      targetNamespaceText.setText(computeDefaultNamespaceName());
      prefixText.setText(computeDefaultPrefix()); 
    }
  }

  public String getTargetNamespace()
  {
    return targetNamespaceText.getText();
  }

  public String getPrefix()
  {
    return prefixText.getText().trim();
  }

  public String getDefinitionName()
  {
  	return computeDefaultDefinitionName();
  }

  public void modifyText(ModifyEvent e)
  {
    if (e.widget == targetNamespaceText)
    {
      startDelayedEvent(e);
    }
    else if (e.widget == prefixText)
    {
      setPageComplete(validatePage());
    }
    else if (e.widget == protocolCombo)
    {
      String protocol = protocolCombo.getText();

      ContentGeneratorUIExtension ext = WSDLEditorPlugin.getInstance().getContentGeneratorUIExtensionRegistry().getExtensionForLabel(protocol);
      generator.setContentGenerator(BindingGenerator.getContentGenerator(ext.getNamespace()));
      updatePageBook(protocol);
      setPageComplete(validatePage());
    }
  }

  protected void updatePageBook(String protocol)
  {
    if (protocol != null)
    {
	  ContentGeneratorOptionsPage page = (ContentGeneratorOptionsPage) pageMap.get(protocol);
      if (page == null)
      {
        page = createContentGeneratorOptionsPage(protocol);

        if (page != null)
        {
          page.init(generator);
          page.createControl(protocolPageBook);
          pageMap.put(protocol, page);
          
          if (page instanceof BaseContentGeneratorOptionsPage) {
        	  // We should put the setWizardPage() method into the ContentGeneratorOptionsPage Interface
        	  ((BaseContentGeneratorOptionsPage) page).setWizardPage(this);
          }
          
        }
      }

      if (page != null)
      {
    	  protocolPageBook.showPage(page.getControl());
    	  protocolPageBook.layout();
    	  protocolPageBook.getParent().layout();
    	  
    	  // resize the wizard dialog if necessary for the updated page
    	  Point size = protocolPageBook.getShell().getSize();
    	  Point minSize = protocolPageBook.getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
    	  int newX = Math.max(size.x, minSize.x);
    	  int newY = Math.max(size.y, minSize.y);
    	  protocolPageBook.getShell().setSize(newX, newY);
    	  
    	  page.setOptionsOnGenerator();
      }
    }
  }

  public ContentGeneratorOptionsPage createContentGeneratorOptionsPage(String protocol)
  {
    ContentGeneratorOptionsPage optionsPage = null;
    ContentGeneratorUIExtension extension = WSDLEditorPlugin.getInstance().getContentGeneratorUIExtensionRegistry().getExtensionForLabel(protocol);
    if (extension != null) {
  	  optionsPage = extension.getBindingContentGeneratorOptionsPage();
    }
    return optionsPage;
  }

  public void updateOccured(Object arg1, Object arg2)
  {
    setPageComplete(validatePage());
  }

  public boolean validatePage()
  {
    boolean ready = true;

    setErrorMessage(null);
    setMessage(null);

    // this.setMessage(Messages.getString("_UI_DESCRIPTION_NEW_WSDL_FILE"),this.NONE);
    // //$NON-NLS-1$

    // so that the page doesn't immediately show up with an error
    if (targetNamespaceText.getText().trim().equals("")) //$NON-NLS-1$
    {
      if (ready)
      {
        setErrorMessage(null);
      }
      return false;
    }

    if (!validateTargetNamespace(targetNamespaceText.getText()))
    {
      ready = false;
    }

    if (createSkeletonCheckBox.getSelection())
    {
      if (!displayDialogMessages())
      {
        ready = false;
      }
    }
    else
    {
      this.setMessage(Messages._UI_DESCRIPTION_NEW_WSDL_FILE, NONE);
    }

    return ready;
  }

  protected boolean displayDialogMessages()
  {
    String protocol = getProtocol();
    if (!(pageMap.get(protocol) instanceof ContentGeneratorOptionsPage))
    {
      return false;
    }

    if (!validateProtocol(protocol))
    {
      if (getMessageType() == IMessageProvider.ERROR)
        return false;
      else
        return true;
    }

    ContentGeneratorOptionsPage optionsPage = (ContentGeneratorOptionsPage) pageMap.get(protocol);
    IFile targetFile = ResourcesPlugin.getWorkspace().getRoot().getFile(newFileCreationPage.getContainerFullPath().append(newFileCreationPage.getFileName()));

    if (optionsPage instanceof BaseContentGeneratorOptionsPage)
    {
      ((BaseContentGeneratorOptionsPage) optionsPage).setTargetIFile(targetFile);

      String message = ((IMessageProvider) optionsPage).getMessage();
      int messageType = ((IMessageProvider) optionsPage).getMessageType();

      if (messageType == IMessageProvider.NONE)
      {
        setMessage(Messages._UI_DESCRIPTION_NEW_WSDL_FILE, NONE);
      }
      else
      {
        setMessage(message, messageType);
      }

      if (messageType == IMessageProvider.ERROR)
      {
        return false;
      }
    }

    return true;
  }

  protected boolean validatePrefix(String prefix)
  {
    String errorMessage = ValidateHelper.checkXMLPrefix(prefix);

    if (errorMessage == null || errorMessage.length() == 0)
    {
      return true;
    }
    return false;
  }

  /**
   * Validates protocol by checking if there is an active wsi policy requires or
   * suggests a default protocol and that protocol is not the same as the
   * currently selected protocol
   * 
   * @param protocol
   * @return
   */
  private boolean validateProtocol(String protocol)
  {
    ContentGeneratorUIExtensionRegistry registry = WSDLEditorPlugin.getInstance().getContentGeneratorUIExtensionRegistry();
    ContentGeneratorUIExtension extension = registry.getExtensionForLabel(protocol);
    if (extension != null)
    {
      String namespace = extension.getNamespace();
      if (namespace != null)
      {
        IProject project = getProject();
        if (activeServicePolicy != null)
        {
          // get default binding and compare if same or not
          String defaultBinding = ServicePolicyHelper.getDefaultBinding(project, activeServicePolicy);
          if (!defaultBinding.equals(namespace))
          {
            int messageType = ServicePolicyHelper.getMessageSeverity(project, activeServicePolicy);
            if (messageType == IMessageProvider.ERROR)
            {
              // if not same, set error message
              // put up an error message
              ContentGeneratorUIExtension ext = registry.getExtensionForNamespace(defaultBinding);
              if (ext != null)
              {
                String n = ext.getLabel();
                setMessage(NLS.bind(Messages._ERROR_WSI_COMPLIANCE_PROTOCOL, new String[] { n }), IMessageProvider.ERROR);
              }
              return false;
            }
            else if (messageType == IMessageProvider.WARNING)
            {
              // put up a warning message
              ContentGeneratorUIExtension ext = registry.getExtensionForNamespace(defaultBinding);
              if (ext != null)
              {
                String n = ext.getLabel();
                setMessage(NLS.bind(Messages._WARN_WSI_COMPLIANCE_PROTOCOL, new String[] { n }), IMessageProvider.WARNING);
              }
              return false;
            }
          }
        }
      }
    }
    return true;
  }

  protected boolean validateXMLName(String xmlName)
  {
    String errorMessage = ValidateHelper.checkXMLName(xmlName);

    if (errorMessage == null || errorMessage.length() == 0)
    {
      return true;
    }
    setErrorMessage(errorMessage);
    return false;
  }

  protected boolean validateTargetNamespace(String ns)
  {
    boolean test = true;
    try
    {
    	new URI(ns);
//      URI testURI = new URI(ns);
      //      if (!testURI.isGenericURI())
      //      {
      //        setErrorMessage(WSDLEditorPlugin.getInstance().getWSDLString("_UI_ERROR_NAMESPACE_INVALID")); //$NON-NLS-1$
      //        test = false;
      //      }
    }
    catch (URISyntaxException e)
    {
      //			String errorMessage = ValidateHelper.checkXMLName(ns);
      //			if (errorMessage == null || errorMessage.length() == 0)
      //			{
      //				test = true;
      //			}
      //			else
      //			{
      setErrorMessage(Messages._UI_ERROR_NAMESPACE_INVALID); //$NON-NLS-1$
      test = false;
      //			}
    }

    return test;
  }

  /*
   * private boolean arePrefixesUniqueAndValid() { java.util.List infoList =
   * namespaceInfo.getNamespaceInfoList(); java.util.List checkedList =
   * namespaceInfo.getNamespaceCheckedList();
   * 
   * Vector prefixList = new Vector(); boolean test = true; boolean isOneBlank =
   * false;
   * 
   * String currentPrefix = prefixText.getText().trim(); if
   * (currentPrefix.length() == 0) { isOneBlank = true; } else { if
   * (validatePrefix(currentPrefix)) { prefixList.add(currentPrefix); } else {
   * setErrorMessage(WSDLEditorPlugin.getWSDLString("_UI_ERROR_PREFIX_IS_INVALID",
   * currentPrefix)); //$NON-NLS-1$ return false; } }
   * 
   * for (int i = 0; i < infoList.size(); i++) { NamespaceInfo info =
   * (NamespaceInfo)infoList.get(i); if
   * (((String)checkedList.get(i)).equals("true")) //$NON-NLS-1$ { String
   * aPrefix = info.prefix.trim(); if (aPrefix.length() > 0) { if
   * (!prefixList.contains(aPrefix)) { if (validatePrefix(aPrefix)) {
   * prefixList.add(aPrefix); } else {
   * setErrorMessage(WSDLEditorPlugin.getWSDLString("_UI_ERROR_PREFIX_IS_INVALID",
   * info.prefix)); //$NON-NLS-1$ test = false; break; } } else {
   * setErrorMessage(WSDLEditorPlugin.getWSDLString("_UI_ERROR_PREFIX_IS_A_DUPLICATE",
   * info.prefix)); //$NON-NLS-1$ test = false; break; } } else { if
   * (!isOneBlank) { isOneBlank = true; } else {
   * setErrorMessage(WSDLEditorPlugin.getWSDLString("_UI_ERROR_MORE_THAN_ONE_PREFIX_IS_BLANK"));
   * //$NON-NLS-1$ test = false; break; } } } } return test; }
   */

  protected DelayedEvent delayedTask;

  protected void startDelayedEvent(ModifyEvent e)
  {
    if (delayedTask == null || delayedTask.getEvent() == null)
    {
      delayedTask = new DelayedEvent();
      delayedTask.setEvent(e);
      Display.getDefault().timerExec(500, delayedTask);
    }
    else
    {
      ModifyEvent delayedEvent = delayedTask.getEvent();

      if (e.widget == delayedEvent.widget)
      {
        // same event, just different data, delay new event
        delayedTask.setEvent(null);
      }
      delayedTask = new DelayedEvent();
      delayedTask.setEvent(e);
      Display.getDefault().timerExec(500, delayedTask);
    }
  }

  class DelayedEvent implements Runnable
  {
    protected ModifyEvent event;

    /*
     * @see Runnable#run()
     */
    public void run()
    {
      if (event != null)
      {
        setPageComplete(validatePage());
        event = null;
      }
    }

    public ModifyEvent getEvent()
    {
      return event;
    }

    public void setEvent(ModifyEvent event)
    {
      this.event = event;
    }
  }

  public void widgetDefaultSelected(SelectionEvent e) {
  }

  public void widgetSelected(SelectionEvent e) {
	  if (e.widget == createSkeletonCheckBox) {
  	 	if (createSkeletonCheckBox.getSelection()) {
  	 		wsdlSkeletonGroup.setVisible(true);
  	 		protocolPageBook.setVisible(true);
  	 	}
  	 	else {
  	 		wsdlSkeletonGroup.setVisible(false);
  	 		protocolPageBook.setVisible(false);
  	 	}
  	 	setPageComplete(validatePage());
  	 }
  }

  Composite wsdlSkeletonGroup;

  Button createSkeletonCheckBox;

  private Label createLabel(Composite comp, String labelString) {
    Label label = new Label(comp, SWT.LEFT);
    label.setText(labelString);
    GridData nsData = new GridData();
    nsData.horizontalAlignment = GridData.FILL;
    label.setLayoutData(nsData);
    
    return label;
  }

  public Vector getNamespaceInfo() {
		Vector namespaces = new Vector();
  		
  		// Add Default Namespaces
		NamespaceInfo info1 = new NamespaceInfo();
		info1.prefix = "wsdl"; //$NON-NLS-1$
		info1.uri = "http://schemas.xmlsoap.org/wsdl/"; //$NON-NLS-1$
		namespaces.addElement(info1);
		
		NamespaceInfo info8 = new NamespaceInfo();
		info8.prefix = "xsd"; //$NON-NLS-1$
		info8.uri = "http://www.w3.org/2001/XMLSchema"; //$NON-NLS-1$
		namespaces.addElement(info8);

		return namespaces;
  }

  public boolean getCreateSkeletonBoolean() {
  	return createSkeletonCheckBox.getSelection();
  }

  public String getProtocol() {
  	return protocolCombo.getText();
  }

  public boolean isSoapDocLiteralProtocol() {
	  // We need to revisit this....  Can we make this code more generic...
	  // Wee need this method because the NewWSDLWizard needs to know if it should create the new
	  // WSDL with a doc-literal pattern (A WSDL Part referencing an XSD Element)
	  ContentGeneratorOptionsPage optionsPage = (ContentGeneratorOptionsPage) pageMap.get(getProtocol());
	  if (optionsPage instanceof ISoapStyleInfo) {
		  return ((ISoapStyleInfo) optionsPage).isDocumentLiteralPattern();
	  }

	  return false;
  }

  /**
   * Returns the project the current containing project
   * 
   * @return IProject object. If path is <code>null</code> the return value is
   *         also <code>null</code>.
   */
  public IProject getProject()
  {
    IPath path = newFileCreationPage.getContainerFullPath();
    IWorkspace workspace = ResourcesPlugin.getWorkspace();
    IProject project = null;

    if (path != null)
    {
      if (workspace.validatePath(path.toString(), IResource.PROJECT).isOK())
      {
        project = workspace.getRoot().getProject(path.toString());
      }
      else
      {
        project = workspace.getRoot().getFile(path).getProject();
      }
    }

    return project;
  }

  public IServicePolicy getServicePolicy()
  {
    return activeServicePolicy;
  }
}