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

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.consumption.ui.common.ValidationUtils;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.runtime.ClientRuntimeSelectionWidget;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.runtime.ProjectSelectionWidget;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.runtime.RuntimeServerSelectionWidget;
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.custom.ScrolledComposite;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;
import org.eclipse.wst.command.internal.provisional.env.core.common.MessageUtils;
import org.eclipse.wst.command.internal.provisional.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.provisional.env.core.selection.SelectionListChoices;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;

/*
 *
 * ServerRuntimeSelectionWidget
 * This widget is the parent widget for server and client deployment/environment settings 
 * 
 */
public class ServerRuntimeSelectionWidget extends SimpleWidgetDataContributor
{
  private String pluginId_ = "org.eclipse.jst.ws.consumption.ui";
  private String createPluginId_ = "org.eclipse.jst.ws.creation.ui";
  
  /* CONTEXT_ID PWRS0002 for the Wizard Scenario Service configuration of the Runtime Selection Page */
  private String INFOPOP_PWRS_GROUP_SERVICE =  "PWRS0002";
  
  private RuntimeServerSelectionWidget runtimeWidget_;
  private ProjectSelectionWidget       projectWidget_;
  private ClientRuntimeSelectionWidget clientWidget_;
  private TextModifyListener           textListener_;
  private MessageUtils msgUtils_;
  
  private boolean isClientWidgetVisible_ = true;
  
  public WidgetDataEvents addControls( Composite parent, Listener statusListener )
  {
    msgUtils_ = new MessageUtils( pluginId_ + ".plugin", this );
    UIUtils      uiUtils  = new UIUtils(msgUtils_, createPluginId_ ); 
    
    ScrolledComposite scroller = new ScrolledComposite( parent, SWT.H_SCROLL | SWT.V_SCROLL );
    scroller.setExpandHorizontal(true);
    scroller.setExpandVertical(true);
    
    Composite root = uiUtils.createComposite( scroller, 1 );
    scroller.setContent( root );
    
    Composite textComposite = uiUtils.createComposite( root, 1, 0, 0 );
    createMessageText( textComposite, msgUtils_.getMessage("MSG_GENERAL_PROJECT_AND_EAR", new String[] { msgUtils_.getMessage("MSG_SERVICE_SUB")}));
    createMessageText( textComposite, msgUtils_.getMessage("MSG_EAR_PROJECT_WILL_BE_CREATED") );
    
    Composite serverComp = uiUtils.createComposite( root, 1, 5, 0 );
    
    Group serverGroup = uiUtils.createGroup( serverComp, "LABEL_SELECTION_VIEW_TITLE",
                                             null, INFOPOP_PWRS_GROUP_SERVICE,
											 2, 5, 5);
    
    runtimeWidget_ = new RuntimeServerSelectionWidget( false );
    runtimeWidget_.addControls( serverGroup, statusListener );
    textListener_ = new TextModifyListener();
    runtimeWidget_.addModifyListener( textListener_ );
             
    projectWidget_ = new ProjectSelectionWidget();
    projectWidget_.addControls( serverGroup, statusListener );
    
    clientWidget_ = new ClientRuntimeSelectionWidget();
    clientWidget_.addControls( root, statusListener );
    
    Point size = root.computeSize(SWT.DEFAULT, SWT.DEFAULT);
    scroller.setMinSize( size ); 
    root.setSize( size );
     
    scroller.setLayoutData( new GridData( GridData.FILL_BOTH ) );
    
    return this;
  }
  
  //If generate proxy is not selected, don't show the client portion of the page.
  public void setGenerateProxy( Boolean value )
  {
    clientWidget_.setVisible( value.booleanValue() ); 
    isClientWidgetVisible_ = value.booleanValue();
  }
  
  public TypeRuntimeServer getServiceTypeRuntimeServer()
  {
    return runtimeWidget_.getTypeRuntimeServer();  
  }
   
  public void setServiceTypeRuntimeServer( TypeRuntimeServer ids )
  {
    runtimeWidget_.removeModifyListener( textListener_ );
    runtimeWidget_.setTypeRuntimeServer( ids );  
    projectWidget_.setTypeRuntimeServer(ids);
    runtimeWidget_.addModifyListener( textListener_ );
  }
  
