function cloneObj (obj) {
    var str;
    var newObj = obj.constructor === Array ? [] : {};
    if (typeof obj !== 'object') {
        return;
    } else if (JSON) {
        str = JSON.stringify(obj);  //系列化对象
        newObj = JSON.parse(str);   //还原
    } else {
        for (var i in obj) {
            newObj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i];
        }
    }
    return newObj;
}

/**
 * 删除线时,更新对应起始环节的poin_lineCount(以它起始的线的总数)和poin_cacheIndexs(缓存被删除的线的id _TR后索引值)
 * @param {transId} 线id 
 * @param {elementRegistry} 通过它的get方法来获取图形信息 
 */
function deleteConnection(transId, elementRegistry) {
    if (!transId || (typeof transId === 'string' && transId.indexOf('_TR') === -1)) {
        return;
    }
    if (transId.indexOf('_TR_') > -1) {
        const actId = transId.split('_TR_')[0];
        const index = Number(transId.split('_TR_')[1]);
        const actEl = elementRegistry.get(actId);
        if (!actEl) {
            return;
        }
        // 删除的为最后一条线,则只要更新poin_lineCount即可
        if (index + 1 === actEl.poin_lineCount) {
            actEl.poin_lineCount--;
        } else {
            // 删除的为中间某些线,不更新poin_lineCount,缓存删除的Index,再生成线时优先从cacheIndexs中取数
            if (actEl.poin_cacheIndexs) {
                let poin_cacheIndexs = actEl.poin_cacheIndexs
                if (index < poin_cacheIndexs[0]) {
                    poin_cacheIndexs.unshift(index)
                } else if (index > poin_cacheIndexs[poin_cacheIndexs.length - 1]) {
                    poin_cacheIndexs.push(index)
                } else {
                    const cacheIndex = poin_cacheIndexs.findIndex(item => item > index)
                    if (cacheIndex > -1) {
                        poin_cacheIndexs.splice(cacheIndex, 0, index)
                    }
                }
            } else {
                actEl.poin_cacheIndexs = [index];
            }
        }
    } else {
        const actEl = elementRegistry.get(transId.split('_TR')[0]);
        if (!actEl) {
            return;
        }
        // 删除的为第一条线
        // 只有这一条线,则只要更新poin_lineCount即可
        if (1 === actEl.poin_lineCount) {
            //delete actEl.poin_lineCount;
            actEl.poin_lineCount = 0;
        } else {
            // 不只有这一条线,需要缓存这个index
            if (actEl.poin_cacheIndexs) {
                actEl.poin_cacheIndexs.unshift(0)
            } else {
                actEl.poin_cacheIndexs = [0];
            }
        }
    }
}

