package com.blueland.bpm.engine.core.model;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import com.blueland.bpm.engine.config.model.ActivityInfoConfig;
import com.blueland.bpm.engine.util.WorkFlowContants;
import com.blueland.bpm.engine.util.ProcessDefinitionUtils;
import com.blueland.bpm.engine.util.WorkFlowException;
/**
 * 流程环节定义模型
 * @author lw
 *
 */
public class ActivityDefinitionModel  implements
		Serializable {
	static final long serialVersionUID = 1L;
	/**
	 * 流程定义ID
	 */
	String procDefId;
	/**
	 * 流程定义名称
	 */
	String procDefName;
	/**
	 * 环节定义ID
	 */
	String actDefId;
	/**
	 * 环节定义名称
	 */
	String actDefName;
	
	/**
	 * 描述
	 */
	String description;
	/**
	 * 优先级
	 */
	int priority;
	/**
	 * 环节类型
	 */
	String actType;
	/**
	 * 是否多人处理
	 */
	boolean isMulti;
	/**
	 * 是否同步模型--待定
	 */
	boolean isAsync;
	/**
	 * 客户端是否可以不传递人员来执行流程
	 */
	boolean isNotSelectReceiver;
	/**
	 * 环节配置对象
	 */
	private ActivityInfoConfig activityInfoConfig;
	
	private List<ActivityResourceModel> activityResources;
	/**
	 * 环节定义变量--待定
	 */
	protected Map<String, Object> variables;

	
	public static ActivityDefinitionModel build(PvmActivity pvmActivity) {
		ActivityDefinitionModel activityDefinition=new ActivityDefinitionModel();
		if (pvmActivity == null){
			/**
			 * 当流程管理中删除流程定义时,如果该流程的环节ID有变更,那么pvmActivity对象可能为Null
			 * 为了不影响删除逻辑此处不抛出异常(通过前端在ProcessMgrDataShare中设置PROCESS_DEF_DEL_MANAGE_OPT标识来判断)
			 * ProcessMgrDataShare.setProcessMgrData(PROCESS_DEF_DEL_MANAGE_OPT)在ProcessDefinitionController.delete()方法中
			 */
			Object obj=ProcessMgrDataShare.getProcessMgrData();
			if(obj!=null&&WorkFlowContants.PROCESS_DEF_DEL_MANAGE_OPT.equals(obj)){
				return null;
			}
			throw new WorkFlowException(ExceptionErrorCode.B2003,"activity is not found");
		}
		ActivityImpl activityImpl = (ActivityImpl) pvmActivity;
		activityDefinition.actDefId = activityImpl.getId();
		String actDefName = (String) activityImpl.getProperty("name");
		if (StringUtils.isEmpty(actDefName)) {
			actDefName = "结束";
		}
		activityDefinition.actDefName=actDefName;
		String destActivityType = (String) activityImpl
				.getProperty(BpmnXMLConstants.ATTRIBUTE_TYPE);

		if (ProcessDefinitionUtils.isMultiInstance(activityImpl)) {// 是否多实例类型
			destActivityType = ProcessDefinitionUtils.WF_ACTIVITY_TYPE_MULTI_INSTANCE;
		}
		activityDefinition.isMulti = ProcessDefinitionUtils.isMultiInstance(activityImpl);
		activityDefinition.isNotSelectReceiver=ProcessDefinitionUtils.isNotSelectReceiver(activityImpl);
		activityDefinition.isAsync=pvmActivity.isAsync();
		activityDefinition.actType = destActivityType;
		activityDefinition.procDefId= activityImpl.getProcessDefinition().getId();
		activityDefinition.procDefName = activityImpl.getProcessDefinition().getName();
		//super.build((ProcessDefinition) activityImpl.getProcessDefinition());
		return activityDefinition;
	}
	

	public static ActivityDefinitionModel build(PvmActivity pvmActivity,
			TransitionImpl transitionImpl) {
		ActivityDefinitionModel activityDefinition=new ActivityDefinitionModel();
		if (pvmActivity == null)
			return activityDefinition;
		ActivityImpl activityImpl = (ActivityImpl) pvmActivity;
		activityDefinition.actDefId = activityImpl.getId();
		// 环节名称:当转移线上的名称不为空时,使用它作为环节名称,否则使用任务定义名称
		String activityName = (String) activityImpl.getProperty("name");
		String transitionName = (String) transitionImpl.getProperty("name");
		String name = StringUtils.isNotEmpty(transitionName) ? transitionName
				: (StringUtils.isNotEmpty(activityName) ? activityName : "送结束");
		activityDefinition.actDefName = name;
		activityDefinition.actType =(String) activityImpl
				.getProperty(BpmnXMLConstants.ATTRIBUTE_TYPE);
		activityDefinition.isAsync=pvmActivity.isAsync();
		activityDefinition.isMulti = ProcessDefinitionUtils.isMultiInstance(activityImpl);;
		activityDefinition.isNotSelectReceiver=ProcessDefinitionUtils.isNotSelectReceiver(activityImpl);
		//super.build((ProcessDefinition) activityImpl.getProcessDefinition());
		return activityDefinition;
	}
	
	
	public static ActivityDefinitionModel build(Task tempTask) {
		ActivityDefinitionModel activityDefinition=new ActivityDefinitionModel();
		TaskEntity task=null;
		if (tempTask == null)
			return activityDefinition;
		task=(TaskEntity) tempTask;
		activityDefinition.actDefId=task.getTaskDefinitionKey();
		String actDefName=task.getName();
		if (StringUtils.isEmpty(actDefName)) {
			actDefName = "结束";
		}
		activityDefinition.actDefName=actDefName;
	/*	String destActivityType = (String) task.get
				.getProperty(WorkFlowContants.WF_ACTIVITY_TYPE_KEY);

		if (ProcessDefinitionUtils.isMultiInstance(activityImpl)) {// 是否多实例类型
			destActivityType = WorkFlowContants.WF_ACTIVITY_TYPE_MULTI_INSTANCE;
		}
		this.isMulti = ProcessDefinitionUtils.isMultiInstance(activityImpl);
		this.isAsync=pvmActivity.isAsync();
		this.activityType = destActivityType;*/
		activityDefinition.procDefName=task.getProcessDefinitionName();
		activityDefinition.procDefId=task.getProcessDefinitionId();
		return activityDefinition;
	}
	
	public ActivityDefinitionModel build(HistoricTaskInstance tempTask) {
		ActivityDefinitionModel activityDefinition=new ActivityDefinitionModel();
		HistoricTaskInstance task=null;
		if (tempTask == null)
			return activityDefinition;
		task=(HistoricTaskInstance) tempTask;
		activityDefinition.actDefId=task.getTaskDefinitionKey();
		String actDefName=task.getName();
		if (StringUtils.isEmpty(actDefName)) {
			actDefName = "结束";
		}
		activityDefinition.actDefName=actDefName;
	/*	String destActivityType = (String) task.get
				.getProperty(WorkFlowContants.WF_ACTIVITY_TYPE_KEY);

		if (ProcessDefinitionUtils.isMultiInstance(activityImpl)) {// 是否多实例类型
			destActivityType = WorkFlowContants.WF_ACTIVITY_TYPE_MULTI_INSTANCE;
		}
		this.isMulti = ProcessDefinitionUtils.isMultiInstance(activityImpl);
		this.isAsync=pvmActivity.isAsync();
		this.activityType = destActivityType;*/
		activityDefinition.procDefId=task.getProcessDefinitionId();
		activityDefinition.procDefName=task.getProcessDefinitionName();
		return activityDefinition;
	}


	public String getProcDefId() {
		return procDefId;
	}


	public void setProcDefId(String procDefId) {
		this.procDefId = procDefId;
	}


	public String getProcDefName() {
		return procDefName;
	}


	public void setProcDefName(String procDefName) {
		this.procDefName = procDefName;
	}


	public String getActDefId() {
		return actDefId;
	}


	public void setActDefId(String actDefId) {
		this.actDefId = actDefId;
	}


	public String getActDefName() {
		return actDefName;
	}


	public void setActDefName(String actDefName) {
		this.actDefName = actDefName;
	}


	public String getDescription() {
		return description;
	}


	public void setDescription(String description) {
		this.description = description;
	}


	public int getPriority() {
		return priority;
	}


	public void setPriority(int priority) {
		this.priority = priority;
	}


	public String getActType() {
		return actType;
	}


	public void setActType(String actType) {
		this.actType = actType;
	}


	public boolean isMulti() {
		return isMulti;
	}


	public void setMulti(boolean isMulti) {
		this.isMulti = isMulti;
	}


	public boolean isAsync() {
		return isAsync;
	}


	public void setAsync(boolean isAsync) {
		this.isAsync = isAsync;
	}


	public ActivityInfoConfig getActivityInfoConfig() {
		return activityInfoConfig;
	}


	public void setActivityInfoConfig(ActivityInfoConfig activityInfoConfig) {
		this.activityInfoConfig = activityInfoConfig;
	}


	public Map<String, Object> getVariables() {
		return variables;
	}


	public void setVariables(Map<String, Object> variables) {
		this.variables = variables;
	}


	public boolean isNotSelectReceiver() {
		return isNotSelectReceiver;
	}


	public void setNotSelectReceiver(boolean isNotSelectReceiver) {
		this.isNotSelectReceiver = isNotSelectReceiver;
	}


	public List<ActivityResourceModel> getActivityResources() {
		return activityResources;
	}


	public void setActivityResources(List<ActivityResourceModel> activityResources) {
		this.activityResources = activityResources;
	}
	public String toString() {
		return ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE);
	}
	

}
