package com.persagy.cameractl.service.windows;

import java.awt.List;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.Thread.State;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.collections.map.HashedMap;
import org.bouncycastle.asn1.x509.NameConstraintValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dh.DpsdkCore.IDpsdkCore;
import com.dh.DpsdkCore.Login_Info_t;
import com.dh.DpsdkCore.dpsdk_protocol_version_e;
import com.dh.DpsdkCore.Return_Value_Info_t;
import com.dh.DpsdkCore.TaskChnlInfoEx_t;
import com.dh.DpsdkCore.TaskInfoEx_t;
import com.dh.DpsdkCore.WindowTaskInfoEx_t;
import com.dh.DpsdkCore.dpsdk_retval_e;
import com.dh.DpsdkCore.dpsdk_sdk_type_e;
import com.dh.DpsdkCore.dpsdk_stream_type_e;
import com.dh.DpsdkCore.TvWall.Set_TvWall_Screen_Window_Source_t;
import com.dh.DpsdkCore.TvWall.TvWall_Layout_Info_t;
import com.dh.DpsdkCore.TvWall.TvWall_List_Info_t;
import com.dh.DpsdkCore.TvWall.TvWall_Screen_Info_t;
import com.dh.DpsdkCore.TvWall.TvWall_Screen_Open_Window_t;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.dh.DpsdkCore.Ptz_Direct_Info_t;
import com.dh.DpsdkCore.Ptz_Operation_Info_t;
import com.dh.DpsdkCore.dpsdk_constant_value;
import com.persagy.cameractl.conf.AllStaticConfig;
import com.persagy.cameractl.utils.Camera;
import com.persagy.cameractl.utils.EnumTools;
import com.persagy.cameractl.utils.JsonTools;
import com.persagy.cameractl.utils.OtherTools;
import com.persagy.cameractl.utils.ResultClass;

public class DpsdkMainWindows {
	Logger logger = LoggerFactory.getLogger(DpsdkMainWindows.class);

	// 初始化得到的sdk句柄
	private static int m_nDLLHandle = -1;
	// dpsdklog目录
	private static String dpsdklog = "./logs/dpsdk/dpsdkjavalog";
	// dpsdk转存储目录
	private static String dumpfile = "./logs/dpsdk/dpsdkjavadump";

	/*
	 * 大屏的6种布局方式,分别是：
	 * 1、一个窗口		2、 左上角是大窗口(跨两行两列)的布局，共9个窗口		3、六个窗口，其中右下角窗口跨两行两列
	 * 4、六个窗口，其中右上角窗口跨两行两列		5、六个窗口，其中左下角窗口跨两行两列	6、九宫格
	 * */
	private static ArrayList<String> layoutNameList = new ArrayList<String>() {
		/**
		* 
		*/
		private static final long serialVersionUID = 1L;
		{
			add("one");
			add("left-up-one");
			add("right-down-one");
			add("right-up-one");
			add("left-down-one");
			add("multi-one");
		}
	};

	// 上一次布局的索引，即layoutNameList的索引
	private static int prevLayoutIndex = -1;

	// 上一次布局内的窗口的ID集合
	private static ArrayList<Integer> prevLayoutWinIdList = new ArrayList<Integer>();

	// 返回值信息
	Return_Value_Info_t nGroupLen = new Return_Value_Info_t();

	private Camera camera;

	public DpsdkMainWindows(Camera _camera) {
		camera = _camera;
	};

