/*******************************************************************************
 * 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.consumption.common.FacetUtils;
import org.eclipse.jst.ws.internal.consumption.ui.ConsumptionUIMessages;
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.consumption.ui.wsrt.WebServiceRuntimeExtensionUtils2;
import org.eclipse.jst.ws.internal.data.TypeRuntimeServer;
import org.eclipse.jst.ws.internal.ui.common.UIUtils;
import org.eclipse.osgi.util.NLS;
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.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;

/*
 *
 * ServerRuntimeSelectionWidget
 * This widget is the parent widget for server and client deployment/environment settings 
 * 
 */
public class ServerRuntimeSelectionWidget extends SimpleWidgetDataContributor
{
  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 boolean isClientWidgetVisible_ = true;
  
  public WidgetDataEvents addControls( Composite parent, Listener statusListener )
  {
    UIUtils      uiUtils  = new UIUtils( 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, NLS.bind(ConsumptionUIMessages.MSG_GENERAL_PROJECT_AND_EAR, new String[] {ConsumptionUIMessages.MSG_SERVICE_SUB}));
    createMessageText( textComposite, ConsumptionUIMessages.MSG_EAR_PROJECT_WILL_BE_CREATED );
    
    Composite serverComp = uiUtils.createComposite( root, 1, 5, 0 );
    
    Group serverGroup = uiUtils.createGroup( serverComp, ConsumptionUIMessages.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);
    projectWidget_.refreshProjectItems();
    runtimeWidget_.addModifyListener( textListener_ );
  }
  
  public TypeRuntimeServer getClientTypeRuntimeServer()
  {
    return clientWidget_.getClientTypeRuntimeServer();  
  }
   
  public void setClientTypeRuntimeServer( TypeRuntimeServer ids )
  {
    clientWidget_.setClientTypeRuntimeServer( ids );  
  }
  
  public void setServiceRuntimeId(String id)
  {
	//TODO This method and any mappings to it
	// should be deleted if no longer required.
  }
  
  public String getServiceRuntimeId()
  {
    //calculate the most appropriate clientRuntimeId based on current settings.
    String projectName = projectWidget_.getProjectName();
    String templateId = projectWidget_.getComponentType();
    
    //Find the service runtime that fits this profile best.
    return WebServiceRuntimeExtensionUtils2.getServiceRuntimeId(runtimeWidget_.getTypeRuntimeServer(), projectName, templateId);    
  }  
  
  public void setClientRuntimeId(String id)
  {
    //TODO This method and any mappings to it
	// should be deleted if no longer required.
  }
  
  public String getClientRuntimeId()
  {
    //calculate the most appropriate clientRuntimeId based on current settings.
    return clientWidget_.getClientRuntimeId();
  } 
  
  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 getServiceComponentType()
  {
    return projectWidget_.getComponentType();
  }
  
  public void setServiceComponentType( String type )
  {
	projectWidget_.setComponentType( type );  
  }
  
  public String getClientComponentType()
  {
    return clientWidget_.getClientComponentType();
  }  
  
  public void setClientComponentType( String type )
  {
	clientWidget_.setClientComponentType( type );  
  }
  
  public String getServiceProjectName()
  {
    return projectWidget_.getProjectName();  
  }
  
  public void setServiceProjectName(String name)
  {
    projectWidget_.setProjectName(name);  
  }
  
  public String getServiceEarProjectName()
  {
	return projectWidget_.getEarProjectName();  
  }
  
  public void setServiceEarProjectName(String name)
  {
    projectWidget_.setEarProjectName(name);  
  }  
  
  public String getClientProjectName()
  {
    return clientWidget_.getClientProjectName();  
  }
  
  public void setClientProjectName(String name)
  {
    clientWidget_.setClientProjectName(name);  
  }  
  
  public String getClientEarProjectName()
  {
	return clientWidget_.getClientEarProjectName();  
  }
  
