/*
 * 该类主要负责系统主要业务逻辑的实现,如多表处理的事务操作、权限控制等
 * 该类根据具体的业务逻辑来调用该实体对应的Dao或者多个Dao来实现数据库操作
 * 实际的数据库操作在对应的Dao或其他Dao中实现
 */
 
package com.blueland.bpm.engine.config.service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.RepositoryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.blueland.bpm.common.base.BaseManager;
import com.blueland.bpm.common.base.EntityDao;
import com.blueland.bpm.common.page.Page;
import com.blueland.bpm.engine.config.dao.ActivityInfoConfigDao;
import com.blueland.bpm.engine.config.model.ActivityInfoConfig;
import com.blueland.bpm.engine.config.model.ActivityOperatePower;
import com.blueland.bpm.engine.core.model.ProcessDefinitionModel;
import com.blueland.bpm.engine.core.service.ProcessDefinitionService;
import com.blueland.bpm.engine.core.service.ProcessModelService;
import com.blueland.bpm.engine.util.WorkFlowException;

/**
 * @author lw
 * @version 1.0
 * @since  
 */

@Service
public class ActivityInfoConfigManager extends BaseManager<ActivityInfoConfig,String>{
	@Autowired
	//ActivityInfoConfig对应的DAO类,主要用于数据库的增删改查等操作
	private ActivityInfoConfigDao activityInfoConfigDao;
	@Autowired
	private ActivityOperatePowerManager activityOperatePowerManager;
	@Autowired
	private ProcessDefinitionService processDefinitionService;
	@Autowired
	private ProcessModelService processModelService;

	public EntityDao getEntityDao() {
		return this.activityInfoConfigDao;
	}
	//分页查询
	public Page findPage(ActivityInfoConfig query) {
		return activityInfoConfigDao.pageQuery(query);
	}
	/*public void updateAndFlush(ActivityInfoConfig entity){
		if(StringUtils.isEmpty(entity.getActivityStatusName())){
			entity.setActivityStatusName(entity.getActivityDefName());
		}
		activityInfoConfigDao.update(entity);
		if(comparisonActvity(entity)){
			//获取最新版本的流程定义
			BpmnModel bpmnModel=processModelService.getBpmnModelByProcDefId(entity.getProcessDefId());
			UserTask userTask=findAct(bpmnModel,entity.getActivityDefId());
			userTask.setName(entity.getActivityDefName());
			//获取最新版本的流程定义
			ProcessDefinitionModel proceDefModel=processDefinitionService.getProcessDef(entity.getProcessDefId());
			//更新bpmn.xml
			processDefinitionService.updateDeploymentResource(proceDefModel.getDeploymentId(),proceDefModel.getProcessDefinitionId(),processModelService.convertBpmnModelToByte(bpmnModel,proceDefModel.getProcessDefinitionId()),true);
			//更新流程定义缓存
			processDefinitionService.refreshProcessDefineCache(proceDefModel.getProcessDefinitionId());
		}
		
	}*/
	public void update(ActivityInfoConfig entity){
		if(StringUtils.isEmpty(entity.getActivityStatusName())){
			entity.setActivityStatusName(entity.getActivityDefName());
		}if(StringUtils.isEmpty(entity.getActivityDefType())){
			entity.setActivityDefType(BpmnXMLConstants.ELEMENT_TASK_USER);
		}
		activityInfoConfigDao.update(entity);
	}
	private UserTask findAct(BpmnModel bpmnModel,String actId){
		//List userList=new ArrayList();
		UserTask userTask = null;
		if (bpmnModel == null) {
			return userTask;
		}
		FlowElement flowElement=bpmnModel.getFlowElement(actId);
		if(flowElement==null){
			return userTask;
		}
		if (!UserTask.class.isInstance(flowElement)) {
			return userTask;
		}
		userTask = (UserTask) flowElement;
		return userTask;
	}
	private boolean comparisonActvity(ActivityInfoConfig params){
		ActivityInfoConfig entity=this.getActivityInfoConfig(params.getProcessDefId(),params.getActivityDefId());
		if(!params.getActivityDefName().equals(entity.getActivityDefName())){
			return true;
		}
		return false;
	}
	public void save(ActivityInfoConfig entity){
		if(StringUtils.isEmpty(entity.getActivityStatusName())){
			entity.setActivityStatusName(entity.getActivityDefName());
		}
		if(StringUtils.isEmpty(entity.getActivityDefChildType())){
			entity.setActivityDefChildType(ActivityInfoConfig.ACTIVITY_DEF_CHILD_TYPE_INSIDE);
		}if(StringUtils.isEmpty(entity.getIdeaDisplayArea())){
			entity.setActivityDefChildType(ActivityInfoConfig.ACTIVITY_DEF_CHILD_TYPE_INSIDE);
		}
		activityInfoConfigDao.save(entity);
	}
	public ActivityInfoConfig getActivityInfoConfig(String procDefId,
			String activityDefId) throws WorkFlowException {
		ActivityInfoConfig param=new ActivityInfoConfig();
		param.setActivityDefId(activityDefId);
		param.setProcessDefId(procDefId);
		return activityInfoConfigDao.getByEntity(param);
	}
	