	/*
	 * 修改java.library.path的值
	 * */
	private boolean loadJNILibDynamically() {
//		try {
//			File directory = new File("./resourcesFile/cameraDll/windows/");
////			System.out.println(directory.getCanonicalPath());//获取标准的路径
//		    String absolutePath= directory.getCanonicalPath();
//			    
//		    String oldLibraryPath=System.getProperty("java.library.path");
//			String newLibraryPath=oldLibraryPath + ":"+absolutePath;
//			System.setProperty("java.library.path", newLibraryPath);
//			Field fieldSysPath = ClassLoader.class.getDeclaredField(newLibraryPath);
//			fieldSysPath.setAccessible(true);
//			fieldSysPath.set(null, null);
//			return true;
//		} catch (Exception e) {
//			logger.error("设置java.library.path出错：",e);
//			return false;
//		}
		try {
			File directory = new File("./config/resourcesFile/cameraDll/windows/dssSdk");
			String absolutePath = directory.getCanonicalPath();

			Field userPathsField = ClassLoader.class.getDeclaredField("usr_paths");
			userPathsField.setAccessible(true);
			String[] paths = (String[]) userPathsField.get(null);
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < paths.length; i++) {
				if (absolutePath.equals(paths[i])) {
					continue;
				}
				sb.append(paths[i]).append(';');
			}
			sb.append(absolutePath);
			System.setProperty("java.library.path", sb.toString());
			final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
			sysPathsField.setAccessible(true);
			sysPathsField.set(null, null);
			return true;
		} catch (Exception e) {
			logger.error("设置java.library.path出错：", e);
			return false;
		}
	}

	/*
	 * 创建DPSDK，即初始化
	 * */
	private String init() {
		boolean setResult = loadJNILibDynamically();
		if (!setResult)
			return "设置java.library.path出错";
		int nRet = -1;
		Return_Value_Info_t res = new Return_Value_Info_t();
		nRet = IDpsdkCore.DPSDK_Create(dpsdk_sdk_type_e.DPSDK_CORE_SDK_SERVER, res);
		if (nRet != dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			return String.valueOf(nRet);
		}

		m_nDLLHandle = res.nReturnValue;
		nRet = IDpsdkCore.DPSDK_SetLog(m_nDLLHandle, dpsdklog.getBytes());

		nRet = IDpsdkCore.DPSDK_StartMonitor(m_nDLLHandle, dumpfile.getBytes());
		if (m_nDLLHandle > 0) {
//			// 设置设备状态上报监听函数
//			nRet = IDpsdkCore.DPSDK_SetDPSDKDeviceStatusCallback(m_nDLLHandle, fDeviceStatus);
//			// 设置NVR通道状态上报监听函数
//			nRet = IDpsdkCore.DPSDK_SetDPSDKNVRChnlStatusCallback(m_nDLLHandle, fNVRChnlStatus);
//			// 设置通用JSON回调
//			nRet = IDpsdkCore.DPSDK_SetGeneralJsonTransportCallback(m_nDLLHandle, fGeneralJson);
//
//			nRet = IDpsdkCore.DPSDK_SetDPSDKGetBayCarInfoCallbackEx(m_nDLLHandle, fBayCarInfo);
//
//			nRet = IDpsdkCore.DPSDK_SetDPSDKTrafficAlarmCallback(m_nDLLHandle, fTrafficAlarmCallback);
//
//			nRet = IDpsdkCore.DPSDK_SetDPSDKGetAreaSpeedDetectCallback(m_nDLLHandle, fGetAreaSpeedDetectCallback);
//
//			nRet = IDpsdkCore.DPSDK_SetPecDoorStatusCallback(m_nDLLHandle, fDoorStatusCallback);
//
//			// nRet = IDpsdkCore.DPSDK_SetDPSDKDeviceChangeCallback(m_nDLLHandle,
//			// fDeviceChangeCallback );
		}
		return "true";
	}

	/*
	 * 登录
	 * */
	private String login() {
		Login_Info_t loginInfo = new Login_Info_t();
		loginInfo.szIp = AllStaticConfig.dahuaApiIp.getBytes();
		loginInfo.nPort = Integer.parseInt(AllStaticConfig.bajiuSdkPort);
		loginInfo.szUsername = AllStaticConfig.dahuaApiKey.getBytes();
		loginInfo.szPassword = AllStaticConfig.dahuaApiSecret.getBytes();
		loginInfo.nProtocol = dpsdk_protocol_version_e.DPSDK_PROTOCOL_VERSION_II;
		loginInfo.iType = 1;

		int nRet = IDpsdkCore.DPSDK_Login(m_nDLLHandle, loginInfo, 10000);
		if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			return "true";
		}
		return String.valueOf(nRet);
	};

	/*
	 * 登出
	 * */
	private String loginOut() {
		// 因为DSS平台设置了断线重连，所以此处不再进行注销
		return "true";
//		int nRet = IDpsdkCore.DPSDK_Logout(m_nDLLHandle, 10000);
//		if (nRet != dpsdk_retval_e.DPSDK_RET_SUCCESS)
//			return String.valueOf(nRet);
////		return onDestroy();
//		return "true";
	};

	/*
	 * 释放内存
	 * */
	private String onDestroy() {
		int nRet = IDpsdkCore.DPSDK_Destroy(m_nDLLHandle);
		if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			return "true";
		}
		return "释放内存失败，错误码：" + nRet;
	}

	/*
	 * 登出及释放轮巡的登录和内存
	 * */
	private String destroyLunx(int initDllHandle, boolean isLoginout) {
		Dpsdk_Lunx_Core dpsdk_Core = Dpsdk_Lunx_Core.INSTANCE;

		if (isLoginout) {
			int logoutRet = dpsdk_Core.DPSDK_Logout(initDllHandle, 10000);
			if (logoutRet != dpsdk_retval_e.DPSDK_RET_SUCCESS)
				return "登出错误：" + String.valueOf(logoutRet);
		}

		int destroyRet = dpsdk_Core.DPSDK_Destroy(initDllHandle);
		if (destroyRet == dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			return "true";
		}
		return "释放内存失败，错误码：" + destroyRet;
	}

	/*
	 * 初始化及登录
	 * */
	private ResultClass initAndLogin() {
		// 代表还没初始化，需要先初始化
		if (m_nDLLHandle == -1) {
			// 初始化
			String initResult = this.init();
			if (initResult != "true") {
				return this.executeErr(false, initResult, "初始化失败");
			}
			// 登录
			String loginResult = this.login();
			if (loginResult != "true") {
				return this.executeErr(false, loginResult, "登录失败");
			}

			// 所有的操作，都要先加载组织树，然后程序休眠5秒
			String loadAllGroupResult = loadAllGroup();
			if (loadAllGroupResult != "true")
				return this.executeErr(true, loadAllGroupResult, "加载组织树错误，错误码：" + loadAllGroupResult);

			try {
				Thread.sleep(5000);
			} catch (Exception e) {
				logger.error("初始化登录加载组织树后程序休眠错误：", e);
				return this.executeErr(true, loadAllGroupResult, "加载组织树错误，错误码：" + loadAllGroupResult);
			}
		}

		ResultClass resultClass = new ResultClass();
		resultClass.name = true;
		return resultClass;
	};

	/*
	 * 加载所有组织树
	 * */
	private String loadAllGroup() {
		int nRet = IDpsdkCore.DPSDK_LoadDGroupInfo(m_nDLLHandle, nGroupLen, 180000);

		if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			return "true";
		}
		return String.valueOf(nRet);
	}

	/*
	 * 获得控制编码 todo 数组越界错误
	 * */
	private int getControlCode() {
		int codeIndex = EnumTools.listSdkCommand.indexOf(camera.command);
		return EnumTools.arrDahSdkCommandCode[codeIndex];
	};

	/*
	 * 云台方向控制
	 * */
	private String onPtzDirctCtrl() {
		logger.info("云台方向控制接口start,入参 = " +this.camera);
		long start = System.currentTimeMillis();
		int controlCode = getControlCode();
		Ptz_Direct_Info_t directInfo = new Ptz_Direct_Info_t();
		directInfo.szCameraId = camera.cameraIndexCode.getBytes();
		directInfo.nStep = camera.speed;
		directInfo.nDirect = controlCode;
		logger.info("云台方向控制接口start,具体方向 =" + controlCode+
				"szCameraId = " + camera.cameraIndexCode.getBytes());
		directInfo.bStop = false;
		int nRet = IDpsdkCore.DPSDK_PtzDirection(m_nDLLHandle, directInfo,
				dpsdk_constant_value.DPSDK_CORE_DEFAULT_TIMEOUT);
		if (nRet != dpsdk_retval_e.DPSDK_RET_SUCCESS) {

			logger.error("云台方向控制失败，入参 = "+this.camera +
					"错误码 = "+ nRet+
					"耗时 = " +(System.currentTimeMillis()-start)+"ms");
			return String.valueOf(nRet);
		}

		directInfo.bStop = true;
		nRet = IDpsdkCore.DPSDK_PtzDirection(m_nDLLHandle, directInfo, dpsdk_constant_value.DPSDK_CORE_DEFAULT_TIMEOUT);
		if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS){
			logger.info("云台方向控制成功，入参 = "+this.camera +"耗时 = " +(System.currentTimeMillis()-start)+"ms");
			return "true";
		}

		logger.error("云台方向控制失败，入参 = "+this.camera +
				"错误码 = "+ nRet+
				"耗时 = " +(System.currentTimeMillis()-start)+"ms");
		return String.valueOf(nRet);
	}

	/*
	 * 云台图像控制，即：变倍、变焦、光圈
	 * */
	private String onPtzCameraCtrl() {
		logger.info("云台镜头控制start,入参 = " +this.camera);
		long start = System.currentTimeMillis();
		int controlCode = getControlCode();
		logger.info("云台镜头控制接口start,具体方向 =" + controlCode);

		Ptz_Operation_Info_t directInfo = new Ptz_Operation_Info_t();
		directInfo.szCameraId = camera.cameraIndexCode.getBytes();
		directInfo.nOperation = controlCode;
		directInfo.nStep = camera.speed;
		directInfo.bStop = false;
		int nRet = IDpsdkCore.DPSDK_PtzCameraOperation(m_nDLLHandle, directInfo,
				dpsdk_constant_value.DPSDK_CORE_DEFAULT_TIMEOUT);
		if (nRet != dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			logger.error("云台镜头控制失败，入参 = "+this.camera +
					"错误码 = "+ nRet+
					"耗时 = " +(System.currentTimeMillis()-start)+"ms");
			return String.valueOf(nRet);
		}
		directInfo.bStop = true;
		nRet = IDpsdkCore.DPSDK_PtzCameraOperation(m_nDLLHandle, directInfo,
				dpsdk_constant_value.DPSDK_CORE_DEFAULT_TIMEOUT);
		if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS){
			logger.info("云台镜头控制成功，入参 = "+this.camera +
					"耗时 = " +(System.currentTimeMillis()-start)+"ms");
			return "true";
		}
		logger.error("云台镜头控制失败，入参 = "+this.camera +
				"错误码 = "+ nRet+
				"耗时 = " +(System.currentTimeMillis()-start)+"ms");
		return String.valueOf(nRet);
	}

	/*
	 * 返回错误结果，同时释放资源 
	 * isLogingout 是否注销登录，在注册失败时不需要注销登录 
	 * executeResult 调用sdk的结果，一般为错误码 
	 * errPrefixString 返回给客户端调用者的错误信息前缀
	 */
	private ResultClass executeErr(boolean isLogingout, String executeResult, String errPrefixString) {
		if (isLogingout)
			loginOut();
		String errReason = OtherTools.joinErrStr(executeResult, errPrefixString);
		return OtherTools.executeErr(errReason);
	};

	/*
	 * 返回调用成功及结果数据,同时注销登陆
	 */
	private ResultClass executeSuccess(Object resultData) {
		loginOut();
		return OtherTools.executeSuccess(resultData);
	};

	/*
	 * 获取电视墙列表
	 * */
	private ResultClass onGetTvWallList() {
		ResultClass resultClass = new ResultClass();
		Return_Value_Info_t nCount = new Return_Value_Info_t();
		int nRet = IDpsdkCore.DPSDK_GetTvWallListCount(m_nDLLHandle, nCount, 10000);

		if (nRet != dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			resultClass.name = false;
			resultClass.reason = "获取电视墙数量错误，错误码：" + nRet;
			return resultClass;
		}

//		int nCurTvWallId = -1;
		if (nCount.nReturnValue > 0) {
			TvWall_List_Info_t pTvWallListInfo = new TvWall_List_Info_t(nCount.nReturnValue);

			nRet = IDpsdkCore.DPSDK_GetTvWallList(m_nDLLHandle, pTvWallListInfo);
			if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS) {
				try {
					for (int i = 0; i < pTvWallListInfo.nCount; i++) {
						pTvWallListInfo.pTvWallInfo[i].tvWallName = new String(pTvWallListInfo.pTvWallInfo[i].szName,
								"UTF-8").trim();
					}
				} catch (Exception e) {
				}

				resultClass.resultData = pTvWallListInfo;
//				for(int i=0;i<pTvWallListInfo.nCount;i++)
//				{
//					System.out.println();
//					System.out.printf("序号=%d，nTvWallId = %d，nState=%s，szName=%s", i+1,pTvWallListInfo.pTvWallInfo[i].nTvWallId,pTvWallListInfo.pTvWallInfo[i].nState,
//							new String(pTvWallListInfo.pTvWallInfo[i].szName).trim());
//				
//					if(i==0)
//					{
//						nCurTvWallId = pTvWallListInfo.pTvWallInfo[i].nTvWallId;
//					}
//				}
			} else {
				resultClass.name = false;
				resultClass.reason = "获取电视墙列表信息失败，错误码：" + nRet;
				return resultClass;
			}
		}
