package com.njcn.product.advance.eventSource.utils;


import com.njcn.product.advance.eventSource.pojo.dto.eventAggregate.*;

public class UtilNormalization {
	public static void matrixcata_pro(EntityLogic[] transformer, EntityMtrans entityMtrans, int len) {
		int i, j, k;
		int node1, node2, con;
		int src_node[] = new int[] { 0 };

		// 连接方式转化为矩阵形式，行、列表示所有节点
		// inf表示两个节点不相连，0表示与自身相连，其他数值表示变压器连接类型
		// 将初始矩阵的元素设为inf,对角线元素设为0
		for (i = 0; i < FinalData.NODE_NUM; i++) {
			for (j = 0; j < FinalData.NODE_NUM; j++) {
				entityMtrans.getMtrans()[i][j] = FinalData.DATA_INF;
			}
			entityMtrans.getMtrans()[i][i] = 0;
		}
		// 根据transformer设置元素
		for (i = 0; i < len; i++) {
			node1 = transformer[i].getNode_h();
			node2 = transformer[i].getNode_l();
			con = transformer[i].getType();
			entityMtrans.getMtrans()[node1 - 1][node2 - 1] = con;
			entityMtrans.getMtrans()[node2 - 1][node1 - 1] = con;
		}
		StringBuilder str = new StringBuilder();
		for (i = 0; i < FinalData.NODE_NUM; i++) {
			for (j = 0; j < FinalData.NODE_NUM; j++) {
				str.append(entityMtrans.getMtrans()[i][j]).append(" ");
				if (j == (FinalData.NODE_NUM - 1))
					str.append("\r\n");
			}
		}

		// 类型匹配矩阵Matrixcata
		// Matrixcata模式匹配矩阵，列为节点数，行为总类别数，元素为第一个节点分别是1-6类别情况下其他节点类别情况。
		// 元素1,2,3，4,5,6 分别对应 Dc,Cb,Da,Cc,Db,Ca
		// 设置矩阵第一行元素
		for (i = 0; i < FinalData.NODE_NUM; i++)
			entityMtrans.getMatrixcata0()[0][i] = 0;
		for (i = 1; i < FinalData.NODE_NUM; i++) {
			// 路径缓存清空
			for (j = 0; j < FinalData.MAX_PATH_NUM; j++) {
				for (k = 0; k < (FinalData.NODE_NUM + 1); k++)
					entityMtrans.getPossiable_path()[j][k] = 0;
			}
			entityMtrans.setPath_num(0);
			// 寻找路径
			src_node[0] = 0;
			findPath(entityMtrans, src_node, i, 0, 1, FinalData.NODE_NUM);
			if (entityMtrans.getPath_num() != 0)
				entityMtrans.getMatrixcata0()[0][i] = entityMtrans.getPossiable_path()[0][FinalData.NODE_NUM]; // 采用第一条路径
			else
				entityMtrans.getMatrixcata0()[0][i] = FinalData.DATA_INF; // 找不到路径填大值表示不通
		}
		// 构造矩阵其他行元素
		for (i = 1; i < FinalData.EVT_TYPE_NUM; i++) {
			for (j = 0; j < FinalData.NODE_NUM; j++)
				// EntityGroupData.Matrixcata0[i][j] =
				// EntityGroupData.Matrixcata0[0][j] + i;
				if (entityMtrans.getMatrixcata0()[0][j] == FinalData.DATA_INF) {
					entityMtrans.getMatrixcata0()[i][j] = FinalData.DATA_INF;
				} else {
					entityMtrans.getMatrixcata0()[i][j] = entityMtrans.getMatrixcata0()[0][j] + i;
				}
		}
		// 将数据归类到0-5
		for (i = 0; i < FinalData.EVT_TYPE_NUM; i++) {
			for (j = 0; j < FinalData.NODE_NUM; j++)
				entityMtrans.getMatrixcata1()[i][j] = entityMtrans.getMatrixcata0()[i][j] % 6;
		}
		// 0换成6，将数据归类到1-6
		for (i = 0; i < FinalData.EVT_TYPE_NUM; i++) {
			for (j = 0; j < FinalData.NODE_NUM; j++) {
				if (entityMtrans.getMatrixcata1()[i][j] == 0)
					entityMtrans.getMatrixcata1()[i][j] = 6;
			}
		}
		str.delete(0, str.length());
		for (i = 0; i < FinalData.EVT_TYPE_NUM; i++) {
			for (j = 0; j < FinalData.NODE_NUM; j++) {
				str.append(entityMtrans.getMatrixcata1()[i][j]).append(" ");
				if (j == (FinalData.NODE_NUM - 1))
					str.append("\r\n");
			}
		}

	}

