// UB530SDK.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "Python.h"
#include "MemoryServer.h"

CMemoryServer g_ub530;
PyObject *g_list = NULL;
/************************************************************************/
/*  函数：[7/4/2018 Wang];
/*  描述：进程是否在运行;
/*  参数：;
/*  	[IN] ：执行文件路径;
/*  	[OUT] ：;
/*  	[IN/OUT] ：;
/*  返回：成功返回进程ID（!= 0）;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* IsAppRunning(PyObject *self, PyObject *args)
{
	// 应用程序路径;
	const char* pszExePath = NULL;
	if (!PyArg_ParseTuple(args, "s", &pszExePath))
		return NULL;

	return Py_BuildValue("i", IsAppRunning(pszExePath));
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：启动进程;
/*  参数：;
/*  	[IN] ：执行文件完整路径,并且默认打开设备索引值为0的设备;
/*  	[OUT] ：;
/*  	[IN/OUT] ：;
/*  返回：成功返回1，失败返回0;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* StartApp(PyObject *self, PyObject *args)
{
	// 应用程序路径;
	const char* pszExePath = NULL;
	if (!PyArg_ParseTuple(args, "s", &pszExePath))
		return NULL;

	// 参数有效性判断;
	if (!pszExePath || !PathFileExists(pszExePath))
		return Py_BuildValue("b",0);

	// 进程是否存在;
	_stprintf_s(g_szAppDir, _T("%s"), pszExePath);
	if ( (g_dwAppId = IsAppRunning(g_szAppDir)) != 0)
		return Py_BuildValue("b",1);

	// 启动应用程序;
	//ShellExecute(NULL, "open", pszExePath, NULL, NULL, SW_SHOWNORMAL);
	SHELLEXECUTEINFO sei;
	memset(&sei, 0, sizeof(SHELLEXECUTEINFO));
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.hwnd = NULL;
	// 普通打开方式：open；若想以管理员身份运行：runas
	sei.lpVerb = _T("runas");
	//sei.fMask = SEE_MASK_NOCLOSEPROCESS;//不设置，则使用默认值;
	sei.lpFile = g_szAppDir;
	sei.lpParameters = NULL;
	sei.lpDirectory = NULL;
	sei.nShow = SW_SHOWNORMAL;
	sei.hInstApp = NULL;

	if ( !ShellExecuteEx(&sei) )
	{
		DWORD dw = GetLastError();
		return Py_BuildValue("b",0);
	}

	if (sei.hProcess)
		CloseHandle(sei.hProcess);

	// 打开索引为0的设备;
	// 待实现;

	return Py_BuildValue("b",1);
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：关闭进程;
/*  参数：;
/*  返回：成功结束进程返回1，失败返回0;
/*  注意：Win7以上系统，如果宿主程序不是以管理权限运行，是无权附加进程并关闭进程;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* StopApp(PyObject *self, PyObject *args)
{
	// 结束进程;
#if 1
	if ( (g_dwAppId = IsAppRunning(g_szAppDir)) != 0)
	{
		if ( !CloseApp(g_dwAppId) )
			return Py_BuildValue("b",0);
	}
#else
	// 调用App的Close函数;
#endif

	return Py_BuildValue("b",1);	// 返回None;
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：连接设备，默认连接索引为0的设备;
/*  参数：;
/*  	[IN] ：设备索引值（从0开始，默认值为0）;
/*  返回：void;
/*  注意：连接设备需要响应时间，测试结果为大概3秒;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* ConnectDevice(PyObject *self, PyObject *args)
{
	BOOL bRet = g_ub530.ConnectDevice();
	return Py_BuildValue("b", bRet);
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：断开设备，默认索引为0的设备;
/*  参数：;
/*  	[IN] ：设备索引值（从0开始，默认值为0）;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* DisconnectDevice(PyObject *self, PyObject *args)
{
	BOOL bRet = g_ub530.DisconnectDevice();
	return Py_BuildValue("b", bRet);
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：开始/停止 流;
/*  参数：;
/*  	[IN] ：true开始，false停止;
/*  返回：void;
/*  注意：操作设备需要响应时间，测试结果为大概3秒;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* StreamOption(PyObject *self, PyObject *args)
{
	BOOL bStartStreaming = FALSE;
	if (!PyArg_ParseTuple(args, "b", &bStartStreaming))
		return NULL;

	BOOL bRet = g_ub530.StreamOpt(bStartStreaming);
	return Py_BuildValue("b", bRet);
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：显示窗口;
/*  参数：;
/*  	[IN] ：;
/*  	[OUT] ：;
/*  	[IN/OUT] ：;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* ShowApp(PyObject *self, PyObject *args)
{
	g_ub530.ShowApp();
	return Py_BuildValue("");	// 返回None;
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：隐藏窗口;
/*  参数：;
/*  	[IN] ：;
/*  	[OUT] ：;
/*  	[IN/OUT] ：;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* HideApp(PyObject *self, PyObject *args)
{
	g_ub530.HideApp();
	return Py_BuildValue("");	// 返回None;
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：抓图，持续方式以张数为单位;
/*  参数：;
/*  	[IN] ：设备索引（从0开始）;
/*  	[IN] ：图片保存路径;
/*  	[IN] ：图片保存格式，默认为PNG;
/*  	[IN] ：包括叠加内容，默认true;
/*  	[IN-4] ：采集区域，上、下、左、右4个参数;
/*  	[IN] ：截图张数，默认1;
/*  返回：void;
/*  注意：接口返回调用成功，并非表明完成截图，只是表示设备完成指令响应，并未完成截图工作;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* CaptureImageByCount(PyObject *self, PyObject *args)
{
	// 图片格式;
	unsigned short dwImageType = 3;
	// 叠加内容;
	BOOL bOverlayMix = TRUE;
	// 采集区域;
	int nTop = 0, nLeft = 0, nRight = 0, nBottom = 0;
	// 持续时间;
	int nKeepTime = 10;
	// 保存路径;
	const char* lpszSaveDir = NULL;
	// 文件前缀;
	const char* lpszPrefix = NULL;
	if (!PyArg_ParseTuple(args, "issh", &nKeepTime, &lpszSaveDir, &lpszPrefix, &dwImageType))
		return NULL;

	BOOL bRet = g_ub530.CaptureImageByCount( nKeepTime, lpszSaveDir, lpszPrefix, dwImageType);

	return Py_BuildValue("b", bRet);
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：单张抓图，持续方式以张数为单位;
/*  参数：;
/*  	[IN] ：设备索引（从0开始）;
/*  	[IN] ：图片保存路径;
/*  	[IN] ：图片保存格式，默认为PNG;
/*  	[IN] ：包括叠加内容，默认true;
/*  	[IN-4] ：采集区域，上、下、左、右4个参数;
/*  	[IN] ：截图张数，默认1;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* CaptureSingleImage(PyObject *self, PyObject *args)
{
	// 图片格式;
	unsigned short dwImageType = 3;
	// 叠加内容;
	BOOL bOverlayMix = TRUE;
	// 采集区域;
	int nTop = 0, nLeft = 0, nRight = 0, nBottom = 0;
	// 持续时间;
	int nKeepTime = 10;
	// 保存路径;
	const char* lpszSaveDir = NULL;
	if (!PyArg_ParseTuple(args, "sh", &lpszSaveDir, &dwImageType))
		return NULL;

	BOOL bRet = g_ub530.CaptureSingleImage(lpszSaveDir, dwImageType);

	return Py_BuildValue("b", bRet);
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：抓图，持续方式以秒为单位;
/*  参数：;
/*  	[IN] ：设备索引（从0开始）;
/*  	[IN] ：图片保存路径;
/*  	[IN] ：图片保存格式，默认为PNG;
/*  	[IN] ：包括叠加内容，默认true;
/*  	[IN-4] ：采集区域，上、下、左、右4个参数;
/*  	[IN] ：持续时间，默认1000ms;
/*  	[IN] ：每秒抓取张数，默认10张;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* CaptureImageByTime(PyObject *self, PyObject *args)
{
	// 图片格式;
	unsigned short dwImageType = 3;
	// 叠加内容;
	BOOL bOverlayMix = TRUE;
	// 采集区域;
	int nTop = 0, nLeft = 0, nRight = 0, nBottom = 0;
	// 持续时间;
	int nKeepTime = 10;
	// 每秒抓取张数;
	int nCaputerCount = 0;
	// 保存路径;
	const char* lpszSaveDir = NULL;
	// 文件前缀;
	const char* lpszPrefix = NULL;
	if (!PyArg_ParseTuple(args, "iissh", &nKeepTime, &nCaputerCount, &lpszSaveDir, &lpszPrefix, &dwImageType))
		return NULL;

	BOOL bRet = g_ub530.CaptureImageByTime(nKeepTime, nCaputerCount, lpszSaveDir, lpszPrefix, dwImageType);

	return Py_BuildValue("b", bRet);
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：停止截图，暂未使用;
/*  参数：;
/*  	[IN] ：;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* StopCaptureImage(PyObject *self, PyObject *args)
{
	g_ub530.StopCaptureImage();
	return Py_BuildValue("");	// 返回None;
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：同步视频录制;
/*  参数：;
/*  	[IN] ：视屏的保存路径;
/*  	[IN] ：录制时间长度，以秒为单位（约值）;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* StartCaptureAudio(PyObject *self, PyObject *args)
{
	// 保存路径;
	const char* lpszSaveDir = NULL;
	if (!PyArg_ParseTuple(args, "s", &lpszSaveDir))
		return NULL;

	BOOL bRet = g_ub530.SynCaptureAudio(lpszSaveDir);

	return Py_BuildValue("b", bRet);
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：停止录制视频;
/*  参数：;
/*  	[IN] ：;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* StopCaptureAudio(PyObject *self, PyObject *args)
{
	g_ub530.StopCaptureAudio();
	return Py_BuildValue("");	// 返回None;
}

/************************************************************************/
/*  函数：[7/2/2018 Wang];
/*  描述：异步视频录制;
/*  参数：;
/*  	[IN] ：视屏的保存路径;
/*  	[IN] ：录制时间长度，以秒为单位（约值）;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* AsyCaptureAudio(PyObject *self, PyObject *args)
{
	// 持续时间;
	DWORD dwKeepTime = 10;
	// 保存路径;
	const char* lpszSaveDir = NULL;
	if (!PyArg_ParseTuple(args, "ls", &dwKeepTime, &lpszSaveDir))
		return NULL;

	BOOL bRet = g_ub530.AsyCaptureAudio(dwKeepTime, lpszSaveDir);

	return Py_BuildValue("b", bRet);
}

/************************************************************************/
/*  函数：[8/13/2018 jianfeng1.wang];
/*  描述：;
/*  参数：;
/*  	[IN] ：;
/*  	[OUT] ：;
/*  	[IN/OUT] ：;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
static PyObject* GetCaptureImageList(PyObject *self, PyObject *args)
{
	// 保存路径;
	const char* lpszImgDir = NULL;
	if (!PyArg_ParseTuple(args, "s", &lpszImgDir))
		return NULL;

	vector<TString> files;
	findfile(lpszImgDir, files);

	if (g_list != NULL)
	{
		Py_DECREF(g_list);
		g_list = NULL;
	}

	int i = 0;
	g_list = PyList_New(0);
	for (vector<TString>::iterator it = files.begin(); it != files.end(); it++)
	{
		PyList_Append(g_list, PyString_FromString(it->c_str()));
	}

	return g_list;
}

// 描述方法,暴露给python的函数;
static PyMethodDef UB530_Methods[] ={
	{"IsAppRunning",IsAppRunning,METH_VARARGS,"程序是否在运行"},
	{"StartApp", StartApp, METH_VARARGS, "启动进程"},
	{"StopApp", StopApp, METH_VARARGS, "关闭进程"},
	{"ConnectDevice", ConnectDevice, METH_VARARGS, "连接设备"},
	{"DisconnectDevice", DisconnectDevice, METH_VARARGS, "断开设备"},
	{"StreamOption",StreamOption,METH_VARARGS,"流操作"},
	{"ShowApp", ShowApp, METH_VARARGS, "显示窗口"},
	{"HideApp", HideApp, METH_VARARGS, "隐藏窗口"},
	{"CaptureImageByCount", CaptureImageByCount, METH_VARARGS, "以张数为单位抓图"},
	{"CaptureImageByTime", CaptureImageByTime, METH_VARARGS, "以时间为单位抓图"},
	{"CaptureSingleImage", CaptureSingleImage, METH_VARARGS, "单张抓图"},
	{"StopCaptureImage", StopCaptureImage, METH_VARARGS, "停止抓图"},
	{"StartCaptureAudio", StartCaptureAudio, METH_VARARGS, "同步视屏录制"},
	{"StopCaptureAudio", StopCaptureAudio, METH_VARARGS, "同步视屏录制"},
	{"AsyCaptureAudio", AsyCaptureAudio, METH_VARARGS, "异步视屏录制"},
	{"GetCaptureImageList", GetCaptureImageList, METH_VARARGS, "返回目录文件列表"},
	{NULL,NULL}
};

// 初始模块;//格式：init<模块名称>
PyMODINIT_FUNC initUB530SDK()
{
	// 初始化共享内存;
	g_ub530.InitMemery();
	// 进程提权;
	if ( !GetDebugPriv() )
		WriteTextLog(_T("提权失败"));
	// 初始化pyd函数列表;
	PyObject *m,*d;
	m = Py_InitModule("UB530SDK", UB530_Methods);
	d = PyModule_GetDict(m);
}