//		if(nCurTvWallId > 0)
//			GetTvWallLayout(nCurTvWallId);
		resultClass.name = true;
		return resultClass;

	}

	/*
	 * 获取电视墙布局信息
	 * nTvWallId 电视墙ID
	 * */
	private ResultClass GetTvWallLayout(int nTvWallId) {
		ResultClass resultClass = new ResultClass();
		TvWall_Layout_Info_t tvWall_Layout_Info_t = GetTvWallLayout2(nTvWallId);
		if (tvWall_Layout_Info_t.errStr != null) {
			resultClass.name = false;
			resultClass.reason = tvWall_Layout_Info_t.errStr;
			return resultClass;
		}
		resultClass.name = true;
		resultClass.resultData = tvWall_Layout_Info_t;
		return resultClass;

	}

	private TvWall_Layout_Info_t GetTvWallLayout2(int nTvWallId) {
		TvWall_Layout_Info_t tvWall_Layout_Info_t = new TvWall_Layout_Info_t(0);

		Return_Value_Info_t nCount = new Return_Value_Info_t();
		int nRet = IDpsdkCore.DPSDK_GetTvWallLayoutCount(m_nDLLHandle, nTvWallId, nCount, 10000);
		if (nRet != dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			tvWall_Layout_Info_t.errStr = "查询电视墙布局总数失败，错误码：" + nRet;
			return tvWall_Layout_Info_t;
		}

//		int nScreenId = -1;
//		float fLeft = 0;
//		float fTop = 0;
//		float fWidth = 0;
//		float fHeight = 0;
		if (nCount.nReturnValue > 0) {
			TvWall_Layout_Info_t pTvWallLayoutInfo = new TvWall_Layout_Info_t(nCount.nReturnValue);
			pTvWallLayoutInfo.nTvWallId = nTvWallId;

			nRet = IDpsdkCore.DPSDK_GetTvWallLayout(m_nDLLHandle, pTvWallLayoutInfo);
			if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS) {
				try {
					for (int i = 0; i < pTvWallLayoutInfo.nCount; i++) {
						pTvWallLayoutInfo.pScreenInfo[i].screenName = new String(
								pTvWallLayoutInfo.pScreenInfo[i].szName, "UTF-8").trim();
						pTvWallLayoutInfo.pScreenInfo[i].decoderId = new String(
								pTvWallLayoutInfo.pScreenInfo[i].szDecoderId).trim();
					}
				} catch (Exception e) {
				}

				return pTvWallLayoutInfo;
//				for(int i=0;i<pTvWallLayoutInfo.nCount;i++)
//				{
//					if(i == 0)
//					{
//						nScreenId = pTvWallLayoutInfo.pScreenInfo[i].nScreenId;
//					}
//					System.out.println();
//					System.out.printf("序号=%d，nScreenId = %d，szName=%s, szDecoderId=%s,fLeft=%f,fTop=%f,fWidth=%f,fHeight=%f,bBind=%d", i+1,pTvWallLayoutInfo.pScreenInfo[i].nScreenId,new String(pTvWallLayoutInfo.pScreenInfo[i].szName).trim(),
//							new String(pTvWallLayoutInfo.pScreenInfo[i].szDecoderId).trim(), pTvWallLayoutInfo.pScreenInfo[i].fLeft, pTvWallLayoutInfo.pScreenInfo[i].fTop,
//							pTvWallLayoutInfo.pScreenInfo[i].fWidth, pTvWallLayoutInfo.pScreenInfo[i].fHeight, pTvWallLayoutInfo.pScreenInfo[i].bBind?1:0);
//					fLeft = pTvWallLayoutInfo.pScreenInfo[i].fLeft;
//					fTop = pTvWallLayoutInfo.pScreenInfo[i].fTop;
//					fWidth = pTvWallLayoutInfo.pScreenInfo[i].fWidth/2;
//					fHeight = pTvWallLayoutInfo.pScreenInfo[i].fHeight/2;
//				}
			} else {
				tvWall_Layout_Info_t.errStr = "查询电视墙布局信息失败，错误码：" + nRet;
				return tvWall_Layout_Info_t;
			}
		} else {
			tvWall_Layout_Info_t.errStr = "电视墙总数为零";
			return tvWall_Layout_Info_t;
		}
	}

	/*
	 * 开窗
	 * */
	private ResultClass tvWallScreenOpenWindow(int nTvWallId, int nScreenId, float fLeft, float fTop, float fWidth,
			float fHeight) {
		TvWall_Screen_Open_Window_t pOpenWindowInfo = new TvWall_Screen_Open_Window_t();
		pOpenWindowInfo.nTvWallId = nTvWallId;
		pOpenWindowInfo.nScreenId = nScreenId;
		pOpenWindowInfo.fLeft = fLeft;
		pOpenWindowInfo.fTop = fTop;
		pOpenWindowInfo.fWidth = fWidth;
		pOpenWindowInfo.fHeight = fHeight;
		System.out.println("即将开窗，nTvWallId：" + nTvWallId + "，nScreenId：" + nScreenId + "，fLeft：" + fLeft + "，fTop："
				+ fTop + "，fWidth：" + fWidth + "，fHeight：" + fHeight);
		int nRet = IDpsdkCore.DPSDK_TvWallScreenOpenWindow(m_nDLLHandle, pOpenWindowInfo, 10000);
		ResultClass resultClass = new ResultClass();
		if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			Map<String, Object> windowIdMap = new HashMap<String, Object>();
			windowIdMap.put("WindowId", pOpenWindowInfo.nWindowId);
			resultClass.resultData = windowIdMap;
			resultClass.name = true;
//			System.out.printf("窗口开窗成功，nRet = %d，nWindowId = %d。", nRet, pOpenWindowInfo.nWindowId);
			/*TvWall_Screen_Close_Window_t pCloseWindowInfo = new TvWall_Screen_Close_Window_t();
			pCloseWindowInfo.nTvWallId = nTvWallId;
			pCloseWindowInfo.nScreenId = nScreenId;
			pCloseWindowInfo.nWindowId = pOpenWindowInfo.nWindowId;
			nRet = IDpsdkCore.DPSDK_TvWallScreenCloseWindow(m_nDLLHandle, pCloseWindowInfo, 10000);
			if(nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS)
			{
				System.out.printf("窗口关窗成功，nRet = %d", nRet);
			}else
			{
				System.out.printf("窗口关窗失败，nRet = %d", nRet);
			}*/
		} else {
//			System.out.printf("窗口开窗失败，nRet = %d", nRet);
			resultClass.name = false;
			resultClass.reason = "窗口开窗失败，错误码：" + nRet;
		}
		return resultClass;
	}

	/*
	 * 设置窗口视频源
	 * */
	private ResultClass SetWndSource(int nTvWallId, int nScreenId, int nWndId, String cameraIndexCode) {
		Set_TvWall_Screen_Window_Source_t pInfo = new Set_TvWall_Screen_Window_Source_t();
		pInfo.nTvWallId = nTvWallId;
		pInfo.nScreenId = nScreenId;
		pInfo.nWindowId = nWndId;
		pInfo.szCameraId = cameraIndexCode.getBytes();
		pInfo.enStreamType = dpsdk_stream_type_e.DPSDK_CORE_STREAMTYPE_MAIN;
		// 停留时间，电视墙任务才会用到，过了停留时间后，播放下一个视频源
		pInfo.nStayTime = 30;

		ResultClass resultClass = new ResultClass();
		int nRet = IDpsdkCore.DPSDK_SetTvWallScreenWindowSource(m_nDLLHandle, pInfo, 1000);
		if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS) {
//			System.out.printf("设置视频源成功，nRet = %d", nRet);
			resultClass.name = true;
		} else {
			System.out.printf("设置视频源失败，nRet = %d", nRet);
			resultClass.name = false;
			resultClass.reason = "设置视频源失败，错误码：" + nRet;
		}
		return resultClass;
	}

	/*
	 * 保存窗口ID，即更新prevLayoutWinIdList
	 * */
	private ResultClass updateLayoutWinIdList(Object mapObject, int index) {
		try {
			String mapStr = JsonTools.obj2Str(mapObject);
			Map<String, Object> windowIdMap = JsonTools.str2Map(mapStr);
			int windowId = Integer.parseInt(String.valueOf(windowIdMap.get("WindowId")));
			// 说明在索引index处有元素，替换值即可
			if (prevLayoutWinIdList.size() > index) {
				prevLayoutWinIdList.set(index, windowId);
			} else
				prevLayoutWinIdList.add(windowId);
			ResultClass resultClass = new ResultClass();
			resultClass.name = true;
			return resultClass;
		} catch (Exception e) {
			logger.error("保存窗口ID错误", e);
			return new ResultClass(false, "保存窗口ID错误");
		}

	};

	/*
	 * 开窗入口
	 * */
	private ResultClass openWindowMain(int nTvWallId, int screenId, float windowLeft, float windowTop,
			float windowWidth, float windowHeight, int windowIndex) {
		// 开窗
		ResultClass openWinResultClass1 = tvWallScreenOpenWindow(nTvWallId, screenId, windowLeft, windowTop,
				windowWidth, windowHeight);
		if (!openWinResultClass1.name)
			return openWinResultClass1;
		// 保存新的窗口ID
		ResultClass updateWinIdResultClass = updateLayoutWinIdList(openWinResultClass1.resultData, windowIndex);
		if (!updateWinIdResultClass.name)
			return updateWinIdResultClass;
		ResultClass resultClass = new ResultClass();
		resultClass.name = true;
		return resultClass;
	}

	/*
	 * 只有一个窗口的开窗入口
	 * */
	private ResultClass openOneWindowMain(int nTvWallId, int screenId, float screenLeft, float screenTop,
			float screenWidth, float screenHeight) {
		return openWindowMain(nTvWallId, screenId, screenLeft, screenTop, screenWidth, screenHeight, 0);
	};

	/*
	 * 左上角第一个窗口是大窗口的开窗入口
	 * */
	private ResultClass openLeftUpWindowMain(int nTvWallId, int screenId, float screenLeft, float screenTop,
			float screenWidth, float screenHeight) {
		int windowCount = 9;
		float oneWindowWidth = screenWidth / 4;
		float oneWindowHeight = screenHeight / 3;
		float windowLeft = screenLeft;
		float windowTop = screenTop;
		float windowWidth = oneWindowWidth;
		float windowHeight = oneWindowHeight;
		for (int i = 0; i < windowCount; i++) {
			switch (i) {
			// 第一行第一个窗口，即大窗口
			case 0:
				windowWidth = oneWindowWidth * 2;
				windowHeight = oneWindowHeight * 2;
				ResultClass openWinResultClass1 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 0);
				if (!openWinResultClass1.name)
					return openWinResultClass1;
				// 其它窗口的宽、高均为一个窗口的宽高，所以此处统一赋值
				windowWidth = oneWindowWidth;
				windowHeight = oneWindowHeight;
				break;
			// 第一行第二个窗口，即中间的窗口
			case 1:
				windowLeft = oneWindowWidth * 2 + windowLeft;
				ResultClass openWinResultClass2 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 1);
				if (!openWinResultClass2.name)
					return openWinResultClass2;
				break;
			// 第一行第三个窗口，即最右侧的窗口
			case 2:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass3 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 2);
				if (!openWinResultClass3.name)
					return openWinResultClass3;
				break;
			// 第二行第一个窗口，即中间的窗口
			case 3:
				windowLeft = oneWindowWidth * 2 + screenLeft;
				windowTop = windowTop + oneWindowHeight;
				ResultClass openWinResultClass4 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 3);
				if (!openWinResultClass4.name)
					return openWinResultClass4;
				break;
			// 第二行第二个窗口，即最右侧的窗口
			case 4:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass5 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 4);
				if (!openWinResultClass5.name)
					return openWinResultClass5;
				break;
			// 第三行第一个窗口
			case 5:
				windowLeft = screenLeft;
				windowTop = windowTop + oneWindowHeight;
				ResultClass openWinResultClass6 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 5);
				if (!openWinResultClass6.name)
					return openWinResultClass6;
				break;
			// 第三行第二个窗口
			case 6:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass7 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 6);
				if (!openWinResultClass7.name)
					return openWinResultClass7;
				break;
			// 第三行第三个窗口
			case 7:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass8 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 7);
				if (!openWinResultClass8.name)
					return openWinResultClass8;
				break;
			// 第三行第四个窗口
			case 8:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass9 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 8);
				if (!openWinResultClass9.name)
					return openWinResultClass9;
				break;

			default:
				break;
			}
		}
		ResultClass resultClass = new ResultClass();
		resultClass.name = true;
		return resultClass;
	};

	/*
	 * 右下角窗口是大窗口的开窗入口
	 * */
	private ResultClass openRightDownWindowMain(int nTvWallId, int screenId, float screenLeft, float screenTop,
			float screenWidth, float screenHeight) {
		int windowCount = 9;
		float oneWindowWidth = screenWidth / 4;
		float oneWindowHeight = screenHeight / 3;
		float windowLeft = screenLeft;
		float windowTop = screenTop;
		float windowWidth = oneWindowWidth;
		float windowHeight = oneWindowHeight;
		for (int i = 0; i < windowCount; i++) {
			switch (i) {
			// 第一行第一个窗口，即最左侧窗口
			case 0:
				ResultClass openWinResultClass1 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 0);
				if (!openWinResultClass1.name)
					return openWinResultClass1;
				break;
			// 第一行第二个窗口
			case 1:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass2 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 1);
				if (!openWinResultClass2.name)
					return openWinResultClass2;
				break;
			// 第一行第三个窗口
			case 2:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass3 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 2);
				if (!openWinResultClass3.name)
					return openWinResultClass3;
				break;
			// 第一行第四个窗口
			case 3:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass4 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 3);
				if (!openWinResultClass4.name)
					return openWinResultClass4;
				break;
			// 第二行第一个窗口
			case 4:
				windowLeft = screenLeft;
				windowTop = windowTop + oneWindowHeight;
				ResultClass openWinResultClass5 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 4);
				if (!openWinResultClass5.name)
					return openWinResultClass5;
				break;
			// 第二行第二个窗口
			case 5:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass6 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 5);
				if (!openWinResultClass6.name)
					return openWinResultClass6;
				break;
			// 第二行第三个窗口，即大窗口
			case 6:
				windowLeft = windowLeft + oneWindowWidth;
				windowWidth = oneWindowWidth * 2;
				windowHeight = oneWindowHeight * 2;
				ResultClass openWinResultClass7 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 6);
				if (!openWinResultClass7.name)
					return openWinResultClass7;
				break;
			// 第三行第一个窗口
			case 7:
				windowTop = windowTop + oneWindowHeight;
				windowLeft = screenLeft;
				windowWidth = oneWindowWidth;
				windowHeight = oneWindowHeight;
				ResultClass openWinResultClass8 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 7);
				if (!openWinResultClass8.name)
					return openWinResultClass8;
				break;
			// 第三行第二个窗口
			case 8:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass9 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 8);
				if (!openWinResultClass9.name)
					return openWinResultClass9;
				break;
			default:
				break;
			}
		}
		ResultClass resultClass = new ResultClass();
		resultClass.name = true;
		return resultClass;
	};

	/*
	 * 右上角窗口是大窗口的开窗入口
	 * */
	private ResultClass openRightUpWindowMain(int nTvWallId, int screenId, float screenLeft, float screenTop,
			float screenWidth, float screenHeight) {
		int windowCount = 9;
		float oneWindowWidth = screenWidth / 4;
		float oneWindowHeight = screenHeight / 3;
		float windowLeft = screenLeft;
		float windowTop = screenTop;
		float windowWidth = oneWindowWidth;
		float windowHeight = oneWindowHeight;
		for (int i = 0; i < windowCount; i++) {
			switch (i) {
			// 第一行第一个窗口，即最左侧窗口
			case 0:
				ResultClass openWinResultClass1 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 0);
				if (!openWinResultClass1.name)
					return openWinResultClass1;
				break;
			// 第一行第二个窗口
			case 1:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass2 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 1);
				if (!openWinResultClass2.name)
					return openWinResultClass2;
				break;
			// 第一行第三个窗口，即大窗口
			case 2:
				windowLeft = windowLeft + oneWindowWidth;
				windowWidth = oneWindowWidth * 2;
				windowHeight = oneWindowHeight * 2;
				ResultClass openWinResultClass3 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 2);
				if (!openWinResultClass3.name)
					return openWinResultClass3;
				break;
			// 第二行第一个窗口
			case 3:
				windowLeft = screenLeft;
				windowTop = windowTop + oneWindowHeight;
				windowWidth = oneWindowWidth;
				windowHeight = oneWindowHeight;
				ResultClass openWinResultClass4 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 3);
				if (!openWinResultClass4.name)
					return openWinResultClass4;
				break;
			// 第二行第二个窗口
			case 4:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass5 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 4);
				if (!openWinResultClass5.name)
					return openWinResultClass5;
				break;
			// 第三行第一个窗口
			case 5:
				windowLeft = screenLeft;
				windowTop = windowTop + oneWindowHeight;
				ResultClass openWinResultClass6 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 5);
				if (!openWinResultClass6.name)
					return openWinResultClass6;
				break;
			// 第三行第二个窗口
			case 6:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass7 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 6);
				if (!openWinResultClass7.name)
					return openWinResultClass7;
				break;
			// 第三行第三个窗口
			case 7:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass8 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 7);
				if (!openWinResultClass8.name)
					return openWinResultClass8;
				break;
			// 第三行第四个窗口
			case 8:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass9 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 8);
				if (!openWinResultClass9.name)
					return openWinResultClass9;
				break;
			default:
				break;
			}
		}
		ResultClass resultClass = new ResultClass();
		resultClass.name = true;
		return resultClass;
	};

	/*
	 * 左下角窗口是大窗口的开窗入口
	 * */
	private ResultClass openLeftDownWindowMain(int nTvWallId, int screenId, float screenLeft, float screenTop,
			float screenWidth, float screenHeight) {
		int windowCount = 9;
		float oneWindowWidth = screenWidth / 4;
		float oneWindowHeight = screenHeight / 3;
		float windowLeft = screenLeft;
		float windowTop = screenTop;
		float windowWidth = oneWindowWidth;
		float windowHeight = oneWindowHeight;
		for (int i = 0; i < windowCount; i++) {
			switch (i) {
			// 第一行第一个窗口，即最左侧窗口
			case 0:
				ResultClass openWinResultClass1 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 0);
				if (!openWinResultClass1.name)
					return openWinResultClass1;
				break;
			// 第一行第二个窗口，即中间窗口
			case 1:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass2 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 1);
				if (!openWinResultClass2.name)
					return openWinResultClass2;
				break;
			// 第一行第三个窗口，即最右侧的窗口
			case 2:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass3 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 2);
				if (!openWinResultClass3.name)
					return openWinResultClass3;
				break;
			// 第一行第四个窗口
			case 3:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass4 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 3);
				if (!openWinResultClass4.name)
					return openWinResultClass4;
				break;
			// 第二行第一个窗口，即大窗口
			case 4:
				windowLeft = screenLeft;
				windowTop = windowTop + oneWindowHeight;
				windowWidth = oneWindowWidth * 2;
				windowHeight = oneWindowHeight * 2;
				ResultClass openWinResultClass5 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 4);
				if (!openWinResultClass5.name)
					return openWinResultClass5;
				break;
			// 第二行第二个窗口
			case 5:
				windowWidth = oneWindowWidth;
				windowHeight = oneWindowHeight;
				windowLeft = windowLeft + oneWindowWidth * 2;
				ResultClass openWinResultClass6 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 5);
				if (!openWinResultClass6.name)
					return openWinResultClass6;
				break;
			// 第二行第三个窗口
			case 6:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass7 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 6);
				if (!openWinResultClass7.name)
					return openWinResultClass7;
				break;
			// 第三行第一个窗口
			case 7:
				windowTop = windowTop + oneWindowHeight;
				windowLeft = screenLeft + oneWindowWidth * 2;
				ResultClass openWinResultClass8 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 7);
				if (!openWinResultClass8.name)
					return openWinResultClass8;
				break;
			// 第三行第二个窗口
			case 8:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass9 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 8);
				if (!openWinResultClass9.name)
					return openWinResultClass9;
				break;
			default:
				break;
			}
		}
		ResultClass resultClass = new ResultClass();
		resultClass.name = true;
		return resultClass;
	};

	/*
	 * 十二宫格窗口
	 * */
	private ResultClass openJiuGonGeWindowMain(int nTvWallId, int screenId, float screenLeft, float screenTop,
			float screenWidth, float screenHeight) {
		int windowCount = 12;
		float oneWindowWidth = screenWidth / 4;
		float oneWindowHeight = screenHeight / 3;
		float windowLeft = screenLeft;
		float windowTop = screenTop;
		float windowWidth = oneWindowWidth;
		float windowHeight = oneWindowHeight;
		for (int i = 0; i < windowCount; i++) {
			switch (i) {
			// 第一行第一个窗口，即最左侧窗口
			case 0:
				ResultClass openWinResultClass1 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 0);
				if (!openWinResultClass1.name)
					return openWinResultClass1;
				break;
			// 第一行第二个窗口
			case 1:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass2 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 1);
				if (!openWinResultClass2.name)
					return openWinResultClass2;
				break;
			// 第一行第三个窗口
			case 2:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass3 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 2);
				if (!openWinResultClass3.name)
					return openWinResultClass3;
				break;
			// 第一行第四个窗口
			case 3:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass4 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 3);
				if (!openWinResultClass4.name)
					return openWinResultClass4;
				break;
			// 第二行第一个窗口
			case 4:
				windowTop = windowTop + oneWindowHeight;
				windowLeft = screenLeft;
				ResultClass openWinResultClass5 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 4);
				if (!openWinResultClass5.name)
					return openWinResultClass5;
				break;
			// 第二行第二个窗口
			case 5:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass6 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 5);
				if (!openWinResultClass6.name)
					return openWinResultClass6;
				break;
			// 第二行第三个窗口
			case 6:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass7 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 6);
				if (!openWinResultClass7.name)
					return openWinResultClass7;
				break;
			// 第二行第四个窗口
			case 7:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass8 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 7);
				if (!openWinResultClass8.name)
					return openWinResultClass8;
				break;
			// 第三行第一个窗口
			case 8:
				windowTop = windowTop + oneWindowHeight;
				windowLeft = screenLeft;
				ResultClass openWinResultClass9 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 8);
				if (!openWinResultClass9.name)
					return openWinResultClass9;
				break;
			// 第三行第二个窗口
			case 9:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass10 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 9);
				if (!openWinResultClass10.name)
					return openWinResultClass10;
				break;
			// 第三行第三个窗口
			case 10:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass11 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 10);
				if (!openWinResultClass11.name)
					return openWinResultClass11;
				break;
			// 第三行第四个窗口
			case 11:
				windowLeft = windowLeft + oneWindowWidth;
				ResultClass openWinResultClass12 = openWindowMain(nTvWallId, screenId, windowLeft, windowTop,
						windowWidth, windowHeight, 11);
				if (!openWinResultClass12.name)
					return openWinResultClass12;
				break;
			default:
				break;
			}
		}
		ResultClass resultClass = new ResultClass();
		resultClass.name = true;
		return resultClass;
	};

	/*
	 * 清除屏幕
	 * */
	private ResultClass clearSceen(int nTvWallId, int screenId) {
		ResultClass resultClass = new ResultClass();
		// 开窗前先获取电视墙布局信息，以设置窗口位置和大小
		TvWall_Layout_Info_t pTvWallLayoutInfo = GetTvWallLayout2(nTvWallId);
		if (pTvWallLayoutInfo.errStr != null) {
			resultClass.name = false;
			resultClass.reason = pTvWallLayoutInfo.errStr;
			return resultClass;
		}
		TvWall_Screen_Info_t currScreen = null;
		TvWall_Screen_Info_t[] pScreenInfo = pTvWallLayoutInfo.pScreenInfo;
		for (int i = 0; i < pScreenInfo.length; i++) {
			if (pScreenInfo[i].nScreenId == screenId) {
				currScreen = pScreenInfo[i];
				break;
			}
		}
		if (currScreen == null) {
			resultClass.name = false;
			resultClass.reason = "未找到屏幕";
			return resultClass;
		}

		// 清除屏幕
		int nRet1 = IDpsdkCore.DPSDK_ClearTvWallScreen(m_nDLLHandle, nTvWallId, 1000);
		if (nRet1 != dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			resultClass.name = false;
			resultClass.reason = "清除屏幕失败，错误码：" + nRet1;
			return resultClass;
		}
		resultClass.name = true;
		return resultClass;
	}

	/*
	 * 开窗逻辑
	 * */
	private ResultClass kaichuangLogic(int nTvWallId, int screenId) {
		ResultClass resultClass = new ResultClass();
		String layoutCode = camera.layoutCode;
		if (layoutCode == null || "".equals(layoutCode)) {
			resultClass.name = false;
			resultClass.reason = "非法的参数";
			return resultClass;
		}
		// 获取将要使用的布局方式
		int currLayoutIndex = layoutNameList.indexOf(layoutCode);
		if (currLayoutIndex == -1) {
			resultClass.name = false;
			resultClass.reason = "非法的布局";
			return resultClass;
		}

		// 先判断布局是否改变，改变时要 先开窗
		if (currLayoutIndex != prevLayoutIndex) {
			ResultClass cleanSceenResult = clearSceen(nTvWallId, screenId);
			if (!cleanSceenResult.name)
				return cleanSceenResult;

			/*
			 * left、top、width、height均为百分比
			 * 窗口的起始left、top均为零;width、height均为100，因为是相对于要进行开窗的屏
			 * */
			float screenLeft = 0;// currScreen.fLeft;
			float screenTop = 0; // currScreen.fTop;
			float screenWidth = 100; // currScreen.fWidth;
			float screenHeight = 100;// currScreen.fHeight;
			// 开始开窗
			ResultClass openWinResultClass = currLayoutIndex == 0
					? openOneWindowMain(nTvWallId, screenId, screenLeft, screenTop, screenWidth, screenHeight)
					: currLayoutIndex == 1
							? openLeftUpWindowMain(nTvWallId, screenId, screenLeft, screenTop, screenWidth,
									screenHeight)
							: currLayoutIndex == 2
									? openRightDownWindowMain(nTvWallId, screenId, screenLeft, screenTop, screenWidth,
											screenHeight)
									: currLayoutIndex == 3
											? openRightUpWindowMain(nTvWallId, screenId, screenLeft, screenTop,
													screenWidth, screenHeight)
											: currLayoutIndex == 4
													? openLeftDownWindowMain(nTvWallId, screenId, screenLeft, screenTop,
															screenWidth, screenHeight)
													: openJiuGonGeWindowMain(nTvWallId, screenId, screenLeft, screenTop,
															screenWidth, screenHeight);

			// 开窗失败时再调用一次清除屏幕的方法
			if (!openWinResultClass.name) {
				IDpsdkCore.DPSDK_ClearTvWallScreen(m_nDLLHandle, nTvWallId, 1000);
				resultClass.name = false;
				resultClass.reason = openWinResultClass.reason;
				return resultClass;
			}
		}

		prevLayoutIndex = currLayoutIndex;
		resultClass.name = true;
		return resultClass;
	}

	/*
	 * 获取所有组织树串
	 * */
	private String GetGroupStr() {
		Return_Value_Info_t nGroupLen = new Return_Value_Info_t();
		byte[] szGroupBuf = new byte[nGroupLen.nReturnValue];
		int nRet = IDpsdkCore.DPSDK_GetDGroupStr(m_nDLLHandle, szGroupBuf, nGroupLen.nReturnValue, 10000);

		if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS) {
			try {
				File file = new File("D:\\dpsdkGroupTree.xml");
				if (!file.exists()) {
					file.createNewFile();
				}

				FileOutputStream out = new FileOutputStream(file);
				out.write(szGroupBuf);
				out.close();
				return "true";
			} catch (IOException e1) {
				logger.error("生成组织树xml文件异常",e1);
				return  "生成组织树xml文件异常";
			}
		} else {
			return "获取所有组织树串失败，错误码："+nRet;
		}
	}

	/* 控制入口 */
	public ResultClass controlMain() {
		logger.info("摄像头控制入口start，入参 = " +this.camera);
		long start = System.currentTimeMillis();
		logger.info("初始化登录开始");
		ResultClass initResultClass = initAndLogin();
		if (!initResultClass.name){
			logger.error("初始化登录失败，原因 = " +initResultClass.toString());
			return initResultClass;
		}
		int controlCodeIndex = EnumTools.listSdkCommand.indexOf(camera.command);
		logger.info("摄像头控制指令=" + controlCodeIndex);
		// controlCodeIndex>5时为方向控制，否则为镜头控制
		String controlResult = controlCodeIndex > 5 ? onPtzDirctCtrl() : onPtzCameraCtrl();

		if (controlResult != "true") {
			logger.error("摄像头控制调用失败，入参 = " +this.camera +"返回信息:控制指令调用失败");
			return this.executeErr(true, controlResult, "控制指令调用失败");
		}
		logger.info("摄像头控制调用成功，入参 = " +this.camera + "耗时 = " +(System.currentTimeMillis()-start) +"ms");

		return this.executeSuccess(null);
	};

	/* 获取电视墙列表信息入口 */
	public ResultClass getTvWallListMain() {
		ResultClass initResultClass = initAndLogin();
		if (!initResultClass.name)
			return initResultClass;

		ResultClass wallResult = onGetTvWallList();
		if (!wallResult.name)
			return this.executeErr(true, wallResult.reason, "");
		return this.executeSuccess(wallResult.resultData);
	};

	/* 获取电视墙布局列表信息入口 */
	public ResultClass getTvWallLayoutListMain() {
		ResultClass initResultClass = initAndLogin();
		if (!initResultClass.name)
			return initResultClass;

		ResultClass wallLayoutResult = GetTvWallLayout(camera.tvWallId);
		if (!wallLayoutResult.name)
			return this.executeErr(true, wallLayoutResult.reason, "");
		return this.executeSuccess(wallLayoutResult.resultData);
	};

	/*
	 * 投屏入口。要求客户把多个物理屏融合成一个逻辑屏，此处代码中所有的操作都是在这一个逻辑屏上进行。
	 * 投屏的步骤：如果布局和上一次的布局一样则直接设置每个窗口的视频源；否则先在融合屏上开窗，然后再设置每个窗口的视频源
	 * nTvWallId 电视墙ID
	 * screenId 屏ID
	 * layoutCode 布局名称，取值范围见数组layoutNameList
	 * cameraIndexArr 窗口数据源数组，每一项均为cameraIndexCode，数组的顺序和窗口顺序保持一致
	 * */
	public ResultClass touP(int nTvWallId, int screenId) {
		ResultClass initResultClass = initAndLogin();
		if (!initResultClass.name)
			return initResultClass;

		String layoutCode = camera.layoutCode;
		String[] cameraIndexArr = camera.cameraIndexArr;
		if (layoutCode == null || "".equals(layoutCode) || cameraIndexArr == null || cameraIndexArr.length == 0)
			return this.executeErr(true, "非法的参数", "投屏失败");
		// 获取将要使用的布局方式
		int currLayoutIndex = layoutNameList.indexOf(layoutCode);
		if (currLayoutIndex == -1)
			return this.executeErr(true, "非法的布局", "投屏失败");

		// 开窗
		ResultClass openWinResult = kaichuangLogic(nTvWallId, screenId);
		if (!openWinResult.name)
			return this.executeErr(true, openWinResult.reason, "开窗失败");

		// 设置窗口源
		for (int j = 0; j < cameraIndexArr.length; j++) {
			String currCameraIndexCode = cameraIndexArr[j];
			int windowId = prevLayoutWinIdList.get(j);
			System.out.println("即将设置视频源，nTvWallId：" + nTvWallId + "，screenId：" + screenId + "，windowId：" + windowId
					+ "，currCameraIndexCode：" + currCameraIndexCode);
			ResultClass setSourceResultClass = SetWndSource(nTvWallId, screenId, windowId, currCameraIndexCode);
			if (!setSourceResultClass.name)
				return this.executeErr(true, setSourceResultClass.reason, "");
		}

		return this.executeSuccess(null);
	};

	public ResultClass lunx() {
		return null;
//		Set_TvWall_Screen_Window_Source_t pInfo = new Set_TvWall_Screen_Window_Source_t();
//		pInfo.nTvWallId = 1;
//		pInfo.nScreenId = 266;
//		pInfo.nWindowId = 0;
//		pInfo.szCameraId = cameraIndexCode.getBytes();
//		pInfo.enStreamType = dpsdk_stream_type_e.DPSDK_CORE_STREAMTYPE_MAIN;
//		// 停留时间，电视墙任务才会用到，过了停留时间后，播放下一个视频源
//		pInfo.nStayTime = 30;
//
//		ResultClass resultClass = new ResultClass();
//		int nRet = IDpsdkCore.DPSDK_SetTvWallScreenWindowSource(m_nDLLHandle, pInfo, 1000);
//		if (nRet == dpsdk_retval_e.DPSDK_RET_SUCCESS) {
////			System.out.printf("设置视频源成功，nRet = %d", nRet);
//			resultClass.name = true;
//		} else {
//			System.out.printf("设置视频源失败，nRet = %d", nRet);
//			resultClass.name = false;
//			resultClass.reason = "设置视频源失败，错误码：" + nRet;
//		}
//		return resultClass;

//		Dpsdk_Lunx_Core dpsdk_Core = Dpsdk_Lunx_Core.INSTANCE;
//
//		// ------------初始化
//		Dpsdk_Lunx_Core.Return_Value_Info_t initRes = new Dpsdk_Lunx_Core.Return_Value_Info_t();
//		int initRet = dpsdk_Core.DPSDK_Create(dpsdk_sdk_type_e.DPSDK_CORE_SDK_SERVER, initRes);
//		if (initRet != dpsdk_retval_e.DPSDK_RET_SUCCESS) {
//			return new ResultClass(false, "初始化失败：" + initRet);
//		}
//		int initDLLHandle = initRes.nReturnValue;
//
//		// ------------登录
//		Dpsdk_Lunx_Core.Login_Info_t loginInfo = new Dpsdk_Lunx_Core.Login_Info_t();
//		loginInfo.szIp = AllStaticConfig.dahuaApiIp.getBytes();
//		loginInfo.nPort = Integer.parseInt(AllStaticConfig.bajiuSdkPort);
//		loginInfo.szUsername = AllStaticConfig.dahuaApiKey.getBytes();
//		loginInfo.szPassword = AllStaticConfig.dahuaApiSecret.getBytes();
//		loginInfo.nProtocol = dpsdk_protocol_version_e.DPSDK_PROTOCOL_VERSION_II;
//		loginInfo.iType = 1;
//
//		int loginRet = dpsdk_Core.DPSDK_Login(initDLLHandle, loginInfo, 10000);
//		if (loginRet != dpsdk_retval_e.DPSDK_RET_SUCCESS) {
//			destroyLunx(initDLLHandle, false);
//			return new ResultClass(false, "登录失败：" + loginRet);
//		}
//
//		long iTaskId = 1;
//		int nWindowCount = 1;
//		int nTimeout = 10000;
//
//		// 通道信息
//		TaskChnlInfoEx_t pTaskChnlInfoEx = new TaskChnlInfoEx_t();
//		pTaskChnlInfoEx.szCameraName = "通1".getBytes();
//		pTaskChnlInfoEx.szCameraId = "1000005$1$0$0".getBytes();
//		pTaskChnlInfoEx.iStreamType = 1;
//
//		// 窗口信息
//		WindowTaskInfoEx_t pWindowTaskInfoEx = new WindowTaskInfoEx_t();
//		pWindowTaskInfoEx.nInfoCount = 1;
//		pWindowTaskInfoEx.pTaskChnlInfoEx = pTaskChnlInfoEx;
//
//		// 任务信息
//		TaskInfoEx_t struTaskInfoEx = new TaskInfoEx_t();
//		struTaskInfoEx.iTaskId = iTaskId;
//		struTaskInfoEx.szTaskName = "任务1".getBytes();
//		struTaskInfoEx.szTaskDesc = "任务1".getBytes();
//		struTaskInfoEx.nWindowTaskInfoCount = nWindowCount;
//		struTaskInfoEx.pWindowTaskInfoEx = pWindowTaskInfoEx;
//
////		int lxResult=IDpsdkCore.DPSDK_AddSwitchEx(m_nDLLHandle,1,nWindowCount,struTaskInfoEx,nTimeout);
//
//		int lxResult = dpsdk_Core.DPSDK_AddSwitchEx(m_nDLLHandle, iTaskId, nWindowCount, struTaskInfoEx, nTimeout);
//
//		destroyLunx(initDLLHandle, true);
//		if (lxResult == dpsdk_retval_e.DPSDK_RET_SUCCESS)
//			return this.executeSuccess(null);
//		return this.executeErr(true, "设置轮巡失败，错误码：" + lxResult, "");
	};

	/*
	 * 开窗
	 * */
	public ResultClass kaichuang(int nTvWallId, int screenId) {
		ResultClass initResultClass = initAndLogin();
		if (!initResultClass.name)
			return initResultClass;

		ResultClass openWinResult = kaichuangLogic(nTvWallId, screenId);
		return !openWinResult.name ? this.executeErr(true, openWinResult.reason, "开窗失败")
				: this.executeSuccess(prevLayoutWinIdList);
	}

	/*
	 * 设置窗口视频源
	 * */
	public ResultClass setWindowSource(int nTvWallId, int screenId) {
		ResultClass initResultClass = initAndLogin();
		if (!initResultClass.name)
			return initResultClass;

		ResultClass setSourceResultClass = SetWndSource(nTvWallId, screenId, camera.windowId, camera.cameraIndexCode);
		return !setSourceResultClass.name ? this.executeErr(true, setSourceResultClass.reason, "设置视频源失败")
				: this.executeSuccess(null);
	}

	/*
	 * 退出投屏
	 * */
	public ResultClass exitToup(int nTvWallId, int screenId) {
		ResultClass initResultClass = initAndLogin();
		if (!initResultClass.name)
			return initResultClass;

		ResultClass cleanSceenResult = clearSceen(nTvWallId, screenId);
		return !cleanSceenResult.name ? this.executeErr(true, cleanSceenResult.reason, "") : this.executeSuccess(null);
	}

	/*
	 * 获取所有组织树串
	 * */
	public ResultClass getGroupTree() {
		ResultClass initResultClass = initAndLogin();
		if (!initResultClass.name)
			return initResultClass;
		
		String groupResult = this.GetGroupStr();

		if (groupResult != "true") {
			return this.executeErr(true, groupResult, "");
		}
		return this.executeSuccess("组织结构树生成成功，保存于D:\\dpsdkGroupTree.xml");
	}
	
}
