/*
*
* Sample program for use with the Product
* Licensed Materials  - Property of IBM
* 5724-I66
* (c) Copyright IBM Corp.  2006, 2009
*   
*/
package com.ibm.wbit.tel.client.jsf.command;

import java.util.HashMap;
import java.util.List;

import com.ibm.bpc.clientcore.ClientException;
import com.ibm.bpc.clientcore.Command;
import com.ibm.bpe.api.ActivityServiceTemplateData;
import com.ibm.bpe.api.BusinessFlowManagerService;
import com.ibm.bpe.api.PIID;
import com.ibm.bpe.api.ProcessTemplateData;
import com.ibm.task.api.ClientObjectWrapper;
import com.ibm.task.api.HumanTaskManagerService;
import com.ibm.task.api.TKIID;
import com.ibm.wbit.tel.client.jsf.bean.BCCreateInstance;
import com.ibm.wbit.tel.client.jsf.infrastructure.CommandException;
import com.ibm.wbit.tel.client.jsf.infrastructure.ServiceFactory;
import com.ibm.wbit.tel.client.jsf.infrastructure.SharedConstants;




/** 
 * BCCreate will create a new Business Case.
 * Hence it will create and start the slected originating task or human task.
 * If the originating task is defined on an initiating receive activity the 
 * corresponding Business Process will be started.  
 * 
 */
public class BCCreate implements Command, SharedConstants {
        
      
    
    /**
     * Executes the create command for the selected Business Case. 
     * Exceptions to be shown in commandbar will be thrown as CommandException.
     * 
     * @param items the list of selected items
     * @return next navigation route as defined in faces-config, may be overwritten by action of commandbar
     * @exception CommandException to be shown in commandbar
     * @see com.ibm.bpc.clientcore.Command#execute(java.util.List)
      */
    @SuppressWarnings("unchecked")
	public String execute(List items) throws ClientException {

        if (items != null) {
            //we have only one selected
            Object obj = items.get(0);
            
            if (obj instanceof BCCreateInstance) {
                BCCreateInstance bcCreateInstance = (BCCreateInstance) obj;
                
                switch (bcCreateInstance.getType()) {
                
                case BCCreateInstance.TYPE_HUMAN_TASK:
                    createAndStartHumanTask(bcCreateInstance);
                    break;
                
                case BCCreateInstance.TYPE_BUSINESS_PROCESS:
                    startBusinessProcess(bcCreateInstance);
                    break;
                
                default:
                    throw new ClientException(NLS_CATALOG, TYPE_OF_BUSINESS_CASE_UNKNOWN, null, null);
                }
            }
        }
        return null;
    }
    
    
    /**
     * Create the standalone originating task or pure human task using its 
     * name and namespace and start it.
     * 
     * @param bcCreateInstance to create and start
     * @exception CommandException to be shown in commandbar
     */
    private void createAndStartHumanTask(BCCreateInstance bcCreateInstance) throws ClientException {

        HumanTaskManagerService htm;
        try {
            htm = ServiceFactory.getInstance().getHumanTaskManagerService();

            //create the task using name and namespace
            String name = bcCreateInstance.getComponentName();
            String namespace = bcCreateInstance.getComponentNamespace();
            TKIID taskInstanceID = htm.createTask(name, namespace);

            //get data structure of inputmessage
            ClientObjectWrapper cow = htm.createInputMessage( taskInstanceID );
            Object dataToStart = bcCreateInstance.getInputValuesAll( cow.getObject() );
            
            //start the task
            htm.startTask(taskInstanceID, new ClientObjectWrapper( dataToStart ), null);
        } catch (Exception e) {
            throw new CommandException(NLS_CATALOG, SERVICE_FAILED_TO_START_HUMAN_TASK, null, e);
        }
    }
    
    
    /**
     * Create a new Business Process and attach the values for custom properties.
     *  
     * @param bcCreateInstance to start
     * @throws ClientException
     */
    private void startBusinessProcess(BCCreateInstance bcCreateInstance) throws ClientException {
        
        BusinessFlowManagerService bfm;
        try {
            bfm = ServiceFactory.getInstance().getBusinessFlowManagerService();
            String processTemplateName;
            ProcessTemplateData processTemplate;
            ActivityServiceTemplateData[] availableStartActivities;
            String startActivityToUse, startActivity;
            
            //get some information about the Business Process to start
            processTemplateName = bcCreateInstance.getComponentName();
            startActivityToUse = bcCreateInstance.getComponentNameStart();
            processTemplate = bfm.getProcessTemplate( processTemplateName );
            availableStartActivities = bfm.getStartActivities( processTemplate.getID() );
                                   
            //find the right startActivity to start Business Process
            int startIdx = -1; 
            for (int i=0; i < availableStartActivities.length && startIdx == -1; i++){
                startActivity = availableStartActivities[i].getActivityName();
                if (startActivity == null) {
                    throw new ClientException(NLS_CATALOG, SERVICE_FAILED_TO_START_BUSINESS_PROCESS_NO_MSG, null, null);
                }
                if ( startActivity.equals(startActivityToUse)){
                    startIdx = i;
                }
            }
            if (startIdx == -1) {
                throw new ClientException(NLS_CATALOG, SERVICE_FAILED_TO_START_BUSINESS_PROCESS_NO_MSG, null, null);
            } 
            
            //get data structure of inputmessage
            com.ibm.bpe.api.ClientObjectWrapper cow = bfm.createMessage(
                    processTemplate.getID(),
                    availableStartActivities[startIdx].getInputMessageTypeName());
                        
            //fill in data
            Object dataToStart = bcCreateInstance.getInputValuesAll( cow.getObject() ); ;
                        
            //start business process asynchronously
            PIID piid = bfm.sendMessage(
            		availableStartActivities[startIdx].getServiceTemplateID(),
                    availableStartActivities[startIdx].getActivityTemplateID(), 
					new com.ibm.bpe.api.ClientObjectWrapper(dataToStart));
        
            //attach all custom properties to just created business process
            HashMap<String, String> cProperties = bcCreateInstance.getCustomPropertyValues();
         
            for (String key  : cProperties.keySet()) {
                bfm.setCustomProperty( piid, key, cProperties.get(key) );
            }
            
        } catch (Exception e) {
            throw new CommandException(NLS_CATALOG, SERVICE_FAILED_TO_START_BUSINESS_PROCESS, null, e);
        }
    }
    
    /**
     * @see com.ibm.bpc.clientcore.Command#isMultiSelectEnabled()
     */
    public boolean isMultiSelectEnabled() {
        return false;
    }

    /** 
     * @see com.ibm.bpc.clientcore.Command#isApplicable(java.util.List)
     */
    @SuppressWarnings("unchecked")
	public boolean[] isApplicable(List arg0) {
        return (new boolean[0]);
    }

    /**
     * @see com.ibm.bpc.clientcore.Command#setContext(java.lang.Object)
     */
    public void setContext(Object arg0) {
    }
        
}
