/*******************************************************************************
 * Copyright (c) 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.jst.ws.internal.creation.ui.widgets;

import org.eclipse.jst.ws.internal.consumption.ui.widgets.PreferencesSelectionWidget;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.WebServiceClientTypeWidget;
import org.eclipse.jst.ws.internal.consumption.ui.wizard.WebServiceServerRuntimeTypeRegistry;
import org.eclipse.jst.ws.internal.data.LabelsAndIds;
import org.eclipse.jst.ws.internal.data.TypeRuntimeServer;
import org.eclipse.jst.ws.internal.ui.common.UIUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.wst.command.env.core.common.MessageUtils;
import org.eclipse.wst.command.env.core.common.SimpleStatus;
import org.eclipse.wst.command.env.core.common.Status;
import org.eclipse.wst.command.env.core.context.ResourceContext;
import org.eclipse.wst.command.env.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.env.ui.widgets.WidgetDataEvents;


public class ServerWizardWidget extends SimpleWidgetDataContributor
{   
  private WebServiceClientTypeWidget clientWidget_;
  private PreferencesSelectionWidget preferencesWidget_;
  private Listener                   statusListener_;
  private TypeRuntimeServer          ids_;
  private LabelsAndIds               labelIds_;
  private boolean                    displayPreferences_;
  
  /*CONTEXT_ID PWPR0001 for the Project Page*/
  private String INFOPOP_PWPR_PAGE = "PWPR0001";
  
  /*CONTEXT_ID PWPR0005 for the Generate Proxy check box of the Project Page*/
  private String INFOPOP_PWPR_CHECKBOX_GENERATE_PROXY = "PWPR0005";
  private Button  generateProxy_;
  
  /*CONTEXT_ID PWPR0010 for the Web Service Type combo box of the Project Page*/
  private String INFOPOP_PWPR_COMBO_TYPE = "PWPR0010";
  private Combo  webserviceType_;
  
  /*CONTEXT_ID PWPR0011 for the Wizard Scenario Service group of the Project Page*/
  private String INFOPOP_PWPR_GROUP_SCENARIO_SERVICE = "PWPR0011";
  private Button startService_;
  
  /*CONTEXT_ID PWPR0009 for the Start Web Project check box check box of the Project Page*/
  private String INFOPOP_PWPR_CHECKBOX_START_WEB_PROJECT = "PWPR0009";
  
  /*CONTEXT_ID PWPR0013 for the test service checkbox of the project page*/  
  private String INFOPOP_PWPR_CHECKBOX_TEST_SERVICE = "PWPR0013";
  private Button testService_;
  
  /*CONTEXT_ID PWPR0014 for the monitor service checkbox of the projec page*/
  private String INFOPOP_PWPR_CHECKBOX_MONITOR_SERVICE = "PWPR0014";
  private Button monitorService;
  
  /*CONTEXT_ID PWPR0012 for the Launch UDDI check box of the Project Page*/
  private String INFOPOP_PWPR_CHECKBOX_LAUNCH_WS = "PWPR0012";
  private Button launchUddi_;
  
  public ServerWizardWidget( boolean displayPreferences )
  {
    displayPreferences_ = displayPreferences;  
  }
  
  public WidgetDataEvents addControls( Composite parent, Listener statusListener)
  {
    String       pluginId = "org.eclipse.jst.ws.consumption.ui";
    String       createPluginId = "org.eclipse.jst.ws.creation.ui";
    MessageUtils msgUtils = new MessageUtils( pluginId + ".plugin", this );
    UIUtils      utils    = new UIUtils( msgUtils, createPluginId );
    
    statusListener_ = statusListener;
    
  	WorkbenchHelp.setHelp( parent, pluginId + "." +  INFOPOP_PWPR_PAGE );
  	
  	Composite serverComposite = utils.createComposite( parent, 1 );
  	
  	Group serviceGroup = utils.createGroup( serverComposite, "GROUP_SCENARIO_SERVICE",
  	                                        "TOOLTIP_PWPR_GROUP_SCENARIO_SERVICE", 
  	                                        INFOPOP_PWPR_GROUP_SCENARIO_SERVICE,
											2, 10, 10);
  	
  	
  	// Create webservice combo box.
    webserviceType_ = utils.createCombo( serviceGroup, "LABEL_WEBSERVICETYPE",
                                         "TOOLTIP_PWPR_COMBO_TYPE",
                                         INFOPOP_PWPR_COMBO_TYPE, 
										 SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY );
    webserviceType_.addListener( SWT.Modify, statusListener );
    
    Composite buttonsGroup = utils.createComposite( serviceGroup, 1 );
    GridData  buttonGrid   = new GridData();
    buttonGrid.horizontalSpan = 2;
    buttonsGroup.setLayoutData( buttonGrid );
    
    // Create start service check box.
    startService_ = utils.createCheckbox( buttonsGroup, "BUTTON_START_WEB_PROJECT",
                                          "TOOLTIP_PWPR_CHECKBOX_START_WEB_PROJECT",
                                          INFOPOP_PWPR_CHECKBOX_START_WEB_PROJECT );
    startService_.addSelectionListener( new SelectionAdapter()
                                        {
                                          public void widgetSelected( SelectionEvent evt )
                                          {
                                            handleStartPressed();
                                          }
                                        });
    
    launchUddi_ = utils.createCheckbox( buttonsGroup, "BUTTON_WS_PUBLISH",
                                        "TOOLTIP_PWPR_CHECKBOX_LAUNCH_WS",
                                        INFOPOP_PWPR_CHECKBOX_LAUNCH_WS );
    
    Composite proxyComposite = utils.createComposite( serverComposite, 1, 5, 0 );
    
    // Create generate proxy check box.
    generateProxy_ = utils.createCheckbox( proxyComposite, "BUTTON_GENERATE_PROXY",
                                           "TOOLTIP_PWPR_CHECKBOX_GENERATE_PROXY",
                                           INFOPOP_PWPR_CHECKBOX_GENERATE_PROXY );
    generateProxy_.addSelectionListener( new SelectionAdapter()
                                         {
                                           public void widgetSelected( SelectionEvent evt )
                                           {
                                             clientWidget_.enableWidget( generateProxy_.getSelection() );
                                           }
                                         });
    
    // Create client selection widget.
    clientWidget_ = new WebServiceClientTypeWidget();
    clientWidget_.addControls( serverComposite, statusListener );
    
    Composite testGroup = utils.createComposite(serverComposite,1);
    
    //  Create test service check box.
    testService_ = utils.createCheckbox( testGroup, "CHECKBOX_TEST_WEBSERVICE",
                                         "TOOLTIP_PWPR_CHECKBOX_TEST_SERVICE",
                                         INFOPOP_PWPR_CHECKBOX_TEST_SERVICE );

    monitorService = utils.createCheckbox( testGroup, "CHECKBOX_MONITOR_WEBSERVICE",
                                         "TOOLTIP_PWPR_CHECKBOX_MONITOR_SERVICE",
                                         INFOPOP_PWPR_CHECKBOX_MONITOR_SERVICE );
    
    if( displayPreferences_ )
    {
      // Create the preferences widgets.
      preferencesWidget_ = new PreferencesSelectionWidget();
      preferencesWidget_.addControls( serverComposite, statusListener );
    }
    
    return this;
  }

  private void handleStartPressed()
  {
    boolean enabled = startService_.getSelection();
    
    testService_.setEnabled( enabled );
    monitorService.setEnabled(enabled);
    launchUddi_.setEnabled( enabled );
    generateProxy_.setEnabled( enabled );
    clientWidget_.enableWidget( getGenerateProxy().booleanValue() );
  }
  
  public void setClientTypeRuntimeServer( TypeRuntimeServer ids )
  {
    clientWidget_.setTypeRuntimeServer( ids );
  }
  
  public TypeRuntimeServer getClientTypeRuntimeServer()
  {
    return clientWidget_.getTypeRuntimeServer();  
  }
  
  public void setServiceTypeRuntimeServer( TypeRuntimeServer ids )
  {
    WebServiceServerRuntimeTypeRegistry registry   = WebServiceServerRuntimeTypeRegistry.getInstance();
    LabelsAndIds                        labelIds   = registry.getServiceTypeLabels();
    int                                 selection  = 0;
    String[]                            serviceIds = labelIds.getIds_();
    String                              selectedId = ids.getTypeId();
    
    webserviceType_.removeListener( SWT.Modify, statusListener_ );
    webserviceType_.setItems( labelIds.getLabels_() );
        
    // Now find the selected one.
    for( int index = 0; index < serviceIds.length; index++ )
    {
      if( selectedId.equals( serviceIds[index ]) )
      {
        selection = index;
        break;
      }
    }
    
    webserviceType_.select( selection );
    webserviceType_.addListener( SWT.Modify, statusListener_ );
    ids_      = ids;  
    labelIds_ = labelIds;
  }
  
  public TypeRuntimeServer getServiceTypeRuntimeServer()
  {
    int selectionIndex = webserviceType_.getSelectionIndex();
    
    ids_.setTypeId( labelIds_.getIds_()[selectionIndex] );
    
    return ids_;  
  }
  
  public Boolean getStartService()
  {
    return new Boolean( startService_.getSelection() );  
  }
  
  public void setStartService( Boolean value )
  {
    startService_.setSelection( value.booleanValue() );
  }

  public Boolean getTestService()
  {
    return new Boolean( testService_.getSelection() && startService_.getSelection() );
  }
  
  public void setTestService( Boolean value )
  {
    testService_.setSelection( value.booleanValue() );  
  }
  
  public Boolean getMonitorService()
  {
    return new Boolean(monitorService.getSelection() && startService_.getSelection());
  }
  
  public void setMonitorService(Boolean value)
  {
    monitorService.setSelection(value.booleanValue());
  }

  public Boolean getPublishService()
  {
    return new Boolean( launchUddi_.getSelection() && startService_.getSelection() );
  }
  
  public void setPublishService( Boolean value )
  {
    launchUddi_.setSelection( value.booleanValue() );  
  }

  public Boolean getGenerateProxy()
  {
    return new Boolean( generateProxy_.getSelection() && startService_.getSelection() );
  }
  
  public void setGenerateProxy( Boolean value )
  {
    generateProxy_.setSelection( value.booleanValue() );  
  }

  public ResourceContext getResourceContext()
  {
    return preferencesWidget_.getResourceContext(); 
  }

  public void setResourceContext( ResourceContext context )
  {
    preferencesWidget_.setResourceContext( context );
  }

  public void internalize()
  {
    handleStartPressed();  
  }
  
  public Status getStatus()
  {
    Status status = new SimpleStatus( "" );
    
    // If the webservice has not been selected then user can not move
    // forward to the next page.
    if( webserviceType_.getText().equals("") )
    {
      status = new SimpleStatus( "", "", Status.ERROR );
    }
    
    return status;
  }
}