	public static int findPath(EntityMtrans entityMtrans, int[] OriginalNode, int destination, int Weight, int src_num, int node_num) // 深度优先搜索
	{
		int i, j;
		int last_node;
		int nextNodes[] = new int[FinalData.NODE_NUM];
		int nextNode_num = 0;
		int nextNodes0[] = new int[FinalData.NODE_NUM];
		int nextNode_num0 = 0;
		int tmpPath[] = new int[FinalData.NODE_NUM + 1];
		int tmpPath_num;
		if (src_num < 1) // 源节点个数不对
			return 1;
		last_node = OriginalNode[src_num - 1];
		if (last_node > node_num) // 判断最后一个节点号是否在范围内
			return 1;
		for (i = 0; i < node_num; i++) {
			// if((Mtrans[last_node][i]>0)&&(Mtrans[last_node][i]<DATA_INF))
			// //寻找相同的节点
			if (entityMtrans.getMtrans()[last_node][i] > 0) // 寻找相同的节点
			{
				nextNodes[nextNode_num] = i;
				nextNode_num++;
			}
		}
		// 如果一条路的最后一个节点就是目标节点，说明此路径是所有路径中的一条，可以直接return
		if (last_node == destination) {
			if (entityMtrans.getPath_num() >= FinalData.MAX_PATH_NUM)
				return 1;
			for (i = 0; i < src_num; i++)
				entityMtrans.getPossiable_path()[entityMtrans.getPath_num()][i] = OriginalNode[i];
			entityMtrans.getPossiable_path()[entityMtrans.getPath_num()][FinalData.NODE_NUM] = Weight; // 最后一个节点填入变压器连接
			entityMtrans.setPath_num(entityMtrans.getPath_num() + 1);
		} else {
			for (i = 0; i < src_num; i++) {
				if (destination == OriginalNode[i])
					return 1;
			}
		}
		// 判断下一个节点有没有目的节点
		for (i = 0; i < nextNode_num; i++) {
			if (nextNodes[i] == destination) {
				// 先清零;
				for (j = 0; j < (FinalData.NODE_NUM + 1); j++)
					tmpPath[j] = 0;
				// 填入源节点
				for (j = 0; j < src_num; j++)
					tmpPath[j] = OriginalNode[j];
				tmpPath[src_num] = destination; // 目的节点加在后面
				tmpPath[FinalData.NODE_NUM] = Weight + entityMtrans.getMtrans()[last_node][destination]; // 最后一个点填入变压器累计
				tmpPath_num = src_num + 1;
				if (entityMtrans.getPath_num() >= FinalData.MAX_PATH_NUM)
					return 1;
				for (j = 0; j < (FinalData.NODE_NUM + 1); j++)
					entityMtrans.getPossiable_path()[entityMtrans.getPath_num()][j] = tmpPath[j]; // tmpPath为路径的路阻
				entityMtrans.setPath_num(entityMtrans.getPath_num() + 1);
				nextNodes[i] = 0;
				if (nextNode_num != 0) // if(nextNode_num)
					nextNode_num--;
			} else {
				// 判断如果源节点中有下一个节点，不再寻找处理
				for (j = 0; j < src_num; j++) {
					if (nextNodes[i] == OriginalNode[j]) {
						nextNodes[i] = 0;
					}
				}
			}
		}
		// 不是目的节点的下一节点继续寻找
		for (i = 0; i < nextNode_num; i++) {
			if (nextNodes[i] != 0) {
				nextNodes0[nextNode_num0] = nextNodes[i];
				nextNode_num0++;
			}
		}
		for (i = 0; i < nextNode_num0; i++) {
			// 填入源节点
			for (j = 0; j < src_num; j++)
				tmpPath[j] = OriginalNode[j];
			tmpPath[src_num] = nextNodes0[i]; // 下一个节点加在后面
			tmpPath_num = src_num + 1;
			findPath(entityMtrans, tmpPath, destination, (Weight + entityMtrans.getMtrans()[last_node][nextNodes0[i]]), tmpPath_num,
					node_num);
		}
		return 0;
	}

	public static int sort_Tstart(EntityGroupData buf) {
		int res_num, out_num;
		int idx = 0;
		if ((buf == null) || (buf.getEvt_in_num() == 0))
			return 0;
		res_num = buf.getEvt_in_num();
		while (res_num > 0) { // while(res_num)
			out_num = sort_Tstart_single(buf);
			// 输出缓冲填入归集缓冲
			// buf.getGrp_buf()[idx] = buf.getOut_buf();
			System.arraycopy(buf.getOut_buf(), 0, buf.getGrp_buf()[idx], 0, buf.getOut_buf().length);
			buf.getGrp_num()[idx] = out_num;
			// 未归集填入输入缓冲
			// buf.setIn_buf(buf.getRes_buf());
			System.arraycopy(buf.getRes_buf(), 0, buf.getIn_buf(), 0, buf.getRes_buf().length);
			buf.setEvt_in_num(buf.getEvt_res_num());
			idx++;
			if (idx >= FinalData.MAX_GROUP_NUM) // 分组超限
				break;
			if (out_num <= res_num)
				res_num = res_num - out_num;
			else
				break; // 分组数目超限
		}
		buf.setGrp_all_num(idx);
		return 1;
	}

