/*******************************************************************************
 * Copyright (c) 2000, 2006 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
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060310   131352 pmoogk@ca.ibm.com - Peter Moogk
 *******************************************************************************/
package org.eclipse.wst.ws.internal.ui.wsi.preferences;

import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.help.IWorkbenchHelpSystem;
import org.eclipse.wst.ws.internal.plugin.WSPlugin;
import org.eclipse.wst.ws.internal.preferences.PersistentWSDLValidationContext;
import org.eclipse.wst.ws.internal.preferences.PersistentWSIContext;
import org.eclipse.wst.ws.internal.ui.WstWSUIPluginMessages;
import org.eclipse.wst.ws.internal.ui.plugin.WSUIPlugin;



public class WSICompliancePreferencePage extends PreferencePage implements IWorkbenchPreferencePage, SelectionListener, Listener

{
	  
  /*CONTEXT_ID PWSI0001 for the WS-I Preference Page*/
  private String INFOPOP_PWSI_PAGE = WSUIPlugin.ID + ".PWSI0000";
  //

  private Label wsi_ssbp_Label_;
  private Combo wsi_ssbp_Types_;
  
  /*CONTEXT_ID PWSI0004 for the WS-I SSBP type combo box on the Profile Compliance and Validation page*/
  private String INFOPOP_PWSI_SSBP_COMBO_TYPE = WSUIPlugin.ID + ".PWSI0004";
  /*CONTEXT_ID PWSI0008 for the WS-I AP type combo box on the Profile Compliance and Validation page*/
  private String INFOPOP_PWSI_AP_COMBO_TYPE = WSUIPlugin.ID + ".PWSI0008";
      
  private Label wsi_ap_Label_;
  private Combo wsi_ap_Types_;
  
  private int savedSSBPSetting_ = -1;
  
  private Group validationSelectionGroup_;
  
  private Text wsdlValidationLabel_;
  /*CONTEXT_ID PWSI0009 for the No Wizard WSDL validation button on the Profile Compliance and Validation page*/
  private Button validateNoWsdlButton_;
  /*CONTEXT_ID PWSI00010 for the Wizard WSDL validation for remote files only button on the Profile Compliance and Validation page*/
  private Button validateRemoteWsdlButton_;
  /*CONTEXT_ID PWSI00011 for the Wizard WSDL validation for all files button on the Profile Compliance and Validation page*/
  private Button validateAllWsdlButton_;
  private Text waitForWsdlValidationLabel_;
  /*CONTEXT_ID PWSI00012 for the Wait for pending WSDL validation to complete checkbox on the Profile Compliance and Validation page*/
  private Button waitForWSDLValidationCheckbox_;
  

  /*
   * CONTEXT_ID PWRS0009 for the no wsdl validation radio button of the profile validation preference page
   */
  private String INFOPOP_PWSI_RADIO_WSDLVAL_NONE = WSUIPlugin.ID + ".PWSI0009";
  /*
   * CONTEXT_ID PWRS0010 for the wsdl validation on remote document radio button of the profile validation preference page
   */
  private String INFOPOP_PWSI_RADIO_WSDLVAL_REMOTE = WSUIPlugin.ID + ".PWSI00010";
  /*
   * CONTEXT_ID PWRS0011 for the wsdl validation on all document radio button of the profile validation preference page
   */
  private String INFOPOP_PWSI_RADIO_WSDLVAL_ALL = WSUIPlugin.ID + ".PWSI0011";
  /*
   * CONTEXT_ID PWRS0012 for the wsdl validation label of the profile validation preference page
   */
  private String INFOPOP_PWSI_WSDLVAL_LABEL = WSUIPlugin.ID + ".PWSI0012";
  /*
   * CONTEXT_ID PWRS0013 for the wait for wsdl validation checkbox of the profile validation preference page
   */
  private String INFOPOP_PWSI_BUTTON_WAIT_FOR_WSDLVAL = WSUIPlugin.ID + ".PWSI0013";

 /**
   * Creates preference page controls on demand.
   *   @param parent  the parent for the preference page
   */
  protected Control createContents(Composite superparent)
  {
   
    IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem();
	
    Composite   parent = new Composite( superparent, SWT.NONE );	
    GridLayout layout = new GridLayout();
    layout.numColumns = 1;
    parent.setLayout( layout );
    parent.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
    parent.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_PAGE);
    helpSystem.setHelp(parent,INFOPOP_PWSI_PAGE);