  public TypeRuntimeServer getClientTypeRuntimeServer()
  {
    return clientWidget_.getClientTypeRuntimeServer();  
  }
   
  public void setClientTypeRuntimeServer( TypeRuntimeServer ids )
  {
    clientWidget_.setClientTypeRuntimeServer( ids );  
  }
  
  public SelectionListChoices getServiceProject2EARProject()
  {
    return projectWidget_.getProjectChoices();
  }
  
  public void setServiceProject2EARProject(SelectionListChoices serviceProject2EARProject)
  {
    projectWidget_.setProjectChoices(serviceProject2EARProject);
  }
  
  public SelectionListChoices getRuntime2ClientTypes()
  {
    return clientWidget_.getRuntime2ClientTypes();
  }  
  
  public void setRuntime2ClientTypes(SelectionListChoices runtime2ClientTypes)
  {
    clientWidget_.setRuntime2ClientTypes(runtime2ClientTypes);
  }
  
  public String getServiceJ2EEVersion()
  {
    return runtimeWidget_.getJ2EEVersion();
  }
  
  public void setServiceJ2EEVersion(String j2eeVersion)
  {
    runtimeWidget_.setJ2EEVersion(j2eeVersion);
    projectWidget_.setJ2EEVersion(j2eeVersion);
  }
  
  public String getClientJ2EEVersion()
  {
    return clientWidget_.getJ2EEVersion();
  }
  
  public void setClientJ2EEVersion(String j2eeVersion)
  {
    clientWidget_.setJ2EEVersion(j2eeVersion);
  }
  
  public boolean getServiceNeedEAR()
  {
    return projectWidget_.getNeedEAR();
  }
  
  public void setServiceNeedEAR(boolean b)
  {
    projectWidget_.setNeedEAR(b);
  }
  
  public boolean getClientNeedEAR()
  {
    return clientWidget_.getClientNeedEAR();
  }
  
  public void setClientNeedEAR(boolean b)
  {
    clientWidget_.setClientNeedEAR(b);
  }  
  
  public String getServiceComponentName()
  {
	return projectWidget_.getComponentName();  
  }
  
  public void setServiceComponentName( String name )
  {
    projectWidget_.setComponentName( name );
  }
  
  public String getServiceEarComponentName()
  {
    return projectWidget_.getEarComponentName();	  
  }
  
  public void setServiceEarComponentName( String name )
  {
	projectWidget_.setEarComponentName( name );  
  }
  
  public void setServiceComponentType( String type )
  {
	projectWidget_.setComponentType( type );  
  }
  
  public String getClientComponentName()
  {
	return clientWidget_.getClientComponentName();  
  }
  
  public void setClientComponentName( String name )
  {
    clientWidget_.setClientComponentName( name );
  }
  
  public String getClientEarComponentName()
  {
    return clientWidget_.getClientEarComponentName();	  
  }
  
  public void setClientEarComponentName( String name )
  {
	clientWidget_.setClientEarComponentName( name );  
  }
  
  public String getClientComponentType()
  {
    return clientWidget_.getClientComponentType();
  }  
  
  public void setComponentType( String type )
  {
	clientWidget_.setClientComponentType( type );  
  }
  
  public String getServiceProjectName()
  {
    return projectWidget_.getProjectName();  
  }
  
  public String getServiceEarProjectName()
  {
	return projectWidget_.getEarProjectName();  
  }
  
  public String getClientProjectName()
  {
    return clientWidget_.getClientProjectName();  
  }
  
  public String getClientEarProjectName()
  {
	return clientWidget_.getClientEarProjectName();  
  }
  