	public static int sort_Tstart_single(EntityGroupData buf) {
		int i;
		int start_time;
		int thd_time1, thd_time2;
		if ((buf == null) || (buf.getEvt_in_num() == 0))
			return 0;
		buf.setEvt_out_num(0);
		buf.setEvt_res_num(0);
		// 如果只有一个事件直接赋值返回
		if (buf.getEvt_in_num() == 1) {
			buf.setEvt_out_num(1);
			// buf.getOut_buf()[0] = buf.getIn_buf()[0];
			// System.arraycopy(buf.getIn_buf()[0], 0, buf.getOut_buf()[0], 0,
			// 1);
			buf.getOut_buf()[0] = (EntityGroupEvtData) buf.getIn_buf()[0].objClone();
			return buf.getEvt_out_num();
		}
		start_time = buf.getIn_buf()[0].getStart_time();
		thd_time1 = start_time - FinalData.TIME_THRESHOLD;
		thd_time2 = start_time + FinalData.TIME_THRESHOLD;
		// 判断时标阀值门槛归集
		for (i = 0; i < buf.getEvt_in_num(); i++) {
			start_time = buf.getIn_buf()[i].getStart_time();
			// 在阈值范围内
			if ((start_time >= thd_time1) && (start_time <= thd_time2)) {
				// buf.getOut_buf()[buf.getEvt_out_num()] = buf.getIn_buf()[i];
				// System.arraycopy(buf.getIn_buf()[i], 0,
				// buf.getOut_buf()[buf.getEvt_out_num()], 0, 1);
				buf.getOut_buf()[buf.getEvt_out_num()] = (EntityGroupEvtData) buf.getIn_buf()[i].objClone();
				buf.setEvt_out_num(buf.getEvt_out_num() + 1);
			} else {
				// buf.getRes_buf()[buf.getEvt_res_num()] = buf.getIn_buf()[i];
				// System.arraycopy(buf.getIn_buf()[i], 0,
				// buf.getRes_buf()[buf.getEvt_res_num()], 0, 1);
				buf.getRes_buf()[buf.getEvt_res_num()] = (EntityGroupEvtData) buf.getIn_buf()[i].objClone();
				buf.setEvt_res_num(buf.getEvt_res_num() + 1);
			}
		}
		return buf.getEvt_out_num();
	}