    GridLayout gl = new GridLayout();
    gl.numColumns = 1;
    gl.marginHeight = 0;
    gl.marginWidth = 0;

    Composite wsi_Composite = new Composite (parent, SWT.NONE);
    wsi_Composite.setLayout(gl);
    wsi_Composite.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
    
    wsi_ap_Label_ = new Label(wsi_Composite, SWT.NONE);
    wsi_ap_Label_.setText(WstWSUIPluginMessages.LABEL_WSI_AP);
    wsi_ap_Label_.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_AP_LABEL);
    wsi_ap_Types_ = new Combo(wsi_Composite, SWT.DROP_DOWN | SWT.READ_ONLY);
    wsi_ap_Types_.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
    wsi_ap_Types_.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_AP_COMBO);
    helpSystem.setHelp(wsi_ap_Types_,INFOPOP_PWSI_AP_COMBO_TYPE);
    
    wsi_ap_Types_.add(WstWSUIPluginMessages.STOP_NON_WSI);
    wsi_ap_Types_.add(WstWSUIPluginMessages.WARN_NON_WSI);
    wsi_ap_Types_.add(WstWSUIPluginMessages.IGNORE_NON_WSI);
    
    wsi_ap_Types_.addSelectionListener(this);
    
    wsi_ssbp_Label_ = new Label(wsi_Composite, SWT.NONE);
    wsi_ssbp_Label_.setText(WstWSUIPluginMessages.LABEL_WSI_SSBP);
    wsi_ssbp_Label_.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_SSBP_LABEL);
    wsi_ssbp_Types_ = new Combo(wsi_Composite, SWT.DROP_DOWN | SWT.READ_ONLY);
    wsi_ssbp_Types_.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
    wsi_ssbp_Types_.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_SSBP_COMBO);
    helpSystem.setHelp(wsi_ssbp_Types_,INFOPOP_PWSI_SSBP_COMBO_TYPE);
    
    wsi_ssbp_Types_.add(WstWSUIPluginMessages.STOP_NON_WSI);
    wsi_ssbp_Types_.add(WstWSUIPluginMessages.WARN_NON_WSI);
    wsi_ssbp_Types_.add(WstWSUIPluginMessages.IGNORE_NON_WSI);
  
    // WSDL validation preferences
    validationSelectionGroup_ = new Group(wsi_Composite, SWT.NONE);
    gl = new GridLayout();
    gl.marginHeight = 0;
    gl.marginWidth = 0;
    validationSelectionGroup_.setLayout(gl);
    GridData gd = new GridData(GridData.FILL_HORIZONTAL);
    validationSelectionGroup_.setLayoutData(gd);
    
    wsdlValidationLabel_ = new Text(validationSelectionGroup_, SWT.READ_ONLY);
    wsdlValidationLabel_.setText(WstWSUIPluginMessages.LABEL_WSDLVAL);
    wsdlValidationLabel_.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_WSDLVAL_LABEL);
    helpSystem.setHelp(wsdlValidationLabel_, INFOPOP_PWSI_WSDLVAL_LABEL);
    
    validateNoWsdlButton_ = new Button(validationSelectionGroup_, SWT.RADIO);
    validateNoWsdlButton_.setText(WstWSUIPluginMessages.LABEL_WSDLVAL_NONE);
    validateNoWsdlButton_.addListener(SWT.Selection, this);
    validateNoWsdlButton_.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_RADIO_WSDLVAL_NONE);
    helpSystem.setHelp(validateNoWsdlButton_, INFOPOP_PWSI_RADIO_WSDLVAL_NONE);
    
    validateRemoteWsdlButton_ = new Button(validationSelectionGroup_, SWT.RADIO);
    validateRemoteWsdlButton_.setText(WstWSUIPluginMessages.LABEL_WSDLVAL_REMOTE);
    validateRemoteWsdlButton_.addListener(SWT.Selection, this);
    validateRemoteWsdlButton_.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_RADIO_WSDLVAL_REMOTE);
    helpSystem.setHelp(validateRemoteWsdlButton_, INFOPOP_PWSI_RADIO_WSDLVAL_REMOTE);
    
    validateAllWsdlButton_ = new Button(validationSelectionGroup_, SWT.RADIO);
    validateAllWsdlButton_.setText(WstWSUIPluginMessages.LABEL_WSDLVAL_ALL);
    validateAllWsdlButton_.addListener(SWT.Selection, this);
    validateAllWsdlButton_.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_RADIO_WSDLVAL_ALL);
    helpSystem.setHelp(validateAllWsdlButton_, INFOPOP_PWSI_RADIO_WSDLVAL_ALL);
    
    new Label(validationSelectionGroup_, SWT.NONE);;
    
    waitForWsdlValidationLabel_ = new Text(validationSelectionGroup_, SWT.READ_ONLY);
    waitForWsdlValidationLabel_.setText(WstWSUIPluginMessages.LABEL_WAIT_FOR_WSDLVAL);
    waitForWsdlValidationLabel_.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_LABEL_WAIT_FOR_WSDLVAL);
    
    waitForWSDLValidationCheckbox_ = new Button(validationSelectionGroup_, SWT.CHECK);
    waitForWSDLValidationCheckbox_.setText(WstWSUIPluginMessages.BUTTON_WAIT_FOR_WSDLVAL);            
    waitForWSDLValidationCheckbox_.addListener(SWT.Selection, this);
    waitForWSDLValidationCheckbox_.setToolTipText(WstWSUIPluginMessages.TOOLTIP_PWSI_BUTTON_WAIT_FOR_WSDLVAL);
    helpSystem.setHelp(waitForWSDLValidationCheckbox_, INFOPOP_PWSI_BUTTON_WAIT_FOR_WSDLVAL);
    
    initializeValues();
    org.eclipse.jface.dialogs.Dialog.applyDialogFont(superparent);    
    return parent;
  }

  /**
   * Does anything necessary because the default button has been pressed.
   */
  protected void performDefaults()
  {
    super.performDefaults();
    initializeDefaults();
  }

  /**
   * Do anything necessary because the OK button has been pressed.
   *  @return whether it is okay to close the preference page
   */
  public boolean performOk()
  {
    storeValues();
    return true;
  }

  protected void performApply()
  {
    performOk();
  }

  /**
   * @see IWorkbenchPreferencePage
   */
  public void init(IWorkbench workbench)   { }

  /**
   * Initializes states of the controls using default values
   * in the preference store.
   */
  private void initializeDefaults()
  {
    // force WSI compliance by default
    
    wsi_ssbp_Types_.select(wsi_ssbp_Types_.indexOf(WstWSUIPluginMessages.WARN_NON_WSI));
    int apSelection = wsi_ap_Types_.indexOf(WstWSUIPluginMessages.WARN_NON_WSI);
    wsi_ap_Types_.select(apSelection);
    savedSSBPSetting_ = -1;  // do not restore saved SSBP setting
    processAPSelection(apSelection);

    PersistentWSDLValidationContext wsdlValidationContext = WSPlugin.getInstance().getWSDLValidationContext();
    String validationSelection = wsdlValidationContext.getDefault();
    wsdlValidationContext.updateWSDLValidation(validationSelection);
    validateNoWsdlButton_.setSelection(false);
    validateRemoteWsdlButton_.setSelection(false);
    validateAllWsdlButton_.setSelection(false);
    processWSDLValidationSelection(validationSelection);
    
    waitForWSDLValidationCheckbox_.setSelection(WSPlugin.getInstance().getWaitForWSDLValidationContext().getDefault());
    WSPlugin.getInstance().getWaitForWSDLValidationContext().setWaitForWSDLValidation(WSPlugin.getInstance().getWaitForWSDLValidationContext().getDefault());
    
  }

  /**
   * Initializes states of the controls from the preference store.
   */
  private void initializeValues()
  {
    
	String WSIText = getWSISelection(WSPlugin.getInstance().getWSISSBPContext());
    wsi_ssbp_Types_.select(wsi_ssbp_Types_.indexOf(WSIText));
    
    int apSelection = wsi_ap_Types_.indexOf(getWSISelection(WSPlugin.getInstance().getWSIAPContext()));
    wsi_ap_Types_.select(apSelection);
    savedSSBPSetting_ = -1;  // do not restore saved SSBP setting
    processAPSelection(apSelection);
    
    String validationSelection = WSPlugin.getInstance().getWSDLValidationContext().getPersistentWSDLValidation();
    processWSDLValidationSelection(validationSelection);
    
    waitForWSDLValidationCheckbox_.setSelection(WSPlugin.getInstance().getWaitForWSDLValidationContext().getPersistentWaitForWSDLValidation());
  }

  private void processWSDLValidationSelection(String validationSelection) {

		if (PersistentWSDLValidationContext.VALIDATE_NO_WSDL.equals(validationSelection)) {
			validateNoWsdlButton_.setSelection(true);
		} else if (PersistentWSDLValidationContext.VALIDATE_REMOTE_WSDL.equals(validationSelection)) {
			validateRemoteWsdlButton_.setSelection(true);
		} else if (PersistentWSDLValidationContext.VALIDATE_ALL_WSDL.equals(validationSelection)) {
			validateAllWsdlButton_.setSelection(true);
		}

	}