  private class TextModifyListener implements ModifyListener 
  {
  	public void modifyText(ModifyEvent e)
  	{
		if( clientWidget_.isVisible() )
  		{  	  
		  TypeRuntimeServer serviceIds = runtimeWidget_.getTypeRuntimeServer();
  		  TypeRuntimeServer clientIds  = clientWidget_.getClientTypeRuntimeServer();
  		
  		  clientIds.setRuntimeId( serviceIds.getRuntimeId() );
  		  clientIds.setServerId( serviceIds.getServerId() );
  		  clientIds.setServerInstanceId( serviceIds.getServerInstanceId() );

  		  clientWidget_.setClientTypeRuntimeServer( clientIds );
  		  clientWidget_.setJ2EEVersion(runtimeWidget_.getJ2EEVersion());  	
  		}
		
		//Set the current server selection and J2EE level on the ProjectSelectionWidget
		projectWidget_.setTypeRuntimeServer(runtimeWidget_.getTypeRuntimeServer());
		projectWidget_.setJ2EEVersion(runtimeWidget_.getJ2EEVersion());
  	}
  }
 
  
  /* (non-Javadoc)
   * @see org.eclipse.wst.command.env.ui.widgets.WidgetContributor#getStatus()
   */
  public IStatus getStatus() 
  {
    IStatus serviceStatus = runtimeWidget_.getStatus();
    IStatus projectStatus = projectWidget_.getStatus();
    IStatus clientStatus  = clientWidget_.getStatus();    
    IStatus finalStatus   = Status.OK_STATUS;
    
    // call child widgets' getStatus()
    if( serviceStatus.getSeverity() == Status.ERROR )
    {
      finalStatus = serviceStatus;
    }
    else if( clientStatus.getSeverity() == Status.ERROR )
    {
      if (isClientWidgetVisible_)
        finalStatus = clientStatus;
    }
    else if ( projectStatus.getSeverity()== Status.ERROR) {
      finalStatus = projectStatus;
    }
    
    //Validate service side server target and J2EE level
	ValidationUtils valUtils = new ValidationUtils();
	String serviceEARName  = projectWidget_.getEarProjectName();
	String serviceProjName = projectWidget_.getProjectName();
	String serviceServerFactoryId = runtimeWidget_.getTypeRuntimeServer().getServerId();
	String serviceJ2EElevel = runtimeWidget_.getJ2EEVersion();
  String serviceComponentName = projectWidget_.getComponentName();
  String serviceEARComponentName = projectWidget_.getEarComponentName();
	IStatus serviceProjectStatus = valUtils.validateProjectTargetAndJ2EE(serviceProjName,serviceComponentName, serviceEARName, serviceEARComponentName, serviceServerFactoryId, serviceJ2EElevel);
	if(serviceProjectStatus.getSeverity()==Status.ERROR)
	{
		finalStatus = serviceProjectStatus;
	}
    
    //Ensure the service project type (Web/EJB) is valid
    if (serviceProjName!=null && serviceProjName.length()>0)
    {
      IProject serviceProj = ProjectUtilities.getProject(serviceProjName);
      if (serviceProj.exists())
      {
		// rskreg
        //WebServiceServerRuntimeTypeRegistry wssrtRegistry = WebServiceServerRuntimeTypeRegistry.getInstance();
        //String serverTypeId = wssrtRegistry.getWebServiceServerByFactoryId(serviceServerFactoryId).getId();
		//String serverTypeId = wssrtRegistry.getWebServiceServerByFactoryId(serviceServerFactoryId).getId();
        /* rskejb
        boolean isEJBRequired = WebServiceRuntimeExtensionUtils.requiresEJBModuleFor(serviceServerFactoryId, webServiceRuntimeId, webServiceTypeId);
        if (!isEJBRequired)
        {
          //Check the Web service type to see if an EJB project is required
          //isEJBRequired = wssrtRegistry.requiresEJBProject(webServiceTypeId);
			isEJBRequired = WebServiceRuntimeExtensionUtils.requiresEJBProject(webServiceTypeId);
        }
        rskejb */
        if (serviceComponentName!=null && serviceComponentName.length()>0)
        {
          String compTypeId = J2EEUtils.getComponentTypeId(serviceProj, serviceComponentName);
          if (!compTypeId.equals(projectWidget_.getComponentType()))
          {
        	//Construct the error message
        	String compTypeLabel = getCompTypeLabel(projectWidget_.getComponentType()); 
        	finalStatus = StatusUtils.errorStatus( msgUtils_.getMessage("MSG_INVALID_PROJECT_TYPE",new String[]{serviceProjName, compTypeLabel}) );        	        	
          }
        }
        // begin remove
        /*
        boolean isEJBRequired = WebServiceRuntimeExtensionUtils.requiresEJBProject(webServiceRuntimeId, webServiceTypeId);
        if (isEJBRequired && serviceComponentName!=null && serviceComponentName.length()>0 && !J2EEUtils.isEJBComponent(serviceProj, serviceComponentName))
        {
          finalStatus = new SimpleStatus("",msgUtils_.getMessage("MSG_INVALID_EJB_PROJECT",new String[]{serviceProjName}),Status.ERROR);          
        }
        if (!isEJBRequired && serviceComponentName!=null && serviceComponentName.length()>0 && !J2EEUtils.isWebComponent(serviceProj, serviceComponentName))
        {
          finalStatus = new SimpleStatus("",msgUtils_.getMessage("MSG_INVALID_WEB_PROJECT",new String[]{serviceProjName}),Status.ERROR);
        }
        */
        // end remove
      }
    }
    
    if (isClientWidgetVisible_) 
    {
	    String clientEARName   = clientWidget_.getClientEarProjectName();
	    String clientProjName  = clientWidget_.getClientProjectName();
	
  		String clientComponentName = clientWidget_.getClientComponentName();
		
	    // check same EAR-ness -----
	    String warning_msg = getEARProjectWarningMessage(serviceEARName, clientEARName);
	    
		if (serviceComponentName.equalsIgnoreCase(clientComponentName)){
			  String err_msg = msgUtils_.getMessage( "MSG_SAME_CLIENT_AND_SERVICE_COMPONENTS", new String[]{ "WEB" } );
			  finalStatus = StatusUtils.errorStatus( err_msg );				
		}
		
	    if( clientProjName != null && serviceProjName != null && 
	        clientProjName.equalsIgnoreCase( serviceProjName ))
	    {
		  String error_msg = msgUtils_.getMessage("MSG_SAME_CLIENT_AND_SERVICE_PROJECTS");
		  finalStatus = StatusUtils.errorStatus( error_msg );
	    }
	    
		if (warning_msg != null)
	    {
	      if (finalStatus.getSeverity()!=Status.ERROR)
	      	return StatusUtils.warningStatus( warning_msg );          
	    }         
      
    }
    
    return finalStatus;
  }
  