	public List<ActivityInfoConfig> findActivityInfoConfigs(String procDefId) throws WorkFlowException {
		ActivityInfoConfig param=new ActivityInfoConfig();
		param.setProcessDefId(procDefId);
		return activityInfoConfigDao.findByExample(param);
	}
	
	public boolean deleteActivityInfoConfigs(String procDefId) throws WorkFlowException {
		ActivityInfoConfig param=new ActivityInfoConfig();
		param.setProcessDefId(procDefId);
		return this.activityInfoConfigDao.getSqlSessionTemplate().delete(this.activityInfoConfigDao.getIbatisMapperNamesapce()+".deleteActivityInfoConfigs", param)>0;
	}
	
	
	public List<ActivityOperatePower> findActivityOperatePower(String procDefId,
			String activityDefId) throws WorkFlowException {
		List<ActivityOperatePower> activityOperatePowers=null;
		ActivityInfoConfig param=getActivityInfoConfig(procDefId,activityDefId);
		String operationRoleId=param.getActivityOperationRoleid();
		if(operationRoleId==null){
			return activityOperatePowers;
		}
		String[] operationRoleIds=null;
		if(operationRoleId.indexOf(";")!=-1){
			operationRoleIds=operationRoleId.split(";");
		}else{
			operationRoleIds=new String[]{operationRoleId};
		}
		activityOperatePowers=activityOperatePowerManager.findActivityOperatePowerByIds(Arrays.asList(operationRoleIds), "", "");
		return activityOperatePowers;
	}
	
	public boolean addActivityOperatePower(List<String>  opIds,String processDefId,
			String activityDefId)  {
		if(opIds==null||opIds.isEmpty()){
			return false;
		}
		ActivityInfoConfig activityInfoConfig=getActivityInfoConfig(processDefId,activityDefId);
		String activityOperationRoleid=activityInfoConfig.getActivityOperationRoleid();
		String[] existOpIds=null;
		if(StringUtils.isNotEmpty(activityOperationRoleid)){
			if(activityOperationRoleid.indexOf(";")!=-1){
				existOpIds=activityOperationRoleid.split(";");
			}else{
				existOpIds=new String[]{activityOperationRoleid};
			}
			
			for (int i=0;i<opIds.size();i++) {
				for (String  existOpId : existOpIds) {
					if(existOpId.equals(opIds.get(i))){
						opIds.remove(i);
						i--;
						break;
					}
				}
			}
		}
		if(opIds.isEmpty()){
			return false;
		}
		if(existOpIds!=null){
			opIds.addAll(Arrays.asList(existOpIds));
		}
		String allOpId=convertAllOpIds(opIds);
		activityInfoConfig.setActivityOperationRoleid(allOpId);
		activityInfoConfigDao.update(activityInfoConfig);
		
		return true;
	}
	
	public boolean removeActivityOperatePower(List<String>  opIds,String processDefId,
			String activityDefId)  {
		if(opIds==null||opIds.isEmpty()){
			return false;
		}
		ActivityInfoConfig activityInfoConfig=getActivityInfoConfig(processDefId,activityDefId);
		String[] existOpIds=null;
		if(activityInfoConfig.getActivityOperationRoleid().indexOf(";")!=-1){
			existOpIds=activityInfoConfig.getActivityOperationRoleid().split(";");
		}else{
			existOpIds=new String[]{activityInfoConfig.getActivityOperationRoleid()};
		}
		List<String> existOpIdList=new ArrayList<String>();
		existOpIdList.addAll(Arrays.asList(existOpIds));
		for (int i=0;i<existOpIdList.size();i++) {
			for (String  opId : opIds) {
				if(existOpIdList.get(i).equals(opId)){
					existOpIdList.remove(i);
					i--;
					break;
				}
			}
		}
		String allOpId=convertAllOpIds(existOpIdList);
		activityInfoConfig.setActivityOperationRoleid(allOpId);
		activityInfoConfigDao.update(activityInfoConfig);
		
		return true;
	}
	
	public void remove(String processDefId,String activityDefId) {
		Map params=new HashMap();
		params.put("processDefId", processDefId);
		params.put("activityDefId", activityDefId);
		this.activityInfoConfigDao.getSqlSessionTemplate().delete(this.activityInfoConfigDao.getIbatisMapperNamesapce()+".delete", params);
	}

	
	private String convertAllOpIds(List<String> list){
		String allOpId="";
		for (String opId : list) {
			allOpId+=opId+";";
		}
		if(!allOpId.equals("")){
			allOpId=allOpId.substring(0,allOpId.lastIndexOf(";"));
		}
		return allOpId;
	}
	public void updateByProcessDefName(String processDefId,String processDefName){
		Map params=new HashMap();
		params.put("processDefId", processDefId);
		params.put("processDefName", processDefName);
		this.activityInfoConfigDao.getSqlSessionTemplate().delete(this.activityInfoConfigDao.getIbatisMapperNamesapce()+".updateByProcessDefName", params);
	}
	
	
}