private String getWSISelection(PersistentWSIContext context)
  {
    
    String WSIvalue = context.getPersistentWSICompliance();
    String WSIText = WstWSUIPluginMessages.WARN_NON_WSI;
    if (PersistentWSIContext.STOP_NON_WSI.equals(WSIvalue)) {
		WSIText = WstWSUIPluginMessages.STOP_NON_WSI;
	} else if (PersistentWSIContext.IGNORE_NON_WSI.equals(WSIvalue)) {
		WSIText = WstWSUIPluginMessages.IGNORE_NON_WSI;
	}
	return WSIText;
  }
  /**
   * Stores the values of the controls back to the preference store.
   */
  private void storeValues()
  {
  	updateWSIContext(wsi_ssbp_Types_.getSelectionIndex(), WSPlugin.getInstance().getWSISSBPContext());
  	updateWSIContext(wsi_ap_Types_.getSelectionIndex(), WSPlugin.getInstance().getWSIAPContext());
  }
  
  private void updateWSIContext(int selectionIndex, PersistentWSIContext context)
  {
    // get the persistent context from the plugin
    
    String value=null;
    switch (selectionIndex) {
    	case 0:
    		value = PersistentWSIContext.STOP_NON_WSI;
    		break;
    	case 1:
    		value = PersistentWSIContext.WARN_NON_WSI;
    		break;
    	case 2:
    		value = PersistentWSIContext.IGNORE_NON_WSI;		
    		break;
    }
    context.updateWSICompliances(value);
  }
  
  public void widgetSelected(SelectionEvent e)
  {
  	
  	processAPSelection( wsi_ap_Types_.getSelectionIndex() );
  	
  }
  
  public void processAPSelection(int selection) {
  	if (selection == 2) { // reset SSBP to default if AP is ignore
  		wsi_ssbp_Types_.setEnabled(true);
  		if (savedSSBPSetting_ != -1)  {
  			// restore saved SSBP setting, if any
  			wsi_ssbp_Types_.select(savedSSBPSetting_);
  			savedSSBPSetting_ = -1;
  		}
  	} else { // set SSBP to follow AP setting if STOP or WARN chosen
  		if (savedSSBPSetting_ == -1)  {  // SSBP setting not saved
  			savedSSBPSetting_ = wsi_ssbp_Types_.getSelectionIndex();
  		}
  		wsi_ssbp_Types_.select(selection);
  		wsi_ssbp_Types_.setEnabled(false);
  		
  	}
  }

  public void widgetDefaultSelected(SelectionEvent e) {
	
  }
  
  /**
   * Called when an event occurs on the page. Handles the event and revalidates the page.
   * 
   * @param event
   *          The event that occured.
   */
  public void handleEvent(Event event) {
	  
	  if (waitForWSDLValidationCheckbox_ == event.widget) {		   		  
		  WSPlugin.getInstance().getWaitForWSDLValidationContext().setWaitForWSDLValidation(waitForWSDLValidationCheckbox_.getSelection());
	  } else {
		  String wsdlValdationSelection = null;
		  if (validateNoWsdlButton_ == event.widget) {
			  wsdlValdationSelection = PersistentWSDLValidationContext.VALIDATE_NO_WSDL;
		  }
		  else if (validateRemoteWsdlButton_ == event.widget) {
			  wsdlValdationSelection = PersistentWSDLValidationContext.VALIDATE_REMOTE_WSDL;
		  }
		  else if (validateAllWsdlButton_ == event.widget) {
			  wsdlValdationSelection = PersistentWSDLValidationContext.VALIDATE_ALL_WSDL;
		  }
		  WSPlugin.getInstance().getWSDLValidationContext().updateWSDLValidation(wsdlValdationSelection);
	  }
	  
	  
  }


}