const bpmn = {
    state: {
        //环节编辑打开和关闭状态
    	nodeVisible: false,
    	//2021-10-15用于批量编排环节查看弹框打开和关闭状态
    	nodeLook:false,
    	//环节自身信息
        nodeInfo: {},
        //modeler实例 用来获取modeling(更新节点信息用的)和elementRegistry(根据id获取节点图形对象用的)
        bpmnModeler:null,
        //任务流程数据
        taskJson:{
            "unitFlag":"",
        	"id":"",
        	"flowId":"",
        	"flowDesc":"",
        	"flowCron":"",
        	"addTime":"",
        	"updateTime": null,
        	"author":"",
        	"jobGroup":"",
        	"lastVersion": "",
        	"flowXmlData":"",//xml数据
        	"flowNodeData":[],//环节数据
        	"connects":[],//add by lujing2021-07-09 批量线分支sequenceFlowId-json数据
        	"fileCoordFlag": 0,
	    	"fileCron": "",
	    	"filePath": "",
	    	"fileBean": "",
	    	"alarmNumLimit": "",//告警次数add by 陆静2021-09-15
	    	"expectExecuteTimes": "",//耗时add by 陆静2021-09-15
	    	"flowBlackDate":"",// 黑名单 by ynj2021-12-02
		"temporaryFlag":0,// 是否临时任务add by myl 2021-12-1
	    	"deadTime":"",
	    	"flowParam": "" //流程参数
        },
        //工作流程图保存数据  bpmn-xml 和表单数据
        bpmnJson: {
        	"packageId":"",
            "bpmnData":"",
            "formData":{
                "id":"",
                "name":"",
                "createDate":"",
                "proPriority":"5",
                "proDescription":"",
                "author":"",
                "todoCenter":"0",
        	    "msgCenter":"0",
                "wfpEventListener":[],
                "remindProcessInfo":{
                    "remindTimeD":"",
                    "remindTimeH":"",
                    "remindTimeM":"",
                    "remindTimeS":"",
                    "remindEmailWay":"",
                    "remindMessageWay":"",
                    "remindCalendar":"0",
                    "remindCount":"",
                    "remindRateD":"",
                    "remindRateH":"",
                    "remindRateM":"",
                    "remindRateS":"",
                    "remindStarter":"",
                    "remindAll":""
                },
                "formName":"",
                "pojoName":"",
                "proData":[],
                "participant":[],
                "transList":[],
                "autoInterfaces":[],
                "actList":[]
            }
        }
    },
    mutations: {
        TOGGLENODEVISIBLE: (state, visible) => {
            state.nodeVisible = visible
        },
        TOGGLENODELOOK: (state, visible) => {
            state.nodeLook = visible
        },
        SETNODEINFO: (state, info) => {
            state.nodeInfo = info
        },
        SETBPMNMODELER: (state, info) => {
            state.bpmnModeler = info
        },
        // add by lidan @2020-05-09
        SETBPMNJSON: (state, info) => {
            state.bpmnJson = info
        },
        SET_BPMN_DATA: (state, data) => {
            state.bpmnJson.bpmnData = data
        },
        //增加发布流程 选择版本号传递给后台
        SETPACKAGEID: (state, info) => {
            state.bpmnJson.packageId = info
        },
        // 基本信息 - 基本信息
        SET_BASE_INFO: (state, info) => {
            const formData = state.bpmnJson.formData;
            formData.id = info.id;
            formData.name = info.name;
            formData.createDate = info.createDate;
            formData.proPriority = info.proPriority;
            formData.proDescription = info.proDescription;
            formData.author = info.author;
            formData.todoCenter = info.todoCenter?info.todoCenter:'0';
            formData.msgCenter = info.msgCenter?info.msgCenter:'0';
        },
        // 基本信息 - 触发事件
        SET_ACTIVITY_TRIGGER: (state, data) => {
            state.bpmnJson.formData.wfpEventListener = [];
            const wfpEventListener = state.bpmnJson.formData.wfpEventListener;
            data.wfpEventListener.forEach(item => {
                wfpEventListener.push({
                    "dataId": item.dataId,
			        "clsPath": item.clsPath
                })
            })
            state.bpmnJson.formData.remindProcessInfo = JSON.parse(JSON.stringify(data.remindProcessInfo));
        },
        // 基本信息 - 流程相关
        SET_RELATIVE_INTERFACE: (state, data) => {
            const formData = state.bpmnJson.formData;
            formData.formName = data.formName;
            formData.pojoName = data.pojoName;
            formData.proData = [];
            data.proData.forEach(item => {
                formData.proData.push({
                    "id": item.id,
                    "name": item.name,
                    "type": item.type,
                    "length": item.length,
                    "isArray": item.isArray,
                    "initValue": item.initValue
                })
            })
        },
        // 接口定义
        SET_AUTO_INTERFACES: (state, data) => {
            state.bpmnJson.formData.autoInterfaces = [];
            const autoInterfaces = state.bpmnJson.formData.autoInterfaces;
            if (data instanceof Array) {
                data.forEach(item => {
                    if (item.children && item.children instanceof Array) {
                        item.children.forEach(childrenItem => {
                            const info = JSON.parse(JSON.stringify(childrenItem.info));
                            delete info['type'];
                            delete info['origName'];
                            info['autoFormList'] = [];
                            if (childrenItem.data && childrenItem.data.length > 0) {
                                childrenItem.data.forEach(listItem => {
                                    info['autoFormList'].push({
                                        "name": listItem.name,
                                        "javaType": listItem.javaType,
                                        "inoutType": listItem.inoutType,
                                        "param": listItem.param,
                                        "scope": listItem.scope
                                    })
                                })
                            }
                            autoInterfaces.push({
                                type: item.type,
                                info: info
                            });
                        })
                    }
                })
            }
        },
        //环节信息保存
        SET_ACTLIST: (state, data) => {
           let actList = state.bpmnJson.formData.actList;
        	//环节的表单数据保存到工作流对象中。=
     	   if(data.oldData != null){
     	      //修改原有数据
     		  actList[actList.findIndex(item => JSON.stringify(item) === JSON.stringify(data.oldData))] = cloneObj(data.newData)
     	     }else{
     	        //添加新数据
     	    	actList.push(cloneObj(data.newData));
     	     }

               // 如果id发生变化,要修改以他开头的线和以他结尾的线
            if ((!data.oldData || data.newData.id != data.oldData.id) && state.nodeInfo.businessObject) {
                const transList = state.bpmnJson.formData.transList;
                const modeling = state.bpmnModeler.get('modeling');
                const elementRegistry = state.bpmnModeler.get('elementRegistry');
                // 以他开头的线们
                if (state.nodeInfo.businessObject.outgoing) {
                    state.nodeInfo.businessObject.outgoing.forEach(item => {
                        const transListIndex = transList.findIndex(listItem => listItem.id === item.id);
                        if (transListIndex > -1) {
                            const idArr = item.id.split('_TR');
                            const TRIndex = idArr.length -  1;
                            const newId = data.newData.id + '_TR' + idArr[TRIndex];
                            // 更新vuex中线的id,from
                            transList[transListIndex].id = newId;
                            transList[transListIndex].from = data.newData.id;
                            // 更新线的id和source
                            modeling.updateProperties(elementRegistry.get(item.id),{
                                id: newId,
                                source: state.nodeInfo
                            });
                        }
                    })
                }

                // 以他结尾的线们
                if (state.nodeInfo.businessObject.incoming) {
                    state.nodeInfo.businessObject.incoming.forEach(item => {
                        const transListIndex = transList.findIndex(listItem => listItem.id === item.id);
                        if (transListIndex > -1) {
                            // 更新vuex中线的to
                            transList[transListIndex].to = data.newData.id;
                            // 更新线的target
                            modeling.updateProperties(elementRegistry.get(item.id), { target: state.nodeInfo });
                        }
                    })
                }
            }
        },
        //泳道信息保存participant
        SET_PARTICIPANT: (state, data) => {
        	let participant = state.bpmnJson.formData.participant;
        	//泳道数据保存到工作流对象中
        	if(data.oldData != null){
        		//修改原有数据
        		participant[participant.findIndex(item => JSON.stringify(item) === JSON.stringify(data.oldData))] = cloneObj(data.newData)
        	}else{
        		//添加新数据
        		participant.push(cloneObj(data.newData));
        	}
        },
      //迁移线信息保存transList
      SET_TRANSLIST: (state, data) => {
        	let transList = state.bpmnJson.formData.transList;
        	//迁移线数据保存到工作流对象中
        	if(data.oldData != null){
        		//修改原有数据
        		transList[transList.findIndex(item => JSON.stringify(item) === JSON.stringify(data.oldData))] = cloneObj(data.newData)
        	}else{
        		//添加新数据
        		transList.push(cloneObj(data.newData));
        	}
        },
        //环节删除
        DEL_ACTLIST: (state, data) => {
        	let transList = state.bpmnJson.formData.transList;
        	let actList = state.bpmnJson.formData.actList;
        	//环节删除
        	actList.splice(data.index,1);
        	//环节关联的线
        	// transList.forEach((item,index)=> {
        	// 	if(item.from == data.id || item.to == data.id){
        	// 		transList.splice(index,1);
        	// 	}
        	// })
        },
        //泳道删除
        DEL_PARTICIPANT: (state, data) => {
        	//data 泳道的id和数组索引
        	let participants = state.bpmnJson.formData.participant;
        	let transList = state.bpmnJson.formData.transList;
        	let actList = state.bpmnJson.formData.actList;
        	//根据索引删除泳道
        	participants.splice(data.index,1);
        	
        	actList.forEach((x,xindex)=> {
        		//环节所属泳道
        		if(x.performer == data.id){
        			//删除环节
        			actList.splice(xindex, 1);
        			//环节关联的线
        			// transList.forEach((y,yindex)=> {
        			// 	if(y.from == x.id || y.to == x.id){
        			// 		transList.splice(yindex,1);
        			// 	}
        			
        			// })
        		}
        	})
        },
        //迁移线信息删除
        DEL_TRANSLIST: (state, data) => {
            if (state.bpmnJson.formData.transList.length && state.bpmnJson.formData.transList.length > data) {
                const transId = state.bpmnJson.formData.transList[data].id
                if (transId) {
                    // 更新线之前环节的poin_lineCount和poin_cacheIndexs
                    deleteConnection(transId, state.bpmnModeler.get('elementRegistry'))
                }
            }
        	state.bpmnJson.formData.transList.splice(data,1);
        },
        // 删除环节的同时,删除其前后的线数据,actEL为环节图形对象
        DEL_ACT_TRANS: (state, actEl) => {
            if (!actEl) {
                return;
            }
            const elementRegistry = state.bpmnModeler.get('elementRegistry');
            if (actEl.incoming) {
                // 仅当该环节前后都只有一条线时,会删除其后线的数据,它之前的线的数据 (bpmn:SequenceFlow)更新
                if (actEl.incoming.length === 1 && actEl.outgoing && actEl.outgoing.length === 1 && 'bpmn:SequenceFlow' === actEl.incoming[0].type) {
                    const transIndex = state.bpmnJson.formData.transList.findIndex(titem => titem.id === actEl.incoming[0].id);
                    if (transIndex > -1) {
                        state.bpmnJson.formData.transList[transIndex].to = actEl.outgoing[0].target.id;
                    }
                } else {
                    // 其他情况,前面的线都应该删除,并更新线前面环节的poin_lineCount和poin_cacheIndexs
                    actEl.incoming.forEach(item => {
                        const transIndex = state.bpmnJson.formData.transList.findIndex(titem => titem.id === item.id)
                        if (transIndex > -1) {
                            state.bpmnJson.formData.transList.splice(transIndex ,1)
                        }
                        deleteConnection(item.id, elementRegistry)
                    });
                }
            }
            // 只要有后面的线,就应该删除,无需更新线前面环节的信息,因为已经被删除
            if (actEl.outgoing) {
                actEl.outgoing.forEach(item => {
                    const transIndex = state.bpmnJson.formData.transList.findIndex(titem => titem.id === item.id)
                    if (transIndex > -1) {
                        state.bpmnJson.formData.transList.splice(transIndex,1)
                    }
                });
            }
        },
        //任务流程保存数据
        SET_TASK_JSON: (state, info) => {
            state.taskJson = info
        },
        //保存任务流程 xml数据
        SET_TASK_XML:(state, data) => {
            state.taskJson.flowXmlData = data
        },
       //保存任务流程-[创建任务]环节flowNodeData
        SET_FLOWNODEDATA: (state, data) => {
        	let flowNodeData = state.taskJson.flowNodeData;
        	//flowNodeData数据保存到工作流对象中
        	if(data.oldData != null){
        		//修改原有数据
        		flowNodeData[flowNodeData.findIndex(item => JSON.stringify(item) === JSON.stringify(data.oldData))] = cloneObj(data.newData)
        	}else{
        		//添加新数据
        		flowNodeData.push(cloneObj(data.newData));
        	}
        },
        //保存任务基本信息数据
        SET_TASK_BASEDATA: (state, data) => {
            state.taskJson.unitFlag = data.unitFlag;
        	state.taskJson.flowId = data.flowId;
        	state.taskJson.jobGroup = data.jobGroup;
        	state.taskJson.flowDesc = data.flowDesc
        	state.taskJson.flowCron = data.flowCron
        	state.taskJson.addTime = data.addTime
        	state.taskJson.author = data.author
        	//增加字段add by 陆静2021-07-12
        	state.taskJson.fileCoordFlag = data.fileCoordFlag
        	state.taskJson.fileCron = data.fileCron
        	state.taskJson.filePath = data.filePath
        	state.taskJson.fileBean = data.fileBean
        	//增加字段add by 陆静2021-09-15
        	state.taskJson.alarmNumLimit = data.alarmNumLimit
        	state.taskJson.expectExecuteTimes = data.expectExecuteTimes
        	//黑名单字段add by ynj2021-12-02
        	state.taskJson.flowBlackDate = data.flowBlackDate
        	//add by myl 2021-12-1
        	state.taskJson.deadTime = data.deadTime
        	state.taskJson.temporaryFlag = data.temporaryFlag
        	//增加字段 by fyz 2022-4-12
        	state.taskJson.flowParam = data.flowParam
        },
       //删除任务环节数据
        DEL_NODEDATA:(state, data)=>{
          state.taskJson.flowNodeData.splice(data,1)
        }
        
    },
    actions: {

    }
}

export default bpmn