// DlgDebug.cpp : 实现文件
//

#include "stdafx.h"
#include "OGCAssistTool.h"
#include "PageDebug.h"
#include "Injection.h"
#include "CharEncoding.h"

// 注入;
extern CInjection g_Injection;
// OGC Tool无序句柄;
extern HWND g_hWnd_SN;
extern HWND g_hWnd_SN_Combobox;
extern HWND g_hWnd_Tester;
extern HWND g_hWnd_FWVersion;
extern HWND g_hWnd_Channel;
extern BOOL StartOGCTool();
// CDlgDebug 对话框

CPageDebug *CPageDebug::m_pDlg = NULL;
IMPLEMENT_DYNAMIC(CPageDebug, CDialogEx)

CPageDebug::CPageDebug(CWnd* pParent /*=NULL*/)
	: CDialogEx(CPageDebug::IDD, pParent)
{
	m_pDlg = this;
}

CPageDebug::~CPageDebug()
{
}

void CPageDebug::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, LIST_DEBUG_DATA, m_ctrlList);
}


BEGIN_MESSAGE_MAP(CPageDebug, CDialogEx)
	ON_WM_CTLCOLOR()
	ON_BN_CLICKED(BTN_SHOW_WND, &CPageDebug::OnBnClickedShowWnd)
	ON_BN_CLICKED(CHECK_HIJACK, &CPageDebug::OnBnClickedHijack)
	ON_BN_CLICKED(BTN_TEST, &CPageDebug::OnBnClickedTest)
	ON_BN_CLICKED(BTN_CONNECT, &CPageDebug::OnBnClickedConnect)
	ON_WM_TIMER()
END_MESSAGE_MAP()


// CDlgDebug 消息处理程序

BOOL CPageDebug::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	//SetBackgroundColor(RGB(255,255,255));
	SetBackgroundColor(RGB(200,200,200));
	InitListCtrl();

	GLOBAL::g_IOCP.SetCallBack(ConnectProc, NULL, GoProc, NULL);

	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}

HBRUSH CPageDebug::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);

	// TODO:  在此更改 DC 的任何属性
	switch ( pWnd->GetDlgCtrlID() ) 
	{
	case CHECK_LOCK:
	case CHECK_HIJACK:
	case CHECK_RESUME_HIJACKING:
		{
#if 1 // 透明控件处理;
			pDC->SetBkMode(TRANSPARENT);

			CRect rc;
			pWnd->GetWindowRect(&rc);
			ScreenToClient(&rc);

			CDC* dc = GetDC();
			pDC->BitBlt(0,0,rc.Width(),rc.Height(),dc,rc.left,rc.top,SRCCOPY);  //把父窗口背景图片先画到按钮上

			ReleaseDC(dc);
			hbr = (HBRUSH) ::GetStockObject(NULL_BRUSH);
#endif
		}
		break;
	default:
		break; 
	}

	// TODO:  如果默认的不是所需画笔，则返回另一个画笔
	return hbr;
}

void CPageDebug::InitListCtrl()
{
	m_ctrlList.InsertColumn( 0, _T("序号"));
	m_ctrlList.SetColumnWidth( 0, 50 );
	m_ctrlList.InsertColumn( 1, _T("R"));
	m_ctrlList.SetColumnWidth( 1, 100 );
	m_ctrlList.InsertColumn( 2, _T("G"));
	m_ctrlList.SetColumnWidth( 2, 100);
	m_ctrlList.InsertColumn( 3, _T("B"));
	m_ctrlList.SetColumnWidth( 3, 100);
	m_ctrlList.InsertColumn( 4, _T("▲E实际值"));
	m_ctrlList.SetColumnWidth(4, 100);
}

HWND MyFindWindow(LPCTSTR lpClassName)
{
	HWND hWnd = NULL;
	if ( lpClassName == NULL || lpClassName[0] == '\0' )
		return hWnd;

	for (std::vector<GLOBAL::WND_INFO>::iterator it = GLOBAL::g_procWndInfo.vtWndInfo.begin(); it != GLOBAL::g_procWndInfo.vtWndInfo.end(); it++ )
	{
		// 返回第一个找到的类名;
		if ( _tcscmp(lpClassName, it->szClassName) == 0 )
		{
			hWnd = it->hWnd;
			break;
		}
	}

	return hWnd;
}

BOOL CPageDebug::ConnectProc(DATAHEADER *pHeader, MSG_INFO *pMsg)
{
	if ( m_pDlg == NULL )
		return FALSE;

	if ( pHeader->byMsgType == C2S_CONNECT )
		m_pDlg->SetDlgItemText(BTN_CONNECT, pMsg->byResult ? _T("断开连接") : _T("连接设备"));
	else if ( pHeader->byMsgType == C2S_DISCONNECT )
		m_pDlg->SetDlgItemText(BTN_CONNECT, pMsg->byResult ? _T("连接设备") : _T("断开连接"));
}

BOOL CPageDebug::GoProc(DATAHEADER *pHeader, MSG_INFO *pMsg)
{
	if ( !pHeader || !pMsg )
		return FALSE;

	// 获取时间;
	DWORD dwElapsed = _tstol((TCHAR*)pMsg->byData);
	// 获取Config.dat第七行;
	TCHAR szConfigPath[MAX_PATH] = {0};
	_stprintf_s(szConfigPath, _T("%s\\Config.dat"), GLOBAL::g_config.szOGCToolPath);
	if ( PathFileExists(szConfigPath) )
	{
		CFile file;
		CFileException excep;
		if ( file.Open(szConfigPath, CFile::modeRead, &excep) )
		{
			DWORD dwRead = 0;
			DWORD dwCount = 0;
			string strData;
			char szRead[MAX_PATH] = {0};
			DWORD dwLen = file.GetLength();
			while ( dwCount < dwLen )
			{
				dwRead = file.Read(szRead, MAX_PATH);
				strData.append(szRead, dwRead);
				dwCount += dwRead;
			}

			file.Close();

			// 获取第七行;
			int nPos=0;
			int nIndex = 0;
			while ( (nPos=strData.find('\r\n')) != std::string::npos )
			{
				if ( nIndex++ == 6 )
				{
					strData = strData.substr(0, nPos);
					break;
				}
				strData = strData.substr(nPos+2);				
			}

			// 输出的文件cvs路径;
			CString strSN;
			m_pDlg->GetDlgItemText(EDIT_SN, strSN);
			TCHAR szOutDataPath[MAX_PATH] = {0};
			_stprintf_s(szOutDataPath, _T("%s\\Output_%s_%s\\%s\\sRGB_32Patterns_.csv"), GLOBAL::g_config.szOGCToolPath, CharEncoding::ASCII2UNICODE(strData.c_str()), CTime::GetCurrentTime().Format("%Y%m%d").GetString(), strSN.GetString());
			if ( PathFileExists(szOutDataPath) )
			{
				// 文件存在,按行读取;
				std::string strFileData = GLOBAL::GetFileData(szOutDataPath);
				if ( strFileData.size() )
				{

				}
			}
		}
	}

	return FALSE;
}

void CPageDebug::OnBnClickedShowWnd()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strText;
	GetDlgItemText(BTN_SHOW_WND, strText);
	if ( strText == _T("显示窗口") )
	{
		ShowOGCWnd(SW_SHOW);
	}
	else
	{
		ShowOGCWnd(SW_HIDE);
	}
}

void CPageDebug::OnBnClickedHijack()
{
	// TODO: 在此添加控件通知处理程序代码
	BOOL bCheck = ((CButton*)GetDlgItem(CHECK_HIJACK))->GetCheck();
	if ( bCheck )
	{
		// 劫持窗口;
		MSG_INFO msg;
		DATAHEADER header;
		header.byMsgType = S2C_HIJACK;
		GLOBAL::g_IOCP.SendPackage(header, msg);
#ifdef _DEBUG
		MessageBox(_T("劫持窗口"), _T("提示"), MB_OK);
#endif
	}
	else
	{
		// 恢复窗口;
		MSG_INFO msg;
		DATAHEADER header;
		header.byMsgType = S2C_RESUME;
		GLOBAL::g_IOCP.SendPackage(header, msg);
#ifdef _DEBUG
		MessageBox(_T("恢复窗口"), _T("提示"), MB_OK);
#endif
	}
}

void CPageDebug::OnBnClickedTest()
{
	if ( GLOBAL::g_procWndInfo.bHijackStatus && GLOBAL::g_procWndInfo.bConnectStatus )
	{
		CString strSN;
		GetDlgItemText(EDIT_SN, strSN);
		if ( strSN.IsEmpty() )
		{
			MessageBox(_T("错误：SN不能空，请输入SN！"), _T("错误！"), MB_ICONERROR);
			return;
		}

		if ( strSN.GetLength() > 25 )
		{
			MessageBox(_T("错误：SN长度不能超过25！"), _T("错误！"), MB_ICONERROR);
			return;
		}

		// 设置SN下拉框长度;
		if ( g_hWnd_SN_Combobox )
		{
			TCHAR szLen[10] = {0};
			_ltot_s(strSN.GetLength(), szLen, 10, 10);
			::SendMessage(g_hWnd_SN_Combobox, CB_SELECTSTRING, 0, (LPARAM)&szLen);	// 此方法：设置句柄文本成功;
		}

		// 设置SN编辑框;
		if ( g_hWnd_SN )
		{
			TCHAR szSN[26] = {0};
			_stprintf_s(szSN, _T("%s"), strSN.GetString());
			::SendMessage(g_hWnd_SN, WM_SETTEXT, 0, (LPARAM)&szSN);
		}

		// 按钮Go按钮;
		HWND hWnd = GLOBAL::g_procWndInfo.GetButtonWnd(_T("Go"));
		if ( hWnd )
		{
			::PostMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
			Sleep(20);
			::PostMessage(hWnd, WM_LBUTTONUP, 0, 0);
		}

		GetDlgItem(BTN_TEST)->EnableWindow(FALSE);
		SetTimer(1, 500, NULL);
	}
	else
	{
		MessageBox(_T("未连接设备，请先按“连接设备”按钮！"), _T("提示"), MB_ICONWARNING);
	}
}

void CPageDebug::OnBnClickedConnect()
{
	CString strText;
	GetDlgItemText(BTN_CONNECT, strText);
	if ( strText == _T("连接设备") )
	{
		// 1、执行一次Connect按钮事件;
		//// 1.1、Connect成功后, 目标进程会返回消息;
		//// 1.2、若没有消息返回，需要判断是否在程序启动前已注入过并且Connect过。
		//// 1.3、要避免2的情况，主进程应该每次启动时，都向目标进程发送消息获取按钮状态。
		// 2、读取SN长度,设置一次SN长度下拉框;
		// 3、将SN赋值到目标进程SN编辑框;
		// 4、执行Go函数;
		// 5、劫持的Go函数未返回消息时,Test按钮和SN编辑框禁止输入;
		switch ( StartOGCTool() )
		{
		case -1:
			// 退出新开;
			break;
		case 0:
			// 新开失败;
			break;
		case 1:
			// 新开成功;
			{
				AfxGetApp()->GetMainWnd()->SetTimer(0, 500, NULL);
				MessageBox(_T("OGC程序启动中，请稍后再尝试，谢谢！"), _T("提示"), MB_OK|MB_ICONWARNING);
			}
			break;
		case 2:
			// 已存在进程;
			{
				// 执行Connect按钮;
				if ( GLOBAL::g_procWndInfo.bHijackStatus && !GLOBAL::g_procWndInfo.bConnectStatus )
				{
					HWND hWnd = GLOBAL::g_procWndInfo.GetButtonWnd(_T("Connect CA310"));
					if ( hWnd )
					{
						::PostMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
						Sleep(20);
						::PostMessage(hWnd, WM_LBUTTONUP, 0, 0);
					}

					SetDlgItemText(BTN_CONNECT, _T("连接中……"));
					//SetTimer(0, 500, NULL);
				}
				else
				{
					MessageBox(_T("设备已连接成功~"), _T("提示！"), MB_OK);
					SetDlgItemText(BTN_CONNECT, _T("断开设备"));
				}
			}
			break;
		default:
			break;
		}
	}
	else
	{
		HWND hWnd = GLOBAL::g_procWndInfo.GetButtonWnd(_T("Disconnect"));
		if ( hWnd )
		{
			::PostMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
			Sleep(20);
			::PostMessage(hWnd, WM_LBUTTONUP, 0, 0);
		}

		SetDlgItemText(BTN_CONNECT, _T("连接设备"));
	}	
}

void CPageDebug::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	switch ( nIDEvent )
	{
	case 0:
		{
			// 应该回调函数实现;
			Sleep(3000);

			if ( GLOBAL::g_procWndInfo.bConnectStatus )
			{
				//GetDlgItem(BTN_CONNECT)->EnableWindow(FALSE);
				SetDlgItemText(BTN_CONNECT, _T("断开连接"));
				// 按钮CheckFW按钮;
				HWND hWnd = GLOBAL::g_procWndInfo.GetButtonWnd(_T("Check FW"));
				if ( hWnd )
				{
					::PostMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
					Sleep(20);
					::PostMessage(hWnd, WM_LBUTTONUP, 0, 0);
				}
			}
			else
			{
				SetDlgItemText(BTN_CONNECT, _T("连接设备"));
			}

			KillTimer(nIDEvent);
		}
		break;
	case 1:
		{
			if ( GLOBAL::g_procWndInfo.dwProcId )
			{

			}
		}
		break;
	default:
		break;
	}
	CDialogEx::OnTimer(nIDEvent);
}