	public static int sort_cata(EntityGroupData buf, int idx) {
		int i, j;
		int cata, node;
		int odrer[] = new int[FinalData.MAX_CATA_NUM + 2];
		// 针对类别是1-6的数据进行模式匹配，并标注属于哪一个模式

		for (i = 0; i < (FinalData.MAX_CATA_NUM + 2); i++)
			odrer[i] = 0;
		// 暂降类型转换
		// 将类型7,8,9转换为6,2,4
		// 其中7，8，9分别对应BC两相接地,AC两相接地,AB两相接地,1,2,3，4,5，6分别对应Dc,Cb,Da,Cc,Db,Ca
		/*
		 * for (i = 0; i < buf.getGrp_num()[idx]; i++) { if
		 * (buf.getGrp_buf()[idx][i].getCata() == 7)
		 * buf.getGrp_buf()[idx][i].setCata(6); if
		 * (buf.getGrp_buf()[idx][i].getCata() == 8)
		 * buf.getGrp_buf()[idx][i].setCata(2); if
		 * (buf.getGrp_buf()[idx][i].getCata() == 9)
		 * buf.getGrp_buf()[idx][i].setCata(4); }
		 */
		for (i = 0; i < buf.getGrp_num()[idx]; i++) {
			/*
			 * if (buf.getGrp_buf()[idx][i].getCata() == 10) //事件类型未知
			 * buf.getGrp_buf()[idx][i].setCata(11); if
			 * (buf.getGrp_buf()[idx][i].getCata() == 9) //三相
			 * buf.getGrp_buf()[idx][i].setCata(10);
			 */

			if (buf.getGrp_buf()[idx][i].getCata() == 0)
				buf.getGrp_buf()[idx][i].setCata(6);

			if (buf.getGrp_buf()[idx][i].getCata() == 6)
				buf.getGrp_buf()[idx][i].setCata(6);
			if (buf.getGrp_buf()[idx][i].getCata() == 7)
				buf.getGrp_buf()[idx][i].setCata(2);
			if (buf.getGrp_buf()[idx][i].getCata() == 8)
				buf.getGrp_buf()[idx][i].setCata(4);
		}

		// 将数据进行模式匹配，并标注属于哪一个模式
		for (i = 0; i < buf.getGrp_num()[idx]; i++) {
			cata = buf.getGrp_buf()[idx][i].getCata();
			node = buf.getGrp_buf()[idx][i].getNode();

			if ((node > FinalData.NODE_NUM) || (buf.getMatrixcata()[0][node - 1] == FinalData.DATA_INF)) {
				buf.getGrp_buf()[idx][i].setCata2(FinalData.QVVR_TYPE_OUTOFRANGE);
				// buf.getGrp_cata_buf()[idx][FinalData.MAX_CATA_NUM +
				// 1][odrer[FinalData.MAX_CATA_NUM + 1]] =
				// buf.getGrp_buf()[idx][i];
				// System.arraycopy(buf.getGrp_buf()[idx][i], 0,
				// buf.getGrp_cata_buf()[idx][FinalData.MAX_CATA_NUM +
				// 1][odrer[FinalData.MAX_CATA_NUM + 1]], 0, 1);
				buf.getGrp_cata_buf()[idx][FinalData.MAX_CATA_NUM + 1][odrer[FinalData.MAX_CATA_NUM
						+ 1]] = (EntityGroupEvtData) buf.getGrp_buf()[idx][i].objClone();
				odrer[FinalData.MAX_CATA_NUM + 1]++;
			} else if (cata == FinalData.QVVR_TYPE_UNKNOWN) {
				buf.getGrp_buf()[idx][i].setCata2(FinalData.QVVR_TYPE_UNKNOWN);
				// buf.getGrp_cata_buf()[idx][FinalData.MAX_CATA_NUM][odrer[FinalData.MAX_CATA_NUM]]
				// = buf.getGrp_buf()[idx][i];
				// System.arraycopy(buf.getGrp_buf()[idx][i], 0,
				// buf.getGrp_cata_buf()[idx][FinalData.MAX_CATA_NUM][odrer[FinalData.MAX_CATA_NUM]],
				// 0, 1);
				buf.getGrp_cata_buf()[idx][FinalData.MAX_CATA_NUM][odrer[FinalData.MAX_CATA_NUM]] = (EntityGroupEvtData) buf
						.getGrp_buf()[idx][i].objClone();
				odrer[FinalData.MAX_CATA_NUM]++;
			} else if (cata == FinalData.QVVR_TYPE_THREE) // ÈıÏàÔİ½µ¹éÀà
			{
				buf.getGrp_buf()[idx][i].setCata2(FinalData.QVVR_TYPE_THREE);
				// buf.getGrp_cata_buf()[idx][FinalData.MAX_CATA_NUM -
				// 1][odrer[FinalData.MAX_CATA_NUM - 1]] =
				// buf.getGrp_buf()[idx][i];
				// System.arraycopy(buf.getGrp_buf()[idx][i], 0,
				// buf.getGrp_cata_buf()[idx][FinalData.MAX_CATA_NUM -
				// 1][odrer[FinalData.MAX_CATA_NUM - 1]], 0, 1);
				buf.getGrp_cata_buf()[idx][FinalData.MAX_CATA_NUM - 1][odrer[FinalData.MAX_CATA_NUM
						- 1]] = (EntityGroupEvtData) buf.getGrp_buf()[idx][i].objClone();
				odrer[FinalData.MAX_CATA_NUM - 1]++;
			} else // 1-6类暂降归类
			{
				for (j = 0; j < FinalData.MAX_CATA_NUM; j++) {
					if (cata == buf.getMatrixcata()[j][node - 1])// 判断数据类别属于第几行
					{
						buf.getGrp_buf()[idx][i].setCata2(j + 1);
						// 进行归类
						// buf.getGrp_cata_buf()[idx][j][odrer[j]] =
						// buf.getGrp_buf()[idx][i];
						// System.arraycopy(buf.getGrp_buf()[idx][i], 0,
						// buf.getGrp_cata_buf()[idx][j][odrer[j]], 0, 1);
						buf.getGrp_cata_buf()[idx][j][odrer[j]] = (EntityGroupEvtData) buf.getGrp_buf()[idx][i]
								.objClone();
						odrer[j]++;
					}
				}
			}
		}
		for (i = 0; i < FinalData.MAX_CATA_NUM + 2; i++)
			buf.getGrp_cata_num()[idx][i] = odrer[i];
		return 0;
	}
}