  private void createMessageText( Composite parent, String value )
  {
    Text     messageText = new Text( parent, SWT.WRAP | SWT.MULTI | SWT.READ_ONLY );    
	GridData gridData    = new GridData( GridData.FILL_BOTH );
	
	gridData.horizontalIndent = 10;    
	messageText.setLayoutData( gridData );
	messageText.setText( value );
  }
  
  private String getEARProjectWarningMessage(String serviceEARName, String clientEARName ) {

    // check if service and client share the same EAR
    if (serviceEARName!=null && clientEARName!=null) {
    
      if (clientEARName.equalsIgnoreCase(serviceEARName) && clientEARName.length()>0) {
        return msgUtils_.getMessage("MSG_SAME_CLIENT_AND_SERVICE_EARS", new String[]{ "EAR" });
      }
    }

    return null;

  }
  
  //Returns a label corresponding to the componentTypeId. This is hard-coded for now.
  //This is something the flexible project framework should provide. Enhancement 106785 has been
  //opened.
  private String getCompTypeLabel(String typeId)
  {
	  if (typeId.equals(IModuleConstants.JST_WEB_MODULE))
	  {
		  return msgUtils_.getMessage("LABEL_CLIENT_COMP_TYPE_WEB");
	  }
	  else if (typeId.equals(IModuleConstants.JST_EJB_MODULE))
	  {
		  return msgUtils_.getMessage("LABEL_CLIENT_COMP_TYPE_EJB");
	  }
	  else if (typeId.equals(IModuleConstants.JST_APPCLIENT_MODULE))
	  {
		  return msgUtils_.getMessage("LABEL_CLIENT_COMP_TYPE_APP_CLIENT");
	  }
	  else if (typeId.equals(IModuleConstants.JST_UTILITY_MODULE))
	  {
		  return msgUtils_.getMessage("LABEL_CLIENT_COMP_TYPE_CONTAINERLESS");
	  }
	  else
	  {
		  //No known label, return the typeId itself. 
		  return typeId;
	  }	  
  }
}