  public void setClientEarProjectName(String name)
  {
    clientWidget_.setClientEarProjectName(name);  
  }    
  
  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_.refreshProjectItems();
  	}
  }
 
  
  /* (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;
    }
    
    String projectName = projectWidget_.getProjectName();
    if (projectName != null && projectName.length()>0)
    {
      //If the project exists, ensure that it is suitable for the selected runtime
      //and server.
      ValidationUtils valUtils = new ValidationUtils();
      IProject project = ProjectUtilities.getProject(projectName);
      String typeId = getServiceTypeRuntimeServer().getTypeId();
      String runtimeId = getServiceTypeRuntimeServer().getRuntimeId();
      String serverFactoryId = getServiceTypeRuntimeServer().getServerId();
      
      if (project.exists())
      {
        //Check if the runtime supports it.
        if (!WebServiceRuntimeExtensionUtils2.doesServiceTypeAndRuntimeSupportProject(typeId, runtimeId, projectName))
        {
          String runtimeLabel = WebServiceRuntimeExtensionUtils2.getRuntimeLabelById(runtimeId);
          finalStatus = StatusUtils.errorStatus(NLS.bind(ConsumptionUIMessages.MSG_SERVICE_RUNTIME_DOES_NOT_SUPPORT_PROJECT, new String[]{runtimeLabel, projectName}));
        }
        
        //Check if the server supports it.

        if (serverFactoryId!=null && serverFactoryId.length()>0)
        {
          if (!valUtils.doesServerSupportProject(serverFactoryId, projectName))
          {
            String serverLabel = WebServiceRuntimeExtensionUtils2.getServerLabelById(serverFactoryId);
            finalStatus = StatusUtils.errorStatus(NLS.bind(ConsumptionUIMessages.MSG_SERVICE_SERVER_DOES_NOT_SUPPORT_PROJECT, new String[]{serverLabel, projectName}));
          }
        }          
      }
      else
      {
        //Look at the project type to ensure that it is suitable for the selected runtime
        //and server.
        
        String templateId = getServiceComponentType();

        if (templateId != null && templateId.length()>0)
        {
          //Check if the runtime supports it.            
          if (!WebServiceRuntimeExtensionUtils2.doesServiceTypeAndRuntimeSupportTemplate(typeId, runtimeId, templateId))
          {
            String runtimeLabel = WebServiceRuntimeExtensionUtils2.getRuntimeLabelById(runtimeId);
            String templateLabel = FacetUtils.getTemplateLabelById(templateId);
            finalStatus = StatusUtils.errorStatus(NLS.bind(ConsumptionUIMessages.MSG_SERVICE_RUNTIME_DOES_NOT_SUPPORT_TEMPLATE, new String[]{runtimeLabel, templateLabel}));
          }
          
          //Check if the server supports it.
          if (serverFactoryId!=null && serverFactoryId.length()>0)
          {
            if (!valUtils.doesServerSupportTemplate(serverFactoryId, templateId))
            {
              String serverLabel = WebServiceRuntimeExtensionUtils2.getServerLabelById(serverFactoryId);
              String templateLabel = FacetUtils.getTemplateLabelById(templateId);
              finalStatus = StatusUtils.errorStatus(NLS.bind(ConsumptionUIMessages.MSG_SERVICE_SERVER_DOES_NOT_SUPPORT_TEMPLATE, new String[]{serverLabel, templateLabel}));
            }
          }
        }
        
        
        
      }
    }    
    /*
    //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())
      {
        if (serviceComponentName!=null && serviceComponentName.length()>0)
        {
          String compTypeId = J2EEUtils.getComponentTypeId(serviceProj);
          if (!compTypeId.equals(projectWidget_.getComponentType()))
          {
        	//Construct the error message
        	String compTypeLabel = getCompTypeLabel(projectWidget_.getComponentType()); 
        	finalStatus = StatusUtils.errorStatus( NLS.bind(ConsumptionUIMessages.MSG_INVALID_PROJECT_TYPE,new String[]{serviceProjName, compTypeLabel}) );        	        	
          }
        }
      }
    }
    */
    if (isClientWidgetVisible_) 
    {
	    String clientEARName   = clientWidget_.getClientEarProjectName();
	    String clientProjName  = clientWidget_.getClientProjectName();
        String serviceProjName = projectWidget_.getProjectName();
	    String serviceEarName  = projectWidget_.getEarProjectName();
  		//String clientComponentName = clientWidget_.getClientComponentName();
		
	    // check same EAR-ness -----
	    String warning_msg = getEARProjectWarningMessage(serviceEarName, clientEARName);
	    
		//if (serviceComponentName.equalsIgnoreCase(clientComponentName)){
			  //String err_msg = NLS.bind(ConsumptionUIMessages.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 =ConsumptionUIMessages.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 NLS.bind(ConsumptionUIMessages.MSG_SAME_CLIENT_AND_SERVICE_EARS, new String[]{ "EAR" });
      }
    }

    return null;

  }
}
