
/********************************************************************************
* File : RTXCaptureDemoTool32Dlg.cpp
* Copyright 2014-2015, Raytrex Technology Co., Ltd.	All Rights Reserved.
*
* A Zebra DLL demo program that calls ZebraZ4U3DllWin32 APIs to communicating with
* Zebra capture-card through USB interface.
*
* Author: T.J.Hsu
* Date: 2014.03.20
* To use, modify, reproduce, and distribute this file is strictly forbidden
* without the prior written permission of Raytrex Technology Co., Ltd.
********************************************************************************/
// RTXCaptureDemoTool32Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "RTXCaptureDemoTool.h"
#include "RTXCaptureDemoToolDlg.h"
#include "TestStepScript.h"
#include "afxdialogex.h"
#include "resource.h"
#include "stdio.h"
#include "stdlib.h"

#define _10BitI2C_Addr			0x1
#define	_1byteRdSubAddr			0x2
#define	_2bytesRdSubAddr		0x4
#define	_3bytesRdSubAddr		0x6
#define	_IgnoreAckChking		0x8
#define	_ReadI2cDevice			0x80


void getProgramVersion(DWORD &dwMSVer, DWORD &dwLSVer);

#ifdef ZEBRAZ4U3DLLWIN32_EXPORTS
#define __USB_HANDLE_NOT_INIT__				-20
#define __USB_HANDLE_NOT_FOUND__			-21
#define __USB_DRV_OK_APP_NOT_READY__		-22

#define  __Zebra_Removed__			-2	// that open Zebra has removed by user
#define  __Zebra_Open_usable__		2	// a Zebra open by me and usable now
#define  __Zebra_Open_DrvNoApp__	1	// a Zebra open by me and usable now
#define __Zebra_NotYet_Init__		0

#define __OPT_STREAMING_OFF__		0		// a picture captured by mipi when a KickoffRunStep called. 
#define __OPT_STREAMING_ON__		1		// pictures captured by mipi after a KickoffRunStep called.

typedef  void(*LOG_HOOK_FUNC)(int hZhandle, char *pszLogMsg, unsigned long logCbArg);

void getProgramVersion(DWORD &dwMSVer, DWORD &dwLSVer);

int lookingViewableZebras(void);
void freeZebrasInfoListQueue(void);

__PZEBRA_BOARD_INFO__ getZebraBoardInfo(__HZHANDLE__ hZhandle, wchar_t **pUsbPortName);
int InitMipiUsbNotifyWin(HWND hWndApp, DWORD idThrdHandle);
void StopMipiUsbNotifyWin(void);
int QueryZebraAppState(__HZHANDLE__ hZhandle);
__HZHANDLE__ bInitUsbDevice(int nZebraIndexInQueue, __HZHANDLE__ *phZhandle);
void CloseUsbDevice(__HZHANDLE__ hZhandle);
wchar_t *getActivePortNname(__HZHANDLE__ hZhandle, int *nPortNumber);
int qureyZebraTestStepCount(__HZHANDLE__ hZhandle);
BOOL KickoffRunStep(__HZHANDLE__ hZhandle, int iRunId, int ExAct, int nOption);
int getRunStepstate(__HZHANDLE__ hZhandle, PSRUNSTEPSTATE pRunStepState);
int GrabImageRequest(__HZHANDLE__ hZhandle, short imgStartIndx, short imgEndIndx, unsigned char imgGotOpCode, unsigned char bWaitSnapped);
int getPicture2File(__HZHANDLE__ hZhandle, char *pictureFileName, UCHAR *errCode);
ULONG getPicture2Buffer(__HZHANDLE__ hZhandle, unsigned char *pPicBuffer, ULONG pPicBufSiz, UCHAR *errCode);
int resetZebraFromApp(__HZHANDLE__ hZhandle, int *resultState);
void resetZebraByUSBDev(__HZHANDLE__ hZhandle);
int getZebraStatus(__HZHANDLE__ hZhandle, PSZEBRASTATUS presultStatus);
int getZebraSWVersion(__HZHANDLE__ hZhandle, PSZEBRAVERSION psZebraVersion);
//int DownloadTestProcedures(char *TestProcedureName);
int getCaptureCardTestProcedures(__HZHANDLE__ hZhandle, char *szGotSettingName, char *pCardName, char *pSensorName, char *pSWVersion);
void createCaptureTestingTemplate(char *pCardName, char *pSensorName, char *pSWVersion, char *pTstName, int testSteps, ...);
int I2cRawDataWrite(__HZHANDLE__ hZhandle, UCHAR cfgByte, USHORT i2cAddr, char *pTxtWrData, int txtLen);
int I2cRawDataRead(__HZHANDLE__ hZhandle, UCHAR cfgByte, USHORT i2cAddr, char *pTxtSubAddr, int nReadLen, UCHAR *pReadBuffer);

int getMaxAliasRunSteps2AllowDownload(__HZHANDLE__ hZhandle);
int getAliasRunStepsCntJustDownload(__HZHANDLE__ hZhandle);
char *get1stDownloadStepAliasName(__HZHANDLE__ hZhandle);
char *getNextDownloadStepAliasName(__HZHANDLE__ hZhandle);
int getRunStepIdFromDownloadAliasList(__HZHANDLE__ hZhandle, char *pAliasTestName);
int RunStepByAliasName(char *pAliasStepName, int nOption);

int SearchingRegisterFiles(__HZHANDLE__ hZhandle, char *pScriptName, LOG_HOOK_FUNC log_cbFunc, unsigned long logCbArg);
int LoadRegisterFiles(__HZHANDLE__ hZhandle, char *pRegFilesDir, LOG_HOOK_FUNC log_cbFunc, unsigned long logCbArg);
int getRegisterStepsCntJustDownload(__HZHANDLE__ hZhandle);
char *get1stDownloadRegisterStepName(__HZHANDLE__ hZhandle);
char *getNextDownloadRegisterStepName(__HZHANDLE__ hZhandle);
int getRunStepIdFromDownloadRegisterStepList(__HZHANDLE__ hZhandle, char *pTestName);
int RunTestStepFile(__HZHANDLE__ hZhandle, char *pTestStepName, int nOption);
int RunRegisterFile(__HZHANDLE__ hZhandle, char *pRegisterName, int nOption);
void SetZebraSetting(__HZHANDLE__ hZhandle, char *pZebraSetting);

#else
#include "ZebraZ4U3DllWin32.h"
#endif 

HWND g_hWndApp;
static wchar_t *g_lptstr = NULL;
static char    *g_lpstr = NULL;
static SZEBRAVERSION sZebraVersion;

LPTSTR lpAnsi2lpWChar(LPSTR lpstr);
LPSTR  lpWChar2lpAnsi(LPTSTR lptstr);

#define		__NO_ERROR_EXCHG__				0
#define		__ILLEGAL_STRM_DATA_SIZE__		-1
#define		__FAIL_ALLOCATED_RAW10_BUFFER__	-2

unsigned char *RawStrmToRaw10(unsigned char *pImgStrmBuffer, ULONG lImgStrmSiz, ULONG *lRaw10Siz, int *errState);
void freeRawExchgBuffer(unsigned char *pRawStrmBuffer);

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

BOOL CALLBACK ProgressProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
static DWORD WINAPI DialogMsgThread(LPVOID Arg);

static DWORD WINAPI GetImageThread(LPVOID Arg);

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// Dialog Data
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CRTXCaptureDemoToolDlg dialog



CRTXCaptureDemoToolDlg::CRTXCaptureDemoToolDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CRTXCaptureDemoToolDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CRTXCaptureDemoToolDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);

	DDX_Control(pDX, IDC_CHK_IGNORE, m_chkIgnoreAck);
	DDX_Control(pDX, IDC_CHK_RAW8TO10, m_chkRaw8To10);
	DDX_Control(pDX, IDC_CHK_SCRIPT_RAW8TO10, m_scriptchkRaw8To10);
	DDX_Control(pDX, IDC_CHK_SHOWTIME, m_chkShowTime);

	DDX_Control(pDX, IDC_RDO_READ, m_RDO_Read);
	DDX_Control(pDX, IDC_RDO_WRITE, m_RDO_Write);

	DDX_Control(pDX, IDC_RDO_APP, m_RDO_App);
	DDX_Control(pDX, IDC_RDO_USB, m_RDO_Usb);

	DDX_Control(pDX, IDC_RDO_ALIAS, m_RDO_Alais);
	DDX_Control(pDX, IDC_RDO_FILE, m_RDO_File);

	DDX_Control(pDX, IDC_CMB_ADDR_BITS, m_Combo_I2CAddrBits);
	DDX_Control(pDX, IDC_CMB_RD_SUBADDR, m_Combo_I2CRdSubAddrBytes);
	DDX_Control(pDX, IDC_CMB_ALIAS_NAME, m_Combo_AliasNames);
}

BEGIN_MESSAGE_MAP(CRTXCaptureDemoToolDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, &CRTXCaptureDemoToolDlg::OnBnClickedOk)
	ON_BN_CLICKED(IDCANCEL, &CRTXCaptureDemoToolDlg::OnBnClickedCancel)
	ON_BN_CLICKED(IDC_BTN_DWLD_OK, &CRTXCaptureDemoToolDlg::OnBnClickedBtnDwldOk)
	ON_BN_CLICKED(IDC_BTN_GOT_TESTSTEP, &CRTXCaptureDemoToolDlg::OnBnClickedBtnGotTeststep)
	ON_BN_CLICKED(IDC_BTN_CREATE_TEMPLATE, &CRTXCaptureDemoToolDlg::OnBnClickedBtnCreateTemplate)
	ON_BN_CLICKED(IDC_BTN_I2C, &CRTXCaptureDemoToolDlg::OnBnClickedBtnI2c)
	ON_CBN_SELCHANGE(IDC_CMB_RD_SUBADDR, &CRTXCaptureDemoToolDlg::OnCbnSelchangeCmbRdSubaddr)
	ON_BN_CLICKED(IDC_RDO_WRITE, &CRTXCaptureDemoToolDlg::OnBnClickedRdoWrite)
	ON_BN_CLICKED(IDC_RDO_READ, &CRTXCaptureDemoToolDlg::OnBnClickedRdoRead)
	ON_BN_CLICKED(IDC_BTN_RESET, &CRTXCaptureDemoToolDlg::OnBnClickedBtnReset)
	ON_BN_CLICKED(IDC_BTN_ZEBRA_STATUS, &CRTXCaptureDemoToolDlg::OnBnClickedBtnZebraStatus)
	ON_BN_CLICKED(IDC_RDO_APP, &CRTXCaptureDemoToolDlg::OnBnClickedRdoApp)
	ON_BN_CLICKED(IDC_RDO_USB, &CRTXCaptureDemoToolDlg::OnBnClickedRdoUsb)
	ON_BN_CLICKED(IDC_BTN_ALIAS, &CRTXCaptureDemoToolDlg::OnBnClickedBtnAlias)
	ON_BN_CLICKED(IDC_BTN_SEL_SCRIPT, &CRTXCaptureDemoToolDlg::OnBnClickedBtnSelScript)
	ON_BN_CLICKED(IDC_BTN_OPEN_LOAD_FILES, &CRTXCaptureDemoToolDlg::OnBnClickedBtnOpenLoadFiles)
	ON_BN_CLICKED(IDC_RDO_ALIAS, &CRTXCaptureDemoToolDlg::OnBnClickedRdoAlias)
	ON_BN_CLICKED(IDC_RDO_FILE, &CRTXCaptureDemoToolDlg::OnBnClickedRdoFile)
	ON_BN_CLICKED(IDC_BTN_GET_IMG, &CRTXCaptureDemoToolDlg::OnBnClickedBtnGetImg)
	ON_BN_CLICKED(IDC_BTN_RUN_SCRIPT, &CRTXCaptureDemoToolDlg::OnBnClickedBtnRunScript)
END_MESSAGE_MAP()


// CRTXCaptureDemoToolDlg message handlers

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

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);

	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here
	DWORD dwDllMSVer, dwDllLSVer;
	TCHAR  dllName[_MAX_FNAME + _MAX_EXT];

	getProgramVersion(m_dwMSVer, m_dwLSVer);
	
	getDllVersion(dllName, &dwDllMSVer, &dwDllLSVer);
	
	_swprintf(m_szProgVersion, L"RTXCaptureDemoTool32(V%d.%d.%d.%d) - %s(V%d.%d.%d.%d)", HIWORD(m_dwMSVer), LOWORD(m_dwMSVer), HIWORD(m_dwLSVer), LOWORD(m_dwLSVer),
		dllName, HIWORD(dwDllMSVer), LOWORD(dwDllMSVer), HIWORD(dwDllLSVer), LOWORD(dwDllLSVer));

	SetWindowText(m_szProgVersion);

	InitMipiUsbNotifyWin(g_hWndApp = this->m_hWnd, NULL);
	
	m_hwndProgress = NULL;
	m_hDialogThrd = (HANDLE)CreateThread(NULL, 0, DialogMsgThread, (PVOID)this, 0, &m_ThrdId);
	while (m_hwndProgress == NULL)
		Sleep(200);

	pGrabCtrl = (__PGRAB_IMAGES)malloc(sizeof(__GRAB_IMAGES__));
	memset(pGrabCtrl, 0, sizeof(__GRAB_IMAGES__));
	pGrabCtrl->bExit = FALSE;
	pGrabCtrl->hGrabThrdCmd = CreateEvent(NULL, FALSE, FALSE, NULL);
	pGrabCtrl->hGrabThrdRslt = CreateSemaphore(NULL, 0, 100, NULL);
	pGrabCtrl->hGrabThrd = (HANDLE)CreateThread(NULL, 0, GetImageThread, (PVOID)this, 0, &pGrabCtrl->hThrdId);


	__PZEBRA_BOARD_INFO__ pZebraBoardInfo;
	__HZHANDLE__ locTmpZHandle;

	// looking all Zebras
	m_FoundZebras = lookingViewableZebras();

	m_Zhandle = __USB_HANDLE_NOT_INIT__;
	m_AvailableIndx = -1;
	// To find 1st Zebra available zebra index
	for (int i = 0; i < m_FoundZebras; i++)
	{
		pZebraBoardInfo = getZebraBoardInfo((__HZHANDLE__)i, NULL);
		if (pZebraBoardInfo->nZebraStatus == __Zebra_NotYet_Init__)
		{
			m_AvailableIndx = i;
			break;
		}
	}


	m_MaxTestStep = 0;
	if (m_FoundZebras && (m_Zhandle = bInitUsbDevice(m_AvailableIndx, &locTmpZHandle)) >= 0)
	{
		TCHAR wBuf[128], *pActivePortName;
		int     nZebraPortNr;

		pActivePortName = getActivePortNname(m_Zhandle, &nZebraPortNr);
		swprintf(wBuf, 128, L"Zebra-P#%d: %s", nZebraPortNr, pActivePortName);
		SetDlgItemText(IDC_STC_ZEBRA_ID, wBuf);

		swprintf(wBuf, 128, L"%d", m_MaxTestStep = qureyZebraTestStepCount(m_Zhandle));

		SetDlgItemText(IDC_TEST_STEP_CNT, (LPCTSTR)wBuf);

		m_RDO_App.SetCheck(BST_CHECKED);
		m_RDO_Usb.SetCheck(BST_UNCHECKED);

		if (m_MaxTestStep == 0)
		{
			CWnd *pWnd = GetDlgItem(IDOK);
			pWnd->EnableWindow(FALSE);
		}
		//.
		if (getZebraSWVersion(m_Zhandle, &sZebraVersion) > 0)
		{
			char szDatabuf[256];
			sprintf(szDatabuf, "Zebra(V%d.%d.%d.%d), Kernel(V%d.%d.%d.%d)", sZebraVersion.zebraMajorVer, sZebraVersion.zebraMinorVer, sZebraVersion.zebraBuildNumber, sZebraVersion.zebraRevisionNumber,
				sZebraVersion.kernelMajorVer, sZebraVersion.kernelMinorVer, sZebraVersion.kernelBuildNumber, sZebraVersion.kernelRevisionNumber);
			SetDlgItemText(IDC_EDT_ZEBRA_VERSION, lpAnsi2lpWChar(szDatabuf));
		}
	}
	else
	{
		m_RDO_App.SetCheck(BST_UNCHECKED);
		if (m_Zhandle == __USB_DRV_OK_APP_NOT_READY__)
		{
			// try monitor the device APP start ...
			MessageBox(L"Application on USB device isn't start! Please start it");
			::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, __APP_MONITOR_START__, locTmpZHandle);
			m_RDO_Usb.SetCheck(BST_CHECKED);
		}
		else
		{
			m_RDO_Usb.SetCheck(BST_UNCHECKED);
		}

		CWnd *pWnd = GetDlgItem(IDOK);
		pWnd->EnableWindow(FALSE);
	}

	SetDlgItemText(IDC_RUN_ID, (LPTSTR)"1");
	SetDlgItemText(IDC_EDT_SAVE, (LPTSTR)L"RTXCapture");

	SetDlgItemText(IDC_DOWNLOAD_NAME, (LPTSTR)L"RTXCaptureTestSteps.ZebraCfg");

	SetDlgItemText(IDC_EDT_GOT_NAME, (LPTSTR)L"RTXCapture");

	SetDlgItemText(IDC_EDT_RESET_REPORT, (LPTSTR)L"");

	SetDlgItemText(IDC_EDT_TEMPLATE_NAME, (LPTSTR)L"RTXCapture");

	SetDlgItemText(IDC_EDT_TMPL_NUM, (LPTSTR)"6");

	SetDlgItemText(IDC_EDT_EXTACT, (LPTSTR)"0");

	SetDlgItemText(IDC_EDT_RUN_OPT, (LPTSTR)"0");

	SetDlgItemText(IDC_EDT_GET_IMG_INDX, (LPTSTR)"0");

	SetDlgItemText(IDC_EDT_GRAB_TO, (LPTSTR)"0");

	m_chkRaw8To10.SetCheck(BST_UNCHECKED);
	m_scriptchkRaw8To10.SetCheck(BST_UNCHECKED);
	m_chkShowTime.SetCheck(BST_UNCHECKED);

	if (m_Zhandle < 0)
	{
		CWnd *pWnd = GetDlgItem(IDOK);
		pWnd->EnableWindow(FALSE);

		pWnd = GetDlgItem(IDC_BTN_ALIAS);
		pWnd->EnableWindow(FALSE);

		pWnd = GetDlgItem(IDC_BTN_DWLD_OK);
		pWnd->EnableWindow(FALSE);

		pWnd = GetDlgItem(IDC_BTN_GOT_TESTSTEP);
		pWnd->EnableWindow(FALSE);

		pWnd = GetDlgItem(IDC_BTN_I2C);
		pWnd->EnableWindow(FALSE);

		pWnd = GetDlgItem(IDC_BTN_RESET);
		if (m_RDO_App.GetCheck() == BST_CHECKED || m_RDO_Usb.GetCheck() == BST_CHECKED)
			pWnd->EnableWindow(TRUE);
		else
			pWnd->EnableWindow(FALSE);

		pWnd = GetDlgItem(IDC_BTN_ZEBRA_STATUS);
		pWnd->EnableWindow(FALSE);

		pWnd = GetDlgItem(IDC_BTN_GET_IMG);
		pWnd->EnableWindow(FALSE);

		pWnd = GetDlgItem(IDC_BTN_RUN_SCRIPT);
		pWnd->EnableWindow(FALSE);
	}

	m_Combo_I2CAddrBits.AddString(L"7 bits addr");
	m_Combo_I2CAddrBits.AddString(L"10 bits addr");
	m_Combo_I2CAddrBits.SetCurSel(0);

	m_Combo_I2CRdSubAddrBytes.AddString(L"No RD sub addr");
	m_Combo_I2CRdSubAddrBytes.AddString(L"1 byte");
	m_Combo_I2CRdSubAddrBytes.AddString(L"2 bytes");
	m_Combo_I2CRdSubAddrBytes.AddString(L"3 bytes");
	m_Combo_I2CRdSubAddrBytes.SetCurSel(0);

	//m_Combo_AliasNames.AddString(L"<None>");
	m_RDO_Alais.SetCheck(BST_CHECKED);
	m_RDO_File.SetCheck(BST_UNCHECKED);
	SetDlgItemText(IDC_CMB_ALIAS_NAME, L"<None>");


	m_RDO_Read.SetCheck(BST_UNCHECKED);
	m_RDO_Write.SetCheck(BST_CHECKED);

	SetDlgItemText(IDC_EDT_I2C_ADDR, L"0x3c");
	
	SetDlgItemText(IDC_EDT_SUB_ADDR, L"0x31,0x3");

	SetDlgItemText(IDC_EDT_RDWRLEN, L"2");

	CWnd *pWnd = GetDlgItem(IDC_EDT_SUB_ADDR);
	pWnd->EnableWindow(FALSE);

	if (0 == getAliasRunStepsCntJustDownload(m_Zhandle))
	{
		pWnd = GetDlgItem(IDC_BTN_ALIAS);
		pWnd->EnableWindow(FALSE);
	}

	// For I2c write
	pWnd = GetDlgItem(IDC_EDT_RDWRLEN);
	pWnd->EnableWindow(FALSE);
	pWnd->ShowWindow(SW_HIDE);

	pWnd = GetDlgItem(IDC_RDBYTES);
	pWnd->EnableWindow(FALSE);
	pWnd->ShowWindow(SW_HIDE);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CRTXCaptureDemoToolDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CRTXCaptureDemoToolDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CRTXCaptureDemoToolDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CRTXCaptureDemoToolDlg::OnBnClickedOk()
{
	// TODO: Add your control notification handler code here
	// Get the run Id on 
	wchar_t wsBuf[16];
	char *pszBuf;
	int iRunId;

	::ShowWindow(m_hwndProgress, SW_SHOW);
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)L"run test step");

	GetDlgItemText(IDC_RUN_ID, wsBuf, 16);

	pszBuf = lpWChar2lpAnsi(wsBuf);
	sscanf(pszBuf, "%d", &iRunId);

	if (iRunId <= m_MaxTestStep)
	{
		int nExtAct, nOption = 0;
		SRUNSTEPSTATE sRunResult;

		GetDlgItemText(IDC_EDT_EXTACT, wsBuf, 16);
		pszBuf = lpWChar2lpAnsi(wsBuf);
		sscanf(pszBuf, "%d", &nExtAct);

		GetDlgItemText(IDC_EDT_RUN_OPT, wsBuf, 16);
		pszBuf = lpWChar2lpAnsi(wsBuf);
		sscanf(pszBuf, "%d", &nOption);

		KickoffRunStep(m_Zhandle, iRunId, nExtAct, nOption);

		if (getRunStepstate(m_Zhandle, &sRunResult))
		{
			int i, j;
			char		szShowBuffer[16];

			if (sRunResult.runResultState == __Sta_step_snapping__ && sRunResult.resultType == __AppendData__ && sRunResult.appDataLen)
			{
				// snapping count
				sprintf(szShowBuffer, "%d", sRunResult.appendBuffer[0]);
				SetDlgItemText(IDC_STC_RUN_IMG_CNT, lpAnsi2lpWChar(szShowBuffer));
				SetDlgItemInt(IDC_EDT_GRAB_TO, sRunResult.appendBuffer[0] - 1);
			}
			else if (sRunResult.runResultState == __Sta_step_succeed__ && sRunResult.resultType == __SnapPicture__)
			{
				sprintf(szShowBuffer, "%d", sRunResult.snapCnt);
				SetDlgItemText(IDC_STC_RUN_IMG_CNT, lpAnsi2lpWChar(szShowBuffer));
				SetDlgItemInt(IDC_EDT_GRAB_TO, sRunResult.snapCnt - 1);
			}
			else if (sRunResult.runResultState == __Sta_step_succeed__ && sRunResult.resultType == __AppendData__)
			{
				::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"run test steps");
				::ShowWindow(m_hwndProgress, SW_HIDE);

				if (sRunResult.appDataLen)
				{
					int k;
					wchar_t wzdatabuf[256 * 5];

					// dump as string
					for (k = 0; k < sRunResult.appDataLen; k++)
					{
						wzdatabuf[k] = sRunResult.appendBuffer[k];
					}
					// switch to second line
					wzdatabuf[k++] = '\r';
					wzdatabuf[k++] = '\n';
					wzdatabuf[k++] = 0;

					// dump data as hexdecimal at second line
					for (i = 0; i < sRunResult.appDataLen; i++)
					{
						k = wcslen(wzdatabuf);
						swprintf(wzdatabuf + k, L"0x%02x ", sRunResult.appendBuffer[i]);
					}
					MessageBox(wzdatabuf);
				}
			}
			::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"run test steps");
			::ShowWindow(m_hwndProgress, SW_HIDE);
		}
	}
	else
	{
		::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"download test steps");
		::ShowWindow(m_hwndProgress, SW_HIDE);
	}
	//CDialogEx::OnOK();
}


void CRTXCaptureDemoToolDlg::OnBnClickedCancel()
{
	// TODO: Add your control notification handler code here
	
	// show free all open Zebra
	// this version only close one handle
	// for (.....) all open handles
		CloseUsbDevice(m_Zhandle);
	
	freeZebrasInfoListQueue();

	StopMipiUsbNotifyWin();

	if (g_lptstr) free(g_lptstr);

	if (g_lpstr) free(g_lpstr);

	::PostMessage(m_hwndProgress, WM_CLOSE, 0, -1L);
	WaitForSingleObject(m_hDialogThrd, INFINITE);		// Wait thread exit

	pGrabCtrl->bExit = TRUE;
	SetEvent(pGrabCtrl->hGrabThrdCmd);
	WaitForSingleObject(pGrabCtrl->hGrabThrd, INFINITE);
	CloseHandle(pGrabCtrl->hGrabThrdCmd);
	CloseHandle(pGrabCtrl->hGrabThrdRslt);
	free(pGrabCtrl);

	CDialogEx::OnCancel();
}

void CRTXCaptureDemoToolDlg::displayDownloadedInfo(void)
{
	wchar_t strDownloadCnt[32];

	swprintf(strDownloadCnt, 128, L"%d", m_MaxTestStep);

	SetDlgItemText(IDC_TEST_STEP_CNT, strDownloadCnt);

	if (m_RDO_Alais.GetCheck() == BST_CHECKED)
	{
		if (getAliasRunStepsCntJustDownload(m_Zhandle))
		{
			char *pAlias;

			CWnd *pWnd = GetDlgItem(IDOK);
			pWnd->EnableWindow(TRUE);

			pWnd = GetDlgItem(IDC_BTN_ALIAS);
			pWnd->EnableWindow(TRUE);

			pWnd = GetDlgItem(IDC_BTN_GOT_TESTSTEP);
			pWnd->EnableWindow(TRUE);

			// set run alais combo box ...
			for (int i = m_Combo_AliasNames.GetCount() - 1; i >= 0; i--)
				m_Combo_AliasNames.DeleteString(i);

			pAlias = get1stDownloadStepAliasName(m_Zhandle);
			if (pAlias)
			{
				wchar_t *pwAliasName;
				BOOL bFistName = FALSE;
				do
				{
					pwAliasName = lpAnsi2lpWChar(pAlias);

					m_Combo_AliasNames.AddString(pwAliasName);
					if (bFistName == FALSE)
					{
						SetDlgItemText(IDC_CMB_ALIAS_NAME, pwAliasName);
						bFistName = TRUE;
					}
				} while (pAlias = getNextDownloadStepAliasName(m_Zhandle));
			}
			else
			{
				SetDlgItemText(IDC_CMB_ALIAS_NAME, L"<None>");
			}
		}
	}
	else if (m_RDO_File.GetCheck() == BST_CHECKED)
	{
		if (getRegisterStepsCntJustDownload(m_Zhandle))
		{
			char *pRegisterFile;

			CWnd *pWnd = GetDlgItem(IDOK);
			pWnd->EnableWindow(TRUE);

			pWnd = GetDlgItem(IDC_BTN_ALIAS);
			pWnd->EnableWindow(TRUE);

			pWnd = GetDlgItem(IDC_BTN_GOT_TESTSTEP);
			pWnd->EnableWindow(TRUE);

			// set run alais combo box ...
			for (int i = m_Combo_AliasNames.GetCount() - 1; i >= 0; i--)
				m_Combo_AliasNames.DeleteString(i);

			pRegisterFile = get1stDownloadRegisterStepName(m_Zhandle);
			if (pRegisterFile)
			{
				wchar_t *pwAliasName;
				BOOL bFistName = FALSE;
				do
				{
					pwAliasName = lpAnsi2lpWChar(pRegisterFile);

					m_Combo_AliasNames.AddString(pwAliasName);
					if (bFistName == FALSE)
					{
						SetDlgItemText(IDC_CMB_ALIAS_NAME, pwAliasName);
						bFistName = TRUE;
					}
				} while (pRegisterFile = getNextDownloadRegisterStepName(m_Zhandle));
			}
			else
			{
				SetDlgItemText(IDC_CMB_ALIAS_NAME, L"<None>");
			}
		}
	}
}


void CRTXCaptureDemoToolDlg::OnBnClickedBtnDwldOk()
{
	// TODO: Add your control notification handler code here
	int i, j;
	wchar_t strDownloadName[128];
	char *pszBuf;

	::ShowWindow(m_hwndProgress, SW_SHOW);
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)L"download test steps");

	GetDlgItemText(IDC_DOWNLOAD_NAME, strDownloadName, 128);

	pszBuf = lpWChar2lpAnsi(strDownloadName);
		
	LoadRegisterFiles(m_Zhandle, pszBuf, NULL, 0);

	m_MaxTestStep = qureyZebraTestStepCount(m_Zhandle);

	// Get the string
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"download test steps");
	::ShowWindow(m_hwndProgress, SW_HIDE);
#if 0
	swprintf(strDownloadName, 128, L"%d", m_MaxTestStep);

	SetDlgItemText(IDC_TEST_STEP_CNT, strDownloadName);

	if (m_RDO_Alais.GetCheck() == BST_CHECKED)
	{
		if (getAliasRunStepsCntJustDownload(m_Zhandle))
		{
			char *pAlias;

			CWnd *pWnd = GetDlgItem(IDOK);
			pWnd->EnableWindow(TRUE);

			pWnd = GetDlgItem(IDC_BTN_ALIAS);
			pWnd->EnableWindow(TRUE);

			pWnd = GetDlgItem(IDC_BTN_GOT_TESTSTEP);
			pWnd->EnableWindow(TRUE);

			// set run alais combo box ...
			for (int i = m_Combo_AliasNames.GetCount() - 1; i >= 0; i--)
				m_Combo_AliasNames.DeleteString(i);

			pAlias = get1stDownloadStepAliasName(m_Zhandle);
			if (pAlias)
			{
				wchar_t *pwAliasName;
				BOOL bFistName = FALSE;
				do
				{
					pwAliasName = lpAnsi2lpWChar(pAlias);

					m_Combo_AliasNames.AddString(pwAliasName);
					if (bFistName == FALSE)
					{
						SetDlgItemText(IDC_CMB_ALIAS_NAME, pwAliasName);
						bFistName = TRUE;
					}
				} while (pAlias = getNextDownloadStepAliasName(m_Zhandle));
			}
			else
			{
				SetDlgItemText(IDC_CMB_ALIAS_NAME, L"<None>");
			}
		}
	}
	else if (m_RDO_File.GetCheck() == BST_CHECKED)
	{
		if (getRegisterStepsCntJustDownload(m_Zhandle))
		{
			char *pRegisterFile;

			CWnd *pWnd = GetDlgItem(IDOK);
			pWnd->EnableWindow(TRUE);

			pWnd = GetDlgItem(IDC_BTN_ALIAS);
			pWnd->EnableWindow(TRUE);

			pWnd = GetDlgItem(IDC_BTN_GOT_TESTSTEP);
			pWnd->EnableWindow(TRUE);

			// set run alais combo box ...
			for (int i = m_Combo_AliasNames.GetCount() - 1; i >= 0; i--)
				m_Combo_AliasNames.DeleteString(i);

			pRegisterFile = get1stDownloadStepRegisterStepName();
			if (pRegisterFile)
			{
				wchar_t *pwAliasName;
				BOOL bFistName = FALSE;
				do
				{
					pwAliasName = lpAnsi2lpWChar(pRegisterFile);

					m_Combo_AliasNames.AddString(pwAliasName);
					if (bFistName == FALSE)
					{
						SetDlgItemText(IDC_CMB_ALIAS_NAME, pwAliasName);
						bFistName = TRUE;
					}
				} while (pRegisterFile = getNextDownloadStepRegisterStepName());
			}
			else
			{
				SetDlgItemText(IDC_CMB_ALIAS_NAME, L"<None>");
			}
		}
	}
#else
	displayDownloadedInfo();
#endif
}




void CRTXCaptureDemoToolDlg::OnBnClickedBtnGotTeststep()
{
	// TODO: Add your control notification handler code here
	int i, j;
	wchar_t strGotSettingName[128];
	char *pszBuf;

	::ShowWindow(m_hwndProgress, SW_SHOW);
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)L"get test steps");

	GetDlgItemText(IDC_EDT_GOT_NAME, strGotSettingName, 128);

	pszBuf = lpWChar2lpAnsi (strGotSettingName);
	
	getCaptureCardTestProcedures(m_Zhandle, pszBuf, "Zebra4", "OV5640", lpWChar2lpAnsi(m_szProgVersion));	// Captrure card & sensor name are temporary

	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"get test steps");
	::ShowWindow(m_hwndProgress, SW_HIDE);
}

DWORD sndCnt = 0;
void CRTXCaptureDemoToolDlg::OnBnClickedBtnCreateTemplate()
{
	// TODO: Add your control notification handler code here
	int i, j, iSteps;
	wchar_t strTemplateName[128];
	char *pszBuf;

	::ShowWindow(m_hwndProgress, SW_SHOW);
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)L"Create test steps");

	GetDlgItemText(IDC_EDT_TMPL_NUM, strTemplateName, 128);
	pszBuf = lpWChar2lpAnsi (strTemplateName);
	sscanf(pszBuf, "%d", &iSteps);


	GetDlgItemText(IDC_EDT_TEMPLATE_NAME, strTemplateName, 128);
	pszBuf = lpWChar2lpAnsi (strTemplateName);

	createCaptureTestingTemplate("Zebra4", "OV5640", lpWChar2lpAnsi(m_szProgVersion), pszBuf, iSteps, -1);

	//::SendDlgItemMessage(m_hwndProgress, IDC_PROGRESS_NAME, WM_USER+3, 0, -1L);
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Create test steps");
	::ShowWindow(m_hwndProgress, SW_HIDE);

	//wsprintf((LPTSTR)strTemplateName, L"\nsend count %d\n", sndCnt++);
	//OutputDebugString((LPTSTR)strTemplateName);

}


void CRTXCaptureDemoToolDlg::OnBnClickedBtnI2c()
{
	UCHAR cfgByte = 0;
	int i2cAddr;
	int i, j;
	wchar_t strI2cInfoBuffer[512];
	char szI2cInfoBuffer[64];
	char *pszBuf;
	wchar_t *pwstrBuf;

	// TODO: Add your control notification handler code here
	int AddrBitsId = m_Combo_I2CAddrBits.GetCurSel();
	int subAddBytes = m_Combo_I2CRdSubAddrBytes.GetCurSel();


	if (AddrBitsId == 1)
		cfgByte |= _10BitI2C_Addr;


	GetDlgItemText(IDC_EDT_I2C_ADDR, strI2cInfoBuffer, 128);
	
	pszBuf = lpWChar2lpAnsi (strI2cInfoBuffer);
	
	sscanf(pszBuf, "0x%x", &i2cAddr);

	switch (subAddBytes)
	{
	case 0:
		break;
	case 1:
		cfgByte |= _1byteRdSubAddr;
		break;
	case 2:
		cfgByte |= _2bytesRdSubAddr;
		break;
	case 3:
		cfgByte |= _3bytesRdSubAddr;
		break;
	}

	if (subAddBytes)
	{
		GetDlgItemText(IDC_EDT_SUB_ADDR, strI2cInfoBuffer, 128);
		
		pszBuf = lpWChar2lpAnsi (strI2cInfoBuffer);

		strcpy (szI2cInfoBuffer, pszBuf);
	}
	else
		szI2cInfoBuffer[0] = 0x0;

	if (m_chkIgnoreAck.GetCheck() == BST_CHECKED)
	{
		cfgByte |= _IgnoreAckChking;
	}

	if (m_RDO_Read.GetCheck() == BST_CHECKED)
	{
		char szI2cTxtData[2048], szReadBuffer[512];
		int  nReadLen, nRdLen;
		// I2c Read ...
		cfgByte |= _ReadI2cDevice;

		GetDlgItemText(IDC_EDT_RDWRLEN, strI2cInfoBuffer, 128);
		
		pszBuf = lpWChar2lpAnsi (strI2cInfoBuffer);
		
		sscanf(pszBuf, "%d", &nReadLen);
		
		// int I2cRawDataRead(UCHAR cfgByte, USHORT i2cAddr, char *pTxtSubAddr, int nReadLen, UCHAR *pReadBuffer);
		nRdLen = I2cRawDataRead(m_Zhandle, cfgByte, i2cAddr, szI2cInfoBuffer, nReadLen, (UCHAR *)szReadBuffer);
		// --- data ...
		szI2cTxtData[0] = 0x0;
		if (nRdLen)
			sprintf(szI2cTxtData, "0x%x", szReadBuffer[0]);

		for (i = 1; i < nRdLen; i++)
		{
			j = strlen(szI2cTxtData);
			sprintf(szI2cTxtData+j, ", 0x%x", szReadBuffer[i]);
		}
		
		// To wide string 
		pwstrBuf = lpAnsi2lpWChar(szI2cTxtData);
		
		SetDlgItemText(IDC_EDT_RDWR_DATA, pwstrBuf);
	}
	else
	{
		// I2c write ...
		GetDlgItemText(IDC_EDT_RDWR_DATA, strI2cInfoBuffer, 512);
		pszBuf = lpWChar2lpAnsi (strI2cInfoBuffer);
		//
		// int I2cRawDataWrite(UCHAR cfgByte, USHORT i2cAddr, char *pTxtWrData, int txtLen);
		I2cRawDataWrite(m_Zhandle, cfgByte, i2cAddr, pszBuf, strlen(pszBuf));
	}
}


void CRTXCaptureDemoToolDlg::OnCbnSelchangeCmbRdSubaddr()
{
	// TODO: Add your control notification handler code here
	CWnd *pWnd = GetDlgItem(IDC_EDT_SUB_ADDR);
	if (m_Combo_I2CRdSubAddrBytes.GetCurSel())
	{
		pWnd->EnableWindow(TRUE);
	}
	else
		pWnd->EnableWindow(FALSE);
}


LRESULT CRTXCaptureDemoToolDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	// TODO: Add your specialized code here and/or call the base class
	__HZHANDLE__ hZhandle, locTmpZHandle;
	int			 nBoardId;
	__PZEBRA_BOARD_INFO__ pZebraBoardInfo;

	switch (message)
	{
	case WM_MIPI_DEVICEARRIVAL:
		hZhandle = (__HZHANDLE__)wParam;
		nBoardId = (int)lParam;

		if (m_Zhandle >= 0)
			pZebraBoardInfo = getZebraBoardInfo(m_Zhandle, NULL);
		else
			pZebraBoardInfo = NULL;

		if (m_Zhandle < 0 ||
			(pZebraBoardInfo && pZebraBoardInfo->nZebraStatus != __Zebra_Open_DrvNoApp__ &&
			 pZebraBoardInfo->nZebraStatus != __Zebra_Open_usable__))	// AP doesn't start now! ex. removed!
		{
			::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Reset Zebra");
			::ShowWindow(m_hwndProgress, SW_HIDE);

			// open this board
			if ((m_Zhandle = bInitUsbDevice(hZhandle, &locTmpZHandle)) >= 0)
			{
				wchar_t wBuf[128], *pActivePortName;
				int     nZebraPortNr;

				CWnd *pWnd = GetDlgItem(IDOK);

				pActivePortName = getActivePortNname(m_Zhandle, &nZebraPortNr);
				swprintf(wBuf, 128, L"Zebra-P#%d: %s", nZebraPortNr, pActivePortName);
				SetDlgItemText(IDC_STC_ZEBRA_ID, wBuf);

				swprintf(wBuf, 128, L"%d", m_MaxTestStep = qureyZebraTestStepCount(m_Zhandle));

				SetDlgItemText(IDC_TEST_STEP_CNT, wBuf);

				if (getZebraSWVersion(m_Zhandle, &sZebraVersion) > 0)
				{
					char szDatabuf[256];
					sprintf(szDatabuf, "Zebra(V%d.%d.%d.%d), Kernel(V%d.%d.%d.%d)", sZebraVersion.zebraMajorVer, sZebraVersion.zebraMinorVer, sZebraVersion.zebraBuildNumber, sZebraVersion.zebraRevisionNumber,
						sZebraVersion.kernelMajorVer, sZebraVersion.kernelMinorVer, sZebraVersion.kernelBuildNumber, sZebraVersion.kernelRevisionNumber);
					SetDlgItemText(IDC_EDT_ZEBRA_VERSION, lpAnsi2lpWChar(szDatabuf));
				}

				if (m_MaxTestStep)
					pWnd->EnableWindow(TRUE);

				pWnd = GetDlgItem(IDC_BTN_ALIAS);
				if (getAliasRunStepsCntJustDownload(m_Zhandle))
					pWnd->EnableWindow(TRUE);
				else
					pWnd->EnableWindow(FALSE);

				pWnd = GetDlgItem(IDC_BTN_DWLD_OK);
				pWnd->EnableWindow(TRUE);

				if (m_MaxTestStep)
				{
					pWnd = GetDlgItem(IDC_BTN_GOT_TESTSTEP);
					pWnd->EnableWindow(TRUE);
				}

				pWnd = GetDlgItem(IDC_BTN_I2C);
				pWnd->EnableWindow(TRUE);

				pWnd = GetDlgItem(IDC_BTN_RESET);
				pWnd->EnableWindow(TRUE);

				pWnd = GetDlgItem(IDC_BTN_ZEBRA_STATUS);
				pWnd->EnableWindow(TRUE);

				pWnd = GetDlgItem(IDC_BTN_GET_IMG);
				pWnd->EnableWindow(TRUE);

				pWnd = GetDlgItem(IDC_BTN_RUN_SCRIPT);
				pWnd->EnableWindow(TRUE);

				SetDlgItemText(IDC_EDT_RESET_REPORT, L"");
				SetDlgItemText(IDC_EDT_ZEBRA_STATUS_RESULT, L"");

				m_RDO_App.SetCheck(BST_CHECKED);
				m_RDO_Usb.SetCheck(BST_UNCHECKED);
			}
			else
			{
				CWnd *pWnd;

				m_RDO_App.SetCheck(BST_UNCHECKED);
				if (m_Zhandle == __USB_DRV_OK_APP_NOT_READY__)
				{
					MessageBox(L"Application on USB device isn't start! Please start it");

					// try monitor the device APP start ...
					::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, __APP_MONITOR_START__, locTmpZHandle);

					m_RDO_Usb.SetCheck(BST_CHECKED);
				}
				else
				{
					m_RDO_Usb.SetCheck(BST_UNCHECKED);
				}

				pWnd = GetDlgItem(IDC_BTN_RESET);
				if (m_RDO_App.GetCheck() == BST_CHECKED || m_RDO_Usb.GetCheck() == BST_CHECKED)
					pWnd->EnableWindow(TRUE);
				else
					pWnd->EnableWindow(FALSE);

			}
		}
		break;

	case WM_MIPI_DEVICEREMOVECOMPLETE:
		{
		hZhandle = (__HZHANDLE__)wParam;
		if (hZhandle == m_Zhandle)	// current active zebra removed
		{
			CWnd *pWnd = GetDlgItem(IDOK);
			pWnd->EnableWindow(FALSE);

			pWnd = GetDlgItem(IDC_BTN_ALIAS);
			pWnd->EnableWindow(FALSE);

			pWnd = GetDlgItem(IDC_BTN_DWLD_OK);
			pWnd->EnableWindow(FALSE);

			pWnd = GetDlgItem(IDC_BTN_GOT_TESTSTEP);
			pWnd->EnableWindow(FALSE);

			pWnd = GetDlgItem(IDC_BTN_I2C);
			pWnd->EnableWindow(FALSE);

			pWnd = GetDlgItem(IDC_BTN_RESET);
			pWnd->EnableWindow(FALSE);

			pWnd = GetDlgItem(IDC_BTN_ZEBRA_STATUS);
			pWnd->EnableWindow(FALSE);

			pWnd = GetDlgItem(IDC_BTN_GET_IMG);
			pWnd->EnableWindow(FALSE);

			pWnd = GetDlgItem(IDC_BTN_RUN_SCRIPT);
			pWnd->EnableWindow(FALSE);

			SetDlgItemText(IDC_EDT_ZEBRA_VERSION, L"");
			SetDlgItemText(IDC_STC_ZEBRA_ID, L"");

			pZebraBoardInfo = getZebraBoardInfo(hZhandle, NULL);
			pZebraBoardInfo->nZebraStatus = __Zebra_Removed__;
			CloseUsbDevice(hZhandle);
			m_Zhandle = __USB_HANDLE_NOT_FOUND__;
			::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, __APP_MONITOR_STOP__, 0);
		}	//.if -
		}
		break;

	case WM_CTLCOLORSTATIC:
		if (m_Zhandle >= 0)
		{
			if (IDC_STC_ZEBRA_ID == ::GetDlgCtrlID((HWND)lParam))
			{
				TCHAR *pActivePortName;
				int     nZebraPortNr;
				pActivePortName = getActivePortNname(m_Zhandle, &nZebraPortNr);
				switch (nZebraPortNr)
				{
				case 1:
					return (BOOL)::CreateSolidBrush(RGB(255, 0, 0));
				case 2:
					return (BOOL)::CreateSolidBrush(RGB(0, 255, 0));
				case 3:
					return (BOOL)::CreateSolidBrush(RGB(0, 0, 255));
				case 4:
					return (BOOL)::CreateSolidBrush(RGB(10, 20, 10));
				default:
					break;
				}

			}
		}
		break;
	}

	return CDialogEx::WindowProc(message, wParam, lParam);
}


void getProgramVersion(DWORD &dwMSVer, DWORD &dwLSVer)
{
	TCHAR 		szFullPath[MAX_PATH];
	unsigned    uiSize;
	DWORD		dwVerHnd;
	DWORD		dwVerInfoSize;
	DWORD		dwResult;
	BYTE        *prgbVersionInfo = NULL;
	VS_FIXEDFILEINFO  *lpVSFixedFileInfo = NULL;

	dwMSVer = 0xffffffff;
	dwLSVer = 0xffffffff;

	// Get version information from the application
	GetModuleFileName(NULL, szFullPath, sizeof(szFullPath));
	dwVerInfoSize = GetFileVersionInfoSize(szFullPath, &dwVerHnd);
	if (dwVerInfoSize)
	{
		prgbVersionInfo = (LPBYTE)GlobalAlloc(GPTR, dwVerInfoSize);
		if (NULL == prgbVersionInfo)
		{
			goto Finish;
		}

		// Read version stamping info
		if (GetFileVersionInfo(szFullPath, dwVerHnd, dwVerInfoSize, prgbVersionInfo))
		{
			// get the value for Translation
			if (VerQueryValue(prgbVersionInfo, L"\\", (LPVOID*)&lpVSFixedFileInfo, &uiSize) && (uiSize != 0))
			{
				dwMSVer = lpVSFixedFileInfo->dwFileVersionMS;
				dwLSVer = lpVSFixedFileInfo->dwFileVersionLS;
			}
		}
		else
		{
			dwResult = GetLastError();
			goto Finish;
		}
	}
	else
	{
		dwResult = GetLastError();
	}

Finish:
	if (NULL != prgbVersionInfo)
		GlobalFree(prgbVersionInfo);
}


void CRTXCaptureDemoToolDlg::OnBnClickedRdoWrite()
{
	// TODO: Add your control notification handler code here
	if (m_RDO_Write.GetCheck() == BST_CHECKED)
	{
		CWnd *pWnd = GetDlgItem(IDC_EDT_RDWRLEN);
		pWnd->EnableWindow(FALSE);
		pWnd->ShowWindow(SW_HIDE);

		pWnd = GetDlgItem(IDC_RDBYTES);
		pWnd->EnableWindow(FALSE);
		pWnd->ShowWindow(SW_HIDE);
	}
}


void CRTXCaptureDemoToolDlg::OnBnClickedRdoRead()
{
	// TODO: Add your control notification handler code here
	if (m_RDO_Read.GetCheck() == BST_CHECKED)
	{
		CWnd *pWnd = GetDlgItem(IDC_EDT_RDWRLEN);
		pWnd->EnableWindow(TRUE);
		pWnd->ShowWindow(SW_SHOW);

		pWnd = GetDlgItem(IDC_RDBYTES);
		pWnd->EnableWindow(TRUE);
		pWnd->ShowWindow(SW_SHOW);
	}
}


WCHAR g_progressBuffer[256] = { 0 };
BOOL CALLBACK ProgressProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	int nDots;
	static __HZHANDLE__ sTmpZHandle;
	//WCHAR dbgBuffer[128];

	switch (message)
	{
	case WM_MIPI_PROGRESS_MONITOR:
		//		wsprintf(dbgBuffer, L"\nreceived msg:%d(WM_USER+3=%d)\n", message, WM_USER+3);
		//		OutputDebugString(dbgBuffer);
		switch (LOWORD(wParam))
		{
		case IDC_PROGRESS_NAME:
			SetDlgItemText(hwndDlg, IDC_PROGRESS_NAME, (LPTSTR)lParam);
			SetTimer(hwndDlg, __Timer_Dots__, 160, NULL);
			break;
		case IDC_PROGRESS_DOT:
			KillTimer(hwndDlg, __Timer_Dots__);
			break;

		case __APP_MONITOR_START__:
			sTmpZHandle = lParam;
			SetTimer(hwndDlg, __Timer_MonitorApp__, 500, NULL);
			break;
		case __APP_MONITOR_STOP__:
			KillTimer(hwndDlg, __Timer_MonitorApp__);
			break;
		}
		return TRUE;

	case WM_TIMER:
		switch (wParam)
		{
		case __Timer_Dots__:
			wcscat(g_progressBuffer, L">>");
			SetDlgItemText(hwndDlg, IDC_PROGRESS_DOT, g_progressBuffer);
			nDots = wcslen(g_progressBuffer);
			if (nDots >= 20)
			{
				g_progressBuffer[0] = 0x0;
			}
			break;

		case __Timer_MonitorApp__:

			if (1 == QueryZebraAppState(sTmpZHandle))
			{
				__PZEBRA_BOARD_INFO__ pZebraBoardInfo;
				KillTimer(hwndDlg, __Timer_MonitorApp__);

				pZebraBoardInfo = getZebraBoardInfo(sTmpZHandle, NULL);

				CloseUsbDevice(sTmpZHandle);

				// (WPARAM) hZhandle, (LPARAM) zebraBoardId
				PostMessage(g_hWndApp, WM_MIPI_DEVICEARRIVAL, sTmpZHandle, pZebraBoardInfo->nZebraBoardId);		// To close mipi device
			}
			break;
		}
		return TRUE;
	case WM_CLOSE:
		DestroyWindow(hwndDlg);
		break;
	}
	return FALSE;
}

static DWORD WINAPI DialogMsgThread(LPVOID Arg)
{
	BOOL bRet;
	CRTXCaptureDemoToolDlg *pToolDlg = (CRTXCaptureDemoToolDlg *)Arg;
	MSG msg;

	pToolDlg->m_hwndProgress = ::CreateDialog(GetModuleHandle(NULL),
		MAKEINTRESOURCE(IDD_PROGRESSING),
		pToolDlg->m_hWnd,
		(DLGPROC)ProgressProc);

	//::ShowWindow(pToolDlg->m_hwndProgress, SW_SHOW);

	// Window message loop to handle NX USB device notification, till NxUsbEndBgWinLib be called
	while (GetMessage(&msg, pToolDlg->m_hwndProgress, 0, 0) >	0)
	{
		DispatchMessage(&msg);
	}

	return 0;
}

void CRTXCaptureDemoToolDlg::OnBnClickedBtnReset()
{
	// TODO: Add your control notification handler code here
	int state;

	::ShowWindow(m_hwndProgress, SW_SHOW);
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)L"Reset Zebra");

	if (m_RDO_App.GetCheck() == BST_CHECKED)
	{
		if (resetZebraFromApp(m_Zhandle, &state) > 0)
		{
			//if (state == 0)
			//SetDlgItemText(IDC_EDT_RESET_REPORT, L"reset Zebra ...");
			//else
			//	SetDlgItemText(IDC_EDT_RESET_REPORT, L"reset Zebra - fail");
			m_Zhandle = __USB_HANDLE_NOT_INIT__;
		}
		//else
		//	SetDlgItemText(IDC_EDT_RESET_REPORT, L"Can't reset Zebra");

	}
	else if (m_RDO_Usb.GetCheck() == BST_CHECKED)
	{
		resetZebraByUSBDev(m_Zhandle);
		m_Zhandle = __USB_HANDLE_NOT_INIT__;
	}
	//::PostMessage(m_hwndProgress, WM_USER + 3, IDC_PROGRESS_DOT, (LPARAM)L"Reset Zebra");
	//::ShowWindow(m_hwndProgress, SW_HIDE);
}


void CRTXCaptureDemoToolDlg::OnBnClickedBtnZebraStatus()
{
	// TODO: Add your control notification handler code here
	SZEBRASTATUS zebraState;

	::ShowWindow(m_hwndProgress, SW_SHOW);
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)L"Zebra status");

	if (getZebraStatus(m_Zhandle, &zebraState) > 0)
	{
		switch (zebraState.zebraState)
		{
		case __std_sysReady__:
			SetDlgItemText(IDC_EDT_ZEBRA_STATUS_RESULT, L"Zebra - ready");
			break;
		case __std_sysBusy__:
			SetDlgItemText(IDC_EDT_ZEBRA_STATUS_RESULT, L"Zebra - Busy");
			break;
		case __std_sysError__:
			SetDlgItemText(IDC_EDT_ZEBRA_STATUS_RESULT, L"Zebra - error");
			break;
		}

	}
	else
		SetDlgItemText(IDC_EDT_ZEBRA_STATUS_RESULT, L"Can't get Zebra status");

	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Zebra status");
	::ShowWindow(m_hwndProgress, SW_HIDE);
}





void CRTXCaptureDemoToolDlg::OnBnClickedRdoApp()
{
	// TODO: Add your control notification handler code here
	if (m_Zhandle >= 0)
	{
		return;
		//m_RDO_App.SetCheck(BST_CHECKED);
	}
	else if (m_Zhandle == __USB_DRV_OK_APP_NOT_READY__)
	{
		m_RDO_App.SetCheck(BST_UNCHECKED);
		m_RDO_Usb.SetCheck(BST_CHECKED);
	}
	else
		m_RDO_App.SetCheck(BST_UNCHECKED);

}


void CRTXCaptureDemoToolDlg::OnBnClickedRdoUsb()
{
	// TODO: Add your control notification handler code here
	if (m_Zhandle >= 0 || m_Zhandle == __USB_DRV_OK_APP_NOT_READY__)
	{
		m_RDO_Usb.SetCheck(BST_CHECKED);
	}
}


void CRTXCaptureDemoToolDlg::OnBnClickedBtnAlias()
{
	// TODO: Add your control notification handler code here
	wchar_t strBuf[16];
	char *pszBuf;
	int iRunId;
	int nHadDownloadItems;

	::ShowWindow(m_hwndProgress, SW_SHOW);
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)L"Run alias test step");

	if (m_RDO_Alais.GetCheck() == BST_CHECKED)
		nHadDownloadItems = getAliasRunStepsCntJustDownload(m_Zhandle);
	else if (m_RDO_File.GetCheck() == BST_CHECKED)
		nHadDownloadItems = getRegisterStepsCntJustDownload(m_Zhandle);

	if (nHadDownloadItems)
	{
		int i;
		wchar_t wAlias[128];
		
		GetDlgItemText(IDC_CMB_ALIAS_NAME, wAlias, 128);

		pszBuf = lpWChar2lpAnsi (wAlias);
		if (m_RDO_Alais.GetCheck() == BST_CHECKED)
			iRunId = getRunStepIdFromDownloadAliasList(m_Zhandle, pszBuf);
		else if (m_RDO_File.GetCheck() == BST_CHECKED)
			iRunId = getRunStepIdFromDownloadRegisterStepList(m_Zhandle, pszBuf);

		if (iRunId >=0)
		{
			int nExtAct, nOption = 0;
			SRUNSTEPSTATE sRunResult;
			char szShowBuffer[16];

			// Show the run id 
			sprintf(szShowBuffer, "%d", iRunId);
			SetDlgItemText(IDC_RUN_ID, lpAnsi2lpWChar(szShowBuffer));

			GetDlgItemText(IDC_EDT_EXTACT, strBuf, 16);
			pszBuf = lpWChar2lpAnsi (strBuf);
			sscanf(pszBuf, "%d", &nExtAct);

			GetDlgItemText(IDC_EDT_RUN_OPT, strBuf, 16);
			pszBuf = lpWChar2lpAnsi (strBuf);
			sscanf(pszBuf, "%d", &nOption);

			KickoffRunStep(m_Zhandle, iRunId, nExtAct, nOption);

			if (getRunStepstate(m_Zhandle, &sRunResult))
			{
				int i, j;


				if (sRunResult.runResultState == __Sta_step_snapping__ && sRunResult.resultType == __AppendData__ && sRunResult.appDataLen)
				{
					// snapping count
					sprintf(szShowBuffer, "%d", sRunResult.appendBuffer[0]);
					SetDlgItemText(IDC_STC_RUN_IMG_CNT, lpAnsi2lpWChar(szShowBuffer));
					SetDlgItemInt(IDC_EDT_GRAB_TO, sRunResult.appendBuffer[0] - 1);
				}
				else if (sRunResult.runResultState == __Sta_step_succeed__ && sRunResult.resultType == __SnapPicture__)
				{
					sprintf(szShowBuffer, "%d", sRunResult.snapCnt);
					SetDlgItemText(IDC_STC_RUN_IMG_CNT, lpAnsi2lpWChar(szShowBuffer));
					SetDlgItemInt(IDC_EDT_GRAB_TO, sRunResult.snapCnt - 1);
				}
				else if (sRunResult.runResultState == __Sta_step_succeed__ && sRunResult.resultType == __AppendData__)
				{
					::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"run test steps");
					::ShowWindow(m_hwndProgress, SW_HIDE);

					if (sRunResult.appDataLen)
					{
						int k;
						wchar_t wzdatabuf[256 * 5];


						for (k = 0; k < sRunResult.appDataLen; k++)
						{
							wzdatabuf[k] = sRunResult.appendBuffer[k];
						}
						// switch to second line
						wzdatabuf[k++] = '\r';
						wzdatabuf[k++] = '\n';
						wzdatabuf[k++] = 0;

						// Copy data to wide char
						for (i = 0; i < sRunResult.appDataLen; i++)
						{
							k = wcslen(wzdatabuf);
							swprintf(wzdatabuf + k, L"0x%02x ", sRunResult.appendBuffer[i]);
						}
						MessageBox(wzdatabuf);
					}
				}
				::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"run test steps");
				::ShowWindow(m_hwndProgress, SW_HIDE);
			}
		}
		else
		{
			::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"download test steps");
			::ShowWindow(m_hwndProgress, SW_HIDE);
		}
	}
	else
	{
		::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"download test steps");
		::ShowWindow(m_hwndProgress, SW_HIDE);
	}
}

void CRTXCaptureDemoToolDlg::OnBnClickedBtnGetImg()
{
	// TODO: Add your control notification handler code here
	int				nRet;
	SRUNSTEPSTATE	sRunResult;

#if 1
	HWND hwndOwner;
	RECT rc, rcDlg, rcOwner;
	DWORD dtime;

	// Get the owner window and dialog box rectangles. 
	if ((hwndOwner = ::GetParent(m_hwndProgress)) == NULL)
	{
		hwndOwner = ::GetDesktopWindow();
	}
	::GetWindowRect(hwndOwner, &rcOwner);
	::GetWindowRect(m_hwndProgress, &rcDlg);
	CopyRect(&rc, &rcOwner);

	// Offset the owner and dialog box rectangles so that right and bottom 
	// values represent the width and height, and then offset the owner again 
	// to discard space taken up by the dialog box. 

	OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
	OffsetRect(&rc, -rc.left, -rc.top);
	OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);

	// The new position is the sum of half the remaining space and the owner's 
	// original position. 
	::SetWindowPos(m_hwndProgress,
		HWND_BOTTOM,
		rcOwner.left - (rc.right * 3),
		rcOwner.top + (rc.bottom / 2),
		0, 0,          // Ignores size arguments. 
		SWP_NOSIZE);
#endif

	::ShowWindow(m_hwndProgress, SW_SHOW);
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)L"Grab image");

	if (m_chkShowTime.GetCheck() == BST_CHECKED)
		dtime = GetTickCount();
	
	// Check image snapping state
	while ((nRet = getRunStepstate(m_Zhandle, &sRunResult)) > 0)
	{
		/* if (sRunResult.runResultState == __Sta_step_snapping__)
		sRunResult.resultType == __AppendData__
		sRunResult.appDataLen = 2;
		sRunResult.appendBuffer [0] = how many image are snapped
		sRunResult.appendBuffer [1] = has snapped images count
		*/
		if (sRunResult.runResultState == __Sta_None_Imgage__)
		{
			// error, no image pic is snapped
			::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Grab image");
			::ShowWindow(m_hwndProgress, SW_HIDE);
			return;
		}
		else if (sRunResult.runResultState == __Sta_step_snapping__ && sRunResult.resultType == __AppendData__)
		{
			// sRunResult.appendBuffer [0] --- picture count
			// sRunResult.appendBuffer [1] --- snapped pictured count
			continue;
		}
		else if (sRunResult.runResultState == __Sta_step_succeed__ && sRunResult.resultType == __SnapPicture__)
		{
			// sRunResult.snapCnt = g_snappedPicCnt;									// simulate a snap count
			// sRunResult.pSnaPicSiz[i] = size of every picture
			break;
		}
	}	// while - check state

	// Get from assigned index to last 
	if (sRunResult.runResultState == __Sta_step_succeed__ && sRunResult.resultType == __SnapPicture__)
	{
		int			nImagStartIndx, nImgEndIndx;
		wchar_t		strBuf[16];
		char		*pszBuf;
		SYSTEMTIME	LocalTime;
		wchar_t		strBmpFileName[256];
		char 		bmpFileName[128];
		UCHAR		errCode;
		int k;

		GetDlgItemText(IDC_EDT_GET_IMG_INDX, strBuf, 16);
		pszBuf = lpWChar2lpAnsi(strBuf);
		sscanf(pszBuf, "%d", &nImagStartIndx);

		GetDlgItemText(IDC_EDT_GRAB_TO, strBuf, 16);
		pszBuf = lpWChar2lpAnsi(strBuf);
		sscanf(pszBuf, "%d", &nImgEndIndx);

		if (nImgEndIndx >= sRunResult.snapCnt) sRunResult.snapCnt - 1;
		else if (nImgEndIndx < 0) nImgEndIndx = 0;

		GrabImageRequest(m_Zhandle, nImagStartIndx, nImgEndIndx, __Grab_opt_noneOperation__, 1);	//	to wait

		// Here only show none image extra operation, to get assigned pictures
		for (k = 0; k < ((nImgEndIndx - nImagStartIndx) + 1); k++)
		{
			// Get pic now ....
#if 0	// to get picture to buffer
			UCHAR *pPic;
			ULONG  uPicGotSiz;

			pPic = (UCHAR *)malloc(sRunResult.pSnaPicSiz[k]);

			uPicGotSiz = getPicture2Buffer(m_Zhandle, pPic, sRunResult.pSnaPicSiz[k], &errCode);
			if (m_chkRaw8To10.GetCheck() == BST_CHECKED)
			{

			}
			// .....
#else
			// Generate a new capture file name by datetime
			GetLocalTime(&LocalTime);

			// Get user provide result name
			GetDlgItemText(IDC_EDT_SAVE, strBmpFileName, 128);

			pszBuf = lpWChar2lpAnsi(strBmpFileName);

			sprintf(bmpFileName, "%s%02d%02d-%02d%02d%02d.%03d.raw", pszBuf, LocalTime.wMonth, LocalTime.wDay, LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond, LocalTime.wMilliseconds);

			//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
#if 0
			{
				int h;
				wchar_t debString[256];
				wchar_t *pwstrBuf;

				pwstrBuf = lpAnsi2lpWChar(bmpFileName);

				wsprintf(debString, L"SNAP file: \"%s\"\n", pwstrBuf);
				OutputDebugString(debString);
			}
#endif
			////////////////////////////////////////////////
			getPicture2File(m_Zhandle, bmpFileName, &errCode);
			if (errCode)
			{
				if (__Error_snapping__ != errCode)	// if snapping try get once
					break;							// error to break

				do
				{
					Sleep(100);			// Wait till data got
				} while (getPicture2File(m_Zhandle, bmpFileName, &errCode) && errCode == __Error_snapping__);
			}
			//
			if (m_chkRaw8To10.GetCheck() == BST_CHECKED)
			{
				FILE *fileRaw8;
				UCHAR *pRaw8Data, *pRaw10Data;

				if (fileRaw8 = fopen(bmpFileName, "r+b"))	// read and write
				{
					long fileSiz;

					fseek(fileRaw8, 0, SEEK_END);
					fileSiz = ftell(fileRaw8);
					fseek(fileRaw8, 0, SEEK_SET);

					pRaw8Data = (UCHAR *)malloc(fileSiz);
					if (pRaw8Data)
					{
						int lrdItem = fread(pRaw8Data, fileSiz, 1, fileRaw8);

						if (lrdItem)
						{
							ULONG uRaw10Size;
							int   errExchg;

							pRaw10Data = RawStrmToRaw10(pRaw8Data, fileSiz, &uRaw10Size, &errExchg);
							if (errExchg == __NO_ERROR_EXCHG__)
							{
								fseek(fileRaw8, 0, SEEK_SET);		
								fwrite (pRaw10Data, uRaw10Size, 1, fileRaw8);

								freeRawExchgBuffer(pRaw10Data);
							}
						}
						free(pRaw8Data);
					}
					fclose(fileRaw8);
				}
			}
#endif
		}	// for - sRunResult.snapCnt

		if (m_chkShowTime.GetCheck() == BST_CHECKED)
			dtime = GetTickCount() - dtime;

		::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Grab image");
		::ShowWindow(m_hwndProgress, SW_HIDE);
		
		if (m_chkShowTime.GetCheck() == BST_CHECKED)
		{
			char msgTime[128];
			sprintf(msgTime, "Total excution time %d milli-seconds", dtime);
			::MessageBoxA(NULL, msgTime, "GetPictures time", MB_OK);
		}
	}
}


LPTSTR lpAnsi2lpWChar(LPSTR lpstr)
{
	int i, len = strlen(lpstr) + 1;
	
	if (g_lptstr) free(g_lptstr);

	g_lptstr = (wchar_t *)malloc(len * sizeof(wchar_t));

	for (i = 0; i < len; i++)
		g_lptstr[i] = lpstr[i];

	return g_lptstr;
}


LPSTR  lpWChar2lpAnsi(LPTSTR lptstr)
{
	int i, len = wcslen(lptstr) + 1;

	if (g_lpstr) free(g_lpstr);

	g_lpstr = (char *)malloc(len * sizeof(CHAR));

	for (i = 0; i < len; i++)
		g_lpstr[i] = lptstr[i];

	return g_lpstr;
}

void CRTXCaptureDemoToolDlg::OnBnClickedBtnSelScript()
{
	// TODO: Add your control notification handler code here
	CString  strFile = L"*.script;*.Script";
	TestStepScript dlgTestScrptFile(TRUE, L"script", strFile);
	CString strMessage;

	int nModal = dlgTestScrptFile.DoModal();

	if ((IDOK == nModal))
	{
		int rtval;
		CString s = dlgTestScrptFile.GetPathName(), s1;
		SetDlgItemText(IDC_EDT_SCRIPT_NAME, s);
	}
}


void CRTXCaptureDemoToolDlg::OnBnClickedBtnOpenLoadFiles()
{
	// TODO: Add your control notification handler code here
	// TODO: Add your control notification handler code here
	CString  strFile;
	TestStepScript dlgDownloadFile(TRUE);// , L"text", strFile);
	OPENFILENAME& ofn = dlgDownloadFile.GetOFN();
	int nModal;

	strFile = L"*.ZebraCfg";
	ofn.lpstrFile = strFile.GetBuffer(MAX_PATH + 1);

	nModal = dlgDownloadFile.DoModal();

	if ((IDOK == nModal))
	{
		int rtval;
		CString s = dlgDownloadFile.GetPathName();
		SetDlgItemText(IDC_DOWNLOAD_NAME, s);
	}
}


void CRTXCaptureDemoToolDlg::OnBnClickedRdoAlias()
{
	// TODO: Add your control notification handler code here
	if (getAliasRunStepsCntJustDownload(m_Zhandle))
	{
		char *pAlias;

		CWnd *pWnd = GetDlgItem(IDOK);
		pWnd->EnableWindow(TRUE);

		pWnd = GetDlgItem(IDC_BTN_ALIAS);
		pWnd->EnableWindow(TRUE);

		pWnd = GetDlgItem(IDC_BTN_GOT_TESTSTEP);
		pWnd->EnableWindow(TRUE);

		// set run alais combo box ...
		for (int i = m_Combo_AliasNames.GetCount() - 1; i >= 0; i--)
			m_Combo_AliasNames.DeleteString(i);

		pAlias = get1stDownloadStepAliasName(m_Zhandle);
		if (pAlias)
		{
			wchar_t *pwAliasName;
			BOOL bFistName = FALSE;
			do
			{
				pwAliasName = lpAnsi2lpWChar(pAlias);

				m_Combo_AliasNames.AddString(pwAliasName);
				if (bFistName == FALSE)
				{
					SetDlgItemText(IDC_CMB_ALIAS_NAME, pwAliasName);
					bFistName = TRUE;
				}
			} while (pAlias = getNextDownloadStepAliasName(m_Zhandle));
		}
		else
		{
			SetDlgItemText(IDC_CMB_ALIAS_NAME, L"<None>");
		}
	}
}


void CRTXCaptureDemoToolDlg::OnBnClickedRdoFile()
{
	// TODO: Add your control notification handler code here
	if (getRegisterStepsCntJustDownload(m_Zhandle))
	{
		char *pRegisterFile;

		CWnd *pWnd = GetDlgItem(IDOK);
		pWnd->EnableWindow(TRUE);

		pWnd = GetDlgItem(IDC_BTN_ALIAS);
		pWnd->EnableWindow(TRUE);

		pWnd = GetDlgItem(IDC_BTN_GOT_TESTSTEP);
		pWnd->EnableWindow(TRUE);

		// set run alais combo box ...
		for (int i = m_Combo_AliasNames.GetCount() - 1; i >= 0; i--)
			m_Combo_AliasNames.DeleteString(i);

		pRegisterFile = get1stDownloadRegisterStepName(m_Zhandle);
		if (pRegisterFile)
		{
			wchar_t *pwAliasName;
			BOOL bFistName = FALSE;
			do
			{
				pwAliasName = lpAnsi2lpWChar(pRegisterFile);

				m_Combo_AliasNames.AddString(pwAliasName);
				if (bFistName == FALSE)
				{
					SetDlgItemText(IDC_CMB_ALIAS_NAME, pwAliasName);
					bFistName = TRUE;
				}
			} while (pRegisterFile = getNextDownloadRegisterStepName(m_Zhandle));
		}
		else
		{
			SetDlgItemText(IDC_CMB_ALIAS_NAME, L"<None>");
		}
	}
}




////////////////////////////////////////////////////////////////////////////////////////////
// __loadRegisterSetting_external__ is option for testing SearchingRegisterFiles() setup in script file.

//#define __loadRegisterSetting_external__

/* comment code: "//" or '#' */
char* isSkipScriptCommentOrWhiteLine(char *chLineData, int sizOfBuf)
{
	char *pData = chLineData;
	char *pCmt, *pLast = chLineData + sizOfBuf;
	int i;

	while (*pData && *pData <= 0x20 && pData < pLast) pData++;

	if (*pData == 0 || pData >= pLast) return NULL;

	if ('/' == pData[0] && '/' == pData[1] || pData[0] == '#') return NULL;

	// Truncate the comments section ...
	pCmt = (char *)memchr(pData, '/', sizOfBuf - (pData - chLineData));
	if (pCmt && *(pCmt + 1) == '/')
	{
		do
		{
			*pCmt++ = 0x0;
		} while (pCmt < pLast);
	}
	i = strlen(pData) - 1;

	while (pData[i] <= 0x20) pData[i--] = 0x0;

	return pData;
}

char *getScriptFuncName(char *pzScriptLine, char **pzArgs)
{
	char *pArg, *pTmp;

	while (*pzScriptLine <= 0x20) pzScriptLine++;

	pArg = pTmp = (char *)memchr((char *)pzScriptLine, '(', strlen(pzScriptLine));

	if (pTmp)
	{
		if (pTmp) pTmp--;

		while (pTmp != pzScriptLine && *pTmp <= 0x20) pTmp--;
		pTmp++;
		*pTmp = 0x0;

		// Handle arguments
		pArg++;
		while (*pArg <= 0x20) pArg++;
		pTmp = (char *)memchr((char *)pArg, ')', strlen(pArg));

		if (pTmp)
		{
			*pTmp = 0x0;
			while (pArg != pTmp && *pTmp <= 0x20) pTmp--;
			pTmp++;
			*pTmp = 0x0;
		}

		*pzArgs = pArg;
	}
	return pzScriptLine;
}

static char imgSavName[256];
void SaveImage2File(char *imageSav2File)
{
	strcpy(imgSavName, imageSav2File);
}




static FILE *logFile = NULL;
static LONG ljustMilliSeconds = 0;
void myLogfunc(int hZhandle, char *logPrintOutString, unsigned long logCbArg)
{
	SYSTEMTIME	LocalTime;
	LONG deltaMilliSeconds = 0;

	if (logFile)
	{
		LONG ldayMilliSeconds;
		
		GetLocalTime(&LocalTime);
		ldayMilliSeconds = LocalTime.wHour * 60 * 60 * 1000 + LocalTime.wMinute * 60 * 1000 + LocalTime.wSecond * 1000 + LocalTime.wMilliseconds;
		
		if (ljustMilliSeconds)
			deltaMilliSeconds = ldayMilliSeconds - ljustMilliSeconds;

		ljustMilliSeconds = ldayMilliSeconds;
		fprintf(logFile, "%02d:%02d:%02d.%03d(dt:%d)=>%s", LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond, LocalTime.wMilliseconds, deltaMilliSeconds, logPrintOutString);
	}
}

void EnableLogFunc(char *logFileName, LOG_HOOK_FUNC LogHookFunc, unsigned long logCbArg)
{
	if (LogHookFunc)
	{
		// Open log file
		logFile = fopen(logFileName, "a");
		ljustMilliSeconds = 0;
	}
	else
	{
		if (logFile) fclose(logFile);
		logFile = NULL;
	}
}


static DWORD WINAPI GetImageThread(LPVOID Arg)
{
	BOOL bRet;
	CRTXCaptureDemoToolDlg *pToolDlg = (CRTXCaptureDemoToolDlg *)Arg;
	HWND	hwndProgress = pToolDlg->m_hwndProgress;
	__PGRAB_IMAGES pGrabCtrl = pToolDlg->pGrabCtrl;
	__HZHANDLE__ hZhandle = pToolDlg->m_Zhandle;

	while (TRUE)
	{
		DWORD dRet;
		if ((dRet = WaitForSingleObject(pGrabCtrl->hGrabThrdCmd, INFINITE)) == WAIT_OBJECT_0)
		{
			char	szLogBuffer[256];
			wchar_t	strScriptMsg[256];
			SRUNSTEPSTATE	sRunResult;
			int		imgIndx, iQueNxtIndx;;
			UCHAR	errCode;

			if (pGrabCtrl->bExit) break;

			switch (pGrabCtrl->GrabAct)
			{
			case __GRAB_IMG_ACT_GOING__:

				wsprintf(strScriptMsg, L"Execute script:  is that average-image ready to get?");
				::PostMessage(hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

				for (imgIndx = pGrabCtrl->nGrabStart; imgIndx <= pGrabCtrl->nGrabLast; imgIndx++)
				{
					// Check the get image is ready now!
					myLogfunc(hZhandle, "getRunStepstate() to get average image state\n", 0);
					while ((dRet = getRunStepstate(hZhandle, &sRunResult)) > 0)
					{
						/* if (sRunResult.runResultState == __Sta_step_snapping__)
						sRunResult.resultType == __AppendData__
						sRunResult.appDataLen = 2;
						sRunResult.appendBuffer [0] = how many image are snapped
						sRunResult.appendBuffer [1] = has snapped images count
						*/
						if (sRunResult.runResultState == __Sta_None_Imgage__)
						{
							// error, no image pic is snapped
							::PostMessage(hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Execute Script");
							::ShowWindow(hwndProgress, SW_HIDE);

							sprintf(szLogBuffer, "getRunStepstate() - None average Imgage\n");
							myLogfunc(hZhandle, szLogBuffer, 0);

							pGrabCtrl->nGrabbeResult = __GRAB_IMG_NON_PIC__;
							ReleaseSemaphore(pGrabCtrl->hGrabThrdRslt, 1, NULL);
							goto endGrabbing;
						}
						else if (sRunResult.runResultState == __Sta_step_snapping__ && sRunResult.resultType == __AppendData__)
						{
							// sRunResult.appendBuffer [0] --- picture count
							// sRunResult.appendBuffer [1] --- snapped pictured count

							if (sRunResult.appendBuffer[0] <= pGrabCtrl->nGrabStart)	// error index
							{
								::PostMessage(hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Execute Script");
								::ShowWindow(hwndProgress, SW_HIDE);

								sprintf(szLogBuffer, "getRunStepstate() - request average image id#%d > total image count(%d)\n", imgIndx, sRunResult.appendBuffer[0]);
								myLogfunc(hZhandle, szLogBuffer, 0);

								pGrabCtrl->nGrabbeResult = __GRAB_IMG_START_INDX_TOO_LOW__;
								ReleaseSemaphore(pGrabCtrl->hGrabThrdRslt, 1, NULL);
								goto endGrabbing;;
							}
							else if (sRunResult.appendBuffer[0] <= pGrabCtrl->nGrabLast)	// error index
							{
								::PostMessage(hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Execute Script");
								::ShowWindow(hwndProgress, SW_HIDE);

								sprintf(szLogBuffer, "getRunStepstate() - request average image id#%d > total image count(%d)\n", imgIndx, sRunResult.appendBuffer[0]);
								myLogfunc(hZhandle, szLogBuffer, 0);

								pGrabCtrl->nGrabbeResult = __GRAB_IMG_LAST_INDX_OVER__;
								ReleaseSemaphore(pGrabCtrl->hGrabThrdRslt, 1, NULL);
								goto endGrabbing;;
							}
							if (sRunResult.appendBuffer[1] >= imgIndx)
							{
								sprintf(szLogBuffer, "getRunStepstate() - still snapping, but request average image id#%d is ready\n", imgIndx);
								myLogfunc(hZhandle, szLogBuffer, 0);
								break;
							}
							else
							{
								sprintf(szLogBuffer, "getRunStepstate() - request average image id#%d not ready now\n", imgIndx);
								myLogfunc(hZhandle, szLogBuffer, 0);
								Sleep(80);
								continue;
							}
						}
						else if (sRunResult.runResultState == __Sta_step_succeed__ && sRunResult.resultType == __SnapPicture__)
						{
							if (sRunResult.snapCnt <= pGrabCtrl->nGrabStart)	// error index
							{
								::PostMessage(hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Execute Script");
								::ShowWindow(hwndProgress, SW_HIDE);

								sprintf(szLogBuffer, "getRunStepstate() - request average image id#%d > total image count(%d)\n", imgIndx, sRunResult.appendBuffer[0]);
								myLogfunc(hZhandle, szLogBuffer, 0);

								pGrabCtrl->nGrabbeResult = __GRAB_IMG_START_INDX_TOO_LOW__;
								ReleaseSemaphore(pGrabCtrl->hGrabThrdRslt, 1, NULL);
								goto endGrabbing;;
							}
							else if (sRunResult.snapCnt <= pGrabCtrl->nGrabLast)	// error index
							{
								::PostMessage(hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Execute Script");
								::ShowWindow(hwndProgress, SW_HIDE);

								sprintf(szLogBuffer, "getRunStepstate() - request average image id#%d > total image count(%d)\n", imgIndx, sRunResult.appendBuffer[0]);
								myLogfunc(hZhandle, szLogBuffer, 0);

								pGrabCtrl->nGrabbeResult = __GRAB_IMG_LAST_INDX_OVER__;
								ReleaseSemaphore(pGrabCtrl->hGrabThrdRslt, 1, NULL);
								goto endGrabbing;;
							}
							// sRunResult.snapCnt = g_snappedPicCnt;									// simulate a snap count
							// sRunResult.pSnaPicSiz[i] = size of every picture
							sprintf(szLogBuffer, "getRunStepstate() - grab average images snapped succeed\n");
							myLogfunc(hZhandle, szLogBuffer, 0);
							break;
						}
						else if (sRunResult.runResultState == __Sta_Invalid__)
						{
							sprintf(szLogBuffer, "getRunStepstate() - grab average images invalid\n");
							myLogfunc(hZhandle, szLogBuffer, 0);

							pGrabCtrl->nGrabbeResult = __GRAB_IMG_RUN_STEP_ERR__;
							ReleaseSemaphore(pGrabCtrl->hGrabThrdRslt, 1, NULL);
							goto endGrabbing;
						}
					}	// while to check image ready

					wsprintf(strScriptMsg, L"Execute script:  Get average image (%d) ", imgIndx);
					::PostMessage(hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

					GrabImageRequest(hZhandle, imgIndx, imgIndx, __Grab_opt_noneOperation__, 1);	//	only get assigned index only and wait

					// Get image to buffer and then save it to file
					if (sRunResult.runResultState == __Sta_step_succeed__)
						pGrabCtrl->pGrabBuffer[pGrabCtrl->nQueHead] = (UCHAR *)malloc(sRunResult.pSnaPicSiz[imgIndx]);
					else
					{
						sRunResult.pSnaPicSiz[imgIndx] = 1024 * 1024 * 40;
						pGrabCtrl->pGrabBuffer[pGrabCtrl->nQueHead] = (UCHAR *)malloc(sRunResult.pSnaPicSiz[imgIndx]);		// make a maximum buffer to received data
					}

					sprintf(szLogBuffer, "getPicture2Buffer() - average image start\n");
					myLogfunc(hZhandle, szLogBuffer, 0);

					pGrabCtrl->dwImageSize[pGrabCtrl->nQueHead] = getPicture2Buffer(hZhandle, pGrabCtrl->pGrabBuffer[pGrabCtrl->nQueHead], sRunResult.pSnaPicSiz[imgIndx], &errCode);

					sprintf(szLogBuffer, "getPicture2Buffer() - average image end\n");
					myLogfunc(hZhandle, szLogBuffer, 0);

					if (__Error_getPicBufferTooShort == errCode)
					{
						sprintf(szLogBuffer, "getPicture2Buffer() - buffer too short error\n");
						myLogfunc(hZhandle, szLogBuffer, 0);
						//free(pPic);
						//continue;
					}

					pGrabCtrl->nGrabbeResult = __GRAB_IMG_GOT__;
					ReleaseSemaphore(pGrabCtrl->hGrabThrdRslt, 1, NULL);

					pGrabCtrl->nQueHead++;
					if (pGrabCtrl->nQueHead == __GRAB_IMAGE_BUFFER_COUNT__)pGrabCtrl->nQueHead = 0;
					while (pGrabCtrl->nQueHead == pGrabCtrl->nQueTail)
					{
						Sleep(100);	// Wait buffer free
					}
				}	// for - image pictures
endGrabbing:
				break;
			default:
				;
			}


		}
	}
	return 0;
}

#define		__key_Begin__					"Begin"
#define		__key_End__						"End"

#define		__key_SearchingRegisterFiles__	"SearchingRegisterFiles"
#define     __key_LoadRegisterFiles__		"LoadRegisterFiles"
#define		__key__RunTestStepFile__		"RunTestStepFile"
#define		__key__SetZebraSetting__		"SetZebraSetting"
#define		__key__RunRegisterFile__		"RunRegisterFile"

#define		__key__SaveImag2File__			"SaveImage2File"
#define		__key__GrabImage__				"GrabImage"
#define		__key__GrabImageAvg__			"GrabImageAvg"
#define		__key__RunStepStatePollingTime__ "RunStepStatePollingTime"
#define		__key_log__						"Log"
#define		__key_StreamingMode__			"StreamingMode"

static DWORD RunStepStatePollingTime = 100;
static char szLastRunRegistFile[128];

void CRTXCaptureDemoToolDlg::OnBnClickedBtnRunScript()
{
	// TODO: Add your control notification handler code here
	FILE		*fileScript = NULL;
//	HANDLE		hScript;

	wchar_t drive[_MAX_DRIVE];
	wchar_t dir[_MAX_DIR];
	wchar_t fname[_MAX_FNAME];
	wchar_t ext[_MAX_EXT];

	wchar_t		strScriptName[256];
	wchar_t		strScriptMsg[256];
	char 		*pszBuf = NULL;
	UCHAR		errCode;
	BOOL		bScriptFuncOn = FALSE;
	int			StreamOnOff = __OPT_STREAMING_OFF__;
	__PZEBRA_BOARD_INFO__ pZebraBoardInfo;
	pZebraBoardInfo = getZebraBoardInfo(m_Zhandle, NULL);

#if 1
	HWND hwndOwner;
	RECT rc, rcDlg, rcOwner;

	// Get the owner window and dialog box rectangles. 
	if ((hwndOwner = ::GetParent(m_hwndProgress)) == NULL)
	{
		hwndOwner = ::GetDesktopWindow();
	}
	::GetWindowRect(hwndOwner, &rcOwner);
	::GetWindowRect(m_hwndProgress, &rcDlg);
	CopyRect(&rc, &rcOwner);

	// Offset the owner and dialog box rectangles so that right and bottom 
	// values represent the width and height, and then offset the owner again 
	// to discard space taken up by the dialog box. 

	OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
	OffsetRect(&rc, -rc.left, -rc.top);
	OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);

	// The new position is the sum of half the remaining space and the owner's 
	// original position. 
	::SetWindowPos(m_hwndProgress,
		HWND_BOTTOM,
		rcOwner.left - (rc.right * 3),
		rcOwner.top + (rc.bottom / 2),
		0, 0,          // Ignores size arguments. 
		SWP_NOSIZE);
#endif


	GetDlgItemText(IDC_EDT_SCRIPT_NAME, strScriptName, 256);
	pszBuf = lpWChar2lpAnsi(strScriptName);

#ifdef __loadRegisterSetting_external__
	_wsplitpath(strScriptName, drive, dir, fname, ext);
	wsprintf(strScriptMsg, L"Execute script: searching \"%s.%s\"", fname, ext);
	::ShowWindow(m_hwndProgress, SW_SHOW);
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

	EnableLogFunc("ZebraTest.log", myLogfunc, 0);

	m_MaxTestStep = SearchingRegisterFiles(m_Zhandle, pszBuf, myLogfunc, 0);

	wsprintf(strScriptMsg, L"Execute script: download register-files");
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

	LoadRegisterFiles(m_Zhandle, NULL, myLogfunc, 0);
	displayDownloadedInfo();

	EnableLogFunc("", NULL, 0);
#endif
	
/*  if you use open the script file; please make sure let it could be shared with next open.
	SearchingRegisterFiles(...) function would open it again!
*/
//	if ((hScript = CreateFileA(pszBuf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) && 
//		 hScript != INVALID_HANDLE_VALUE)
	if (fileScript = fopen(pszBuf, "rt"))
	{
		unsigned char	rdSettingBuffer[256];
		char            szScriptName[256];

		strcpy(szScriptName, pszBuf);	// used when SearchingRegisterFiles() doesn't set script file name 

		RunStepStatePollingTime = 100;	// default set to 100 milli-seconds
		// get every string line
		while (fgets((char *)rdSettingBuffer, sizeof(rdSettingBuffer), fileScript))
		{
			// Check USB disconnected!
			if (pZebraBoardInfo->nZebraStatus != __Zebra_Open_usable__)
			{
				MessageBox(L"*** Zebra USB disconnected! ***\r\n     Script is broken!");
				EnableLogFunc("", NULL, 0);
				break;
			}

			if ((pszBuf = isSkipScriptCommentOrWhiteLine((char *)rdSettingBuffer, sizeof(rdSettingBuffer))) == 0)
				continue;		// comment line 

			if (strcmp(__key_Begin__, pszBuf) == 0)	// in begin section start
			{
				bScriptFuncOn = TRUE;
				continue;
			}
			else if (strcmp(__key_End__, pszBuf) == 0)	// end section
			{
				EnableLogFunc("", NULL, 0);
				bScriptFuncOn = FALSE;
				continue;
			}

			if (bScriptFuncOn)
			{
				char *pzArgs;
				char *pScripFuncName = getScriptFuncName(pszBuf, &pzArgs);
				if (strcmp(__key_SearchingRegisterFiles__, pScripFuncName) == 0)
				{
#ifndef __loadRegisterSetting_external__
					// This SearchingRegisterFiles() & LoadRegisterFiles() may put external of script file.
					// call them before open script file to collect used setting files in script

					if (*pzArgs == 0)
						pzArgs = szScriptName;
					else
					{	// 141023 
						char			drive[_MAX_DRIVE];
						char			dir[_MAX_DIR];
						char			fname[_MAX_FNAME];
						char			ext[_MAX_EXT];

						_splitpath(pzArgs, drive, dir, fname, ext);
						if (*drive == 0 && *dir == 0)
						{
							char szTmpName[_MAX_FNAME];
							_splitpath(szScriptName, drive, dir, fname, ext);
							strcpy(szTmpName, fname);
							strcat(szTmpName, ext);
							if (strcmp(szTmpName, pzArgs) == 0)
								pzArgs = szScriptName;
						}
					}
					wsprintf(strScriptMsg, L"Execute script: searching \"%s\"", lpAnsi2lpWChar(pzArgs));
					::ShowWindow(m_hwndProgress, SW_SHOW);
					::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

					m_MaxTestStep = SearchingRegisterFiles(m_Zhandle, pzArgs, myLogfunc, 0);
#endif
					continue;
				}
				else if (strcmp(__key_LoadRegisterFiles__, pScripFuncName) == 0)
				{
#ifndef __loadRegisterSetting_external__
					// This LoadRegisterFiles() && SearchingRegisterFiles() may put external of script file.
					// call them before open script file to collect used setting files in script
					wsprintf(strScriptMsg, L"Execute script: download register-files");
					::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

					LoadRegisterFiles(m_Zhandle, NULL, myLogfunc, 0);
					displayDownloadedInfo();
#endif
					continue;
				}
				else if (strcmp(__key__RunTestStepFile__, pScripFuncName) == 0)
				{
					char szLogBuffer[256];
					SRUNSTEPSTATE	sRunResult;

					// Run the register file
					wsprintf(strScriptMsg, L"Execute script: run test step file \"%s\"", lpAnsi2lpWChar(pzArgs));
					::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

					sprintf(szLogBuffer, "RunTestStepFile() run test step %s\n", pzArgs);
					strcpy(szLastRunRegistFile, pzArgs);
					myLogfunc(m_Zhandle, szLogBuffer, 0);

					RunTestStepFile(m_Zhandle, pzArgs, StreamOnOff);
					getRunStepstate(m_Zhandle, &sRunResult);	// remove default status, 141014
					continue;
				}
				else if (strcmp(__key__SetZebraSetting__, pScripFuncName) == 0)
				{
					// Set Zebra setting for read Register file
					SetZebraSetting(m_Zhandle, pzArgs);
					continue;
				}
				else if (strcmp(__key__RunRegisterFile__, pScripFuncName) == 0)
				{
					char szLogBuffer[256];
					SRUNSTEPSTATE	sRunResult;

					// Run the register file
					wsprintf(strScriptMsg, L"Execute script: run register file \"%s\"", lpAnsi2lpWChar(pzArgs));
					::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

					sprintf(szLogBuffer, "RunRegisterFile() run test step %s\n", pzArgs);
					strcpy(szLastRunRegistFile, pzArgs);
					myLogfunc(m_Zhandle, szLogBuffer, 0);

					RunRegisterFile(m_Zhandle, pzArgs, StreamOnOff);
					getRunStepstate(m_Zhandle, &sRunResult);	// remove default status, 141014
					continue;
				}
				else if (strcmp(__key__SaveImag2File__, pScripFuncName) == 0)
				{
					wsprintf(strScriptMsg, L"Execute script:  Image be saved to \"%s\"", lpAnsi2lpWChar(pzArgs));
					::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

					SaveImage2File(pzArgs);
					continue;
				}
				else if (strcmp(__key__GrabImage__, pScripFuncName) == 0)
				{
					int imgIndx, nRet;
					char saveFile[256];
					SYSTEMTIME	LocalTime;
					SRUNSTEPSTATE	sRunResult;
					UCHAR *pPic;
					ULONG  uPicGotSiz;

					char szLogBuffer[256];

					// get which index image be got
					sscanf(pzArgs, "%d", &imgIndx);

					// save up the save file name
					GetLocalTime(&LocalTime);
					sprintf(saveFile, "%s~%s~%02d%02d-%02d%02d%02d.%03d_id#%d.raw", imgSavName, szLastRunRegistFile, LocalTime.wMonth, LocalTime.wDay, LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond, LocalTime.wMilliseconds, imgIndx);

					//wsprintf(strScriptMsg, L"Execute script:  get image save to \"%s\"", lpAnsi2lpWChar(saveFile));
					//::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

					wsprintf(strScriptMsg, L"Execute script:  Checking image is ready to get");
					::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);
					// Check the get image is ready now!

					myLogfunc(m_Zhandle, "getRunStepstate() to get image state\n", 0);
					while ((nRet = getRunStepstate(m_Zhandle, &sRunResult)) > 0)
					{
						/* if (sRunResult.runResultState == __Sta_step_snapping__)
						sRunResult.resultType == __AppendData__
						sRunResult.appDataLen = 2;
						sRunResult.appendBuffer [0] = how many image are snapped
						sRunResult.appendBuffer [1] = has snapped images count
						*/
						if (sRunResult.runResultState == __Sta_None_Imgage__)
						{
							// error, no image pic is snapped
							::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Execute Script");
							::ShowWindow(m_hwndProgress, SW_HIDE);

							sprintf(szLogBuffer, "getRunStepstate() - None_Imgage\n");
							myLogfunc(m_Zhandle, szLogBuffer, 0);
							return;
						}
						else if (sRunResult.runResultState == __Sta_step_snapping__ && sRunResult.resultType == __AppendData__)
						{
							// sRunResult.appendBuffer [0] --- picture count
							// sRunResult.appendBuffer [1] --- snapped pictured count

							if (sRunResult.appendBuffer[0] <= imgIndx)	// error index
							{
								::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Execute Script");
								::ShowWindow(m_hwndProgress, SW_HIDE);

								sprintf(szLogBuffer, "getRunStepstate() - request image id#%d > total image count(%d)\n", imgIndx, sRunResult.appendBuffer[0]);
								myLogfunc(m_Zhandle, szLogBuffer, 0);
								return;
							}
#if 0	// to wait snapping action completed, a bug when just run action is snapping! and next run command to send!
							if (sRunResult.appendBuffer[1] >= imgIndx)
							{
								sprintf(szLogBuffer, "getRunStepstate() - still snapping, but request id#%d is ready\n", imgIndx);
								myLogfunc(m_Zhandle, szLogBuffer, 0);
								break;
							}
							else
							{
								sprintf(szLogBuffer, "getRunStepstate() - request image id#%d not ready now\n", imgIndx);
								myLogfunc(m_Zhandle, szLogBuffer, 0);
								Sleep(RunStepStatePollingTime);
								continue;
							}
#endif
						}
						else if (sRunResult.runResultState == __Sta_step_succeed__ && sRunResult.resultType == __SnapPicture__)
						{
							// sRunResult.snapCnt = g_snappedPicCnt;									// simulate a snap count
							// sRunResult.pSnaPicSiz[i] = size of every picture
							sprintf(szLogBuffer, "getRunStepstate() - images snapped succeed\n");
							myLogfunc(m_Zhandle, szLogBuffer, 0);
							break;
						}
						else if (sRunResult.runResultState == __Sta_Invalid__)
						{
							sprintf(szLogBuffer, "getRunStepstate() - images invalid\n");
							myLogfunc(m_Zhandle, szLogBuffer, 0);
							goto InvalContinue;
						}
					}	// while to check image ready

					wsprintf(strScriptMsg, L"Execute script:  Get image (%d) ", imgIndx);
					::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

					// Send command to Zebra to get this image
// GrabImageAvg					if (strcmp(__key__GrabImage__, pScripFuncName) == 0)
// GrabImageAvg					{
						GrabImageRequest(m_Zhandle, imgIndx, imgIndx, __Grab_opt_noneOperation__, 1);	//	only get assigned index only and wait

						sprintf(szLogBuffer, "GrabImageRequest() - image#%d ~ image#%d raw image with wait\n", imgIndx, imgIndx);
						myLogfunc(m_Zhandle, szLogBuffer, 0);
// GrabImageAvg					}
// GrabImageAvg					else if (strcmp(__key__GrabImageAvg__, pScripFuncName) == 0)
// GrabImageAvg					{
// GrabImageAvg						GrabImageRequest(m_Zhandle, imgIndx, imgIndx, __Grab_opt_ImageAvg__, 1);		//	only get assigned index only and wait
// GrabImageAvg
// GrabImageAvg						sprintf(szLogBuffer, "GrabImageRequest() - image#%d ~ image#%d raw images avrage with wait\n", imgIndx, imgIndx);
// GrabImageAvg						myLogfunc(m_Zhandle, szLogBuffer, 0);
// GrabImageAvg					}

					// Get image to buffer and then save it to file
					if (sRunResult.runResultState == __Sta_step_succeed__)
						pPic = (UCHAR *)malloc(sRunResult.pSnaPicSiz[imgIndx]);
					else
					{
						sRunResult.pSnaPicSiz[imgIndx] = 1024 * 1024 * 40;
						pPic = (UCHAR *)malloc(sRunResult.pSnaPicSiz[imgIndx]);		// make a maximum buffer to received data
					}

					sprintf(szLogBuffer, "getPicture2Buffer() - start\n");
					myLogfunc(m_Zhandle, szLogBuffer, 0);

					uPicGotSiz = getPicture2Buffer(m_Zhandle, pPic, sRunResult.pSnaPicSiz[imgIndx], &errCode);

					sprintf(szLogBuffer, "getPicture2Buffer() - end\n");
					myLogfunc(m_Zhandle, szLogBuffer, 0);

					if (__Error_getPicBufferTooShort == errCode)
					{
						sprintf(szLogBuffer, "getPicture2Buffer() - buffer too short error\n");
						myLogfunc(m_Zhandle, szLogBuffer, 0);
						//free(pPic);
						//continue;
					}

					wsprintf(strScriptMsg, L"Execute script:  save image (%d) to \"%s\"", imgIndx, lpAnsi2lpWChar(saveFile));
					::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

					// Save got picture to file
					HANDLE hFile = CreateFileA(saveFile, // open One.txt
						GENERIC_WRITE,             // open for reading
						0,                        // do not share
						NULL,                     // no security
						CREATE_ALWAYS,            // existing file only
						FILE_ATTRIBUTE_NORMAL,    // normal file
						NULL);                    // no attr. template

					if (m_scriptchkRaw8To10.GetCheck() == BST_CHECKED)
					{
						UCHAR *pPicRaw10;
						ULONG  uRaw10Size;
						int     errExchg;

						pPicRaw10 = RawStrmToRaw10(pPic, uPicGotSiz, &uRaw10Size, &errExchg);
						if (errExchg == __NO_ERROR_EXCHG__)
						{
							if (hFile != INVALID_HANDLE_VALUE)
							{
								DWORD wrLen;
								WriteFile(hFile, pPicRaw10, uRaw10Size, &wrLen, NULL);
								CloseHandle(hFile);
							}
							freeRawExchgBuffer(pPicRaw10);
						}
					}
					else
					{
						if (hFile != INVALID_HANDLE_VALUE)
						{
							DWORD wrLen;
							WriteFile(hFile, pPic, uPicGotSiz, &wrLen, NULL);
							CloseHandle(hFile);
						}
					}

					free(pPic);
InvalContinue:
					continue;
				}
				else if (strcmp(__key__GrabImageAvg__, pScripFuncName) == 0)
				{
					char *p;
					char szLogBuffer[256];

					// Check image-count of current test-step
					sscanf(pzArgs, "%d", &pGrabCtrl->nGrabStart);
					p = strchr(pzArgs, ',');
					if (p) p++;
					if (p < (pzArgs + strlen(pzArgs)))
					{
						int   ic;
						int	  errExchg;
						char saveFile[256];
						SYSTEMTIME	LocalTime;
						UCHAR *pPicRaw10_0 = NULL, *pPicRaw10_X;
						USHORT *pwPicRaw10_0 = NULL, *pwPicRaw10_X;
						ULONG uRaw10Siz0, uRaw10SizX;
						DWORD dwAvgStartTick, dRet;
						SRUNSTEPSTATE	sRunResult;

						sscanf(p, "%d", &pGrabCtrl->nGrabLast);

											// save up the save file name
						GetLocalTime(&LocalTime);
						sprintf(saveFile, "%s~%s~%02d%02d-%02d%02d%02d.%03d_id#%d-%d.raw", imgSavName, szLastRunRegistFile, LocalTime.wMonth, LocalTime.wDay, LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond, LocalTime.wMilliseconds, pGrabCtrl->nGrabStart, pGrabCtrl->nGrabLast);

						sprintf(szLogBuffer, "GrabImageAvg() - starting\n");
						myLogfunc(m_Zhandle, szLogBuffer, 0);
						dwAvgStartTick = GetTickCount();

						// Kick grab thread to receive image
						pGrabCtrl->GrabAct = __GRAB_IMG_ACT_GOING__;
						SetEvent(pGrabCtrl->hGrabThrdCmd);

						for (ic = 0; ic < (pGrabCtrl->nGrabLast - pGrabCtrl->nGrabStart + 1); ic++)
						{
							// Wait image got!
							WaitForSingleObject(pGrabCtrl->hGrabThrdRslt, INFINITE);
							switch (pGrabCtrl->nGrabbeResult)
							{
							case __GRAB_IMG_GOT__:
								if (ic)
								{
									pPicRaw10_X = RawStrmToRaw10(pGrabCtrl->pGrabBuffer[pGrabCtrl->nQueTail],
										pGrabCtrl->dwImageSize[pGrabCtrl->nQueTail], &uRaw10SizX, &errExchg);
									pwPicRaw10_X = (USHORT *)pPicRaw10_X;

									for (int n = 0; n < uRaw10SizX / 2; n++)	// word adding
										pwPicRaw10_0[n] += pwPicRaw10_X[n];
									freeRawExchgBuffer(pPicRaw10_X);
								}
								else
								{
									pPicRaw10_0 = RawStrmToRaw10(pGrabCtrl->pGrabBuffer[pGrabCtrl->nQueTail],
										pGrabCtrl->dwImageSize[pGrabCtrl->nQueTail], &uRaw10Siz0, &errExchg);
									pwPicRaw10_0 = (USHORT *)pPicRaw10_0;
								}

								free(pGrabCtrl->pGrabBuffer[pGrabCtrl->nQueTail]);
								pGrabCtrl->nQueTail++;
								if (pGrabCtrl->nQueTail >= __GRAB_IMAGE_BUFFER_COUNT__) pGrabCtrl->nQueTail = 0;
								break;
							default:
								goto ErrGrabbed;
								;
							}
						}	// for all images

						for (int n = 0; n < uRaw10Siz0 / 2; n++)	// average
							pwPicRaw10_0[n] /= (pGrabCtrl->nGrabLast - pGrabCtrl->nGrabStart + 1);

						sprintf(szLogBuffer, "GrabImageAvg() - end; GrabeImageAvg() total ticks=%d\n", GetTickCount() - dwAvgStartTick);
						myLogfunc(m_Zhandle, szLogBuffer, 0);

						// Save average file
						wsprintf(strScriptMsg, L"Execute script:  save average image (%d-%d) to \"%s\"", pGrabCtrl->nGrabStart, pGrabCtrl->nGrabLast, lpAnsi2lpWChar(saveFile));
						::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_NAME, (LPARAM)strScriptMsg);

						// Save got picture to file
						HANDLE hFile = CreateFileA(saveFile, // open One.txt
							GENERIC_WRITE,             // open for reading
							0,                        // do not share
							NULL,                     // no security
							CREATE_ALWAYS,            // existing file only
							FILE_ATTRIBUTE_NORMAL,    // normal file
							NULL);                    // no attr. template

						if (hFile != INVALID_HANDLE_VALUE)
						{
							DWORD wrLen;
							WriteFile(hFile, pPicRaw10_0, uRaw10Siz0, &wrLen, NULL);
							CloseHandle(hFile);
						}
						freeRawExchgBuffer(pPicRaw10_0);

					ErrGrabbed:
						// make sure just run state is completed!
						while ((dRet = getRunStepstate(m_Zhandle, &sRunResult)) > 0)
						{
							if (sRunResult.runResultState != __Sta_step_snapping__)
								break;
						}
					}
				}
				else if (strcmp(__key_log__, pScripFuncName) == 0)
				{
					int imgIndx;
					//sscanf(pzArgs, "%d", &imgIndx);
					EnableLogFunc(pzArgs, myLogfunc, 0);
					continue;
				}
				else if (strcmp(__key__RunStepStatePollingTime__, pScripFuncName) == 0)
				{
					sscanf(pzArgs, "%d", &RunStepStatePollingTime);
					continue;
				}
				else if (strcmp(__key_StreamingMode__, pScripFuncName) == 0)
				{
					if (*pzArgs == '1')
						StreamOnOff = __OPT_STREAMING_ON__;
					else
						StreamOnOff = __OPT_STREAMING_OFF__;
					continue;
				}
				
			}	
		}	// while - parsing
		fclose(fileScript);
//		CloseHandle(hScript);
	}
	::PostMessage(m_hwndProgress, WM_MIPI_PROGRESS_MONITOR, IDC_PROGRESS_DOT, (LPARAM)L"Execute Script");
	::ShowWindow(m_hwndProgress, SW_HIDE);




}

unsigned char *RawStrmToRaw10(unsigned char *pImgStrmBuffer, ULONG lImgStrmSiz, ULONG *lRaw10Siz, int *errState)
{
	ULONG l, n;
	ULONG nRaw10Size = lImgStrmSiz / 5 * 8;
	unsigned char *pRaw10Buffer = NULL;
	unsigned char raw10Ext[4];

	if (lImgStrmSiz == 0)
	{
		if (errState) *errState = __ILLEGAL_STRM_DATA_SIZE__;
		return pRaw10Buffer;
	}

	if (lImgStrmSiz % 5) nRaw10Size += 8;	// to extra data size

	pRaw10Buffer = (unsigned char *)malloc(nRaw10Size);
	if (pRaw10Buffer == NULL)
	{
		if (errState) *errState = __FAIL_ALLOCATED_RAW10_BUFFER__;
		return pRaw10Buffer;
	}

	if (errState) *errState = __NO_ERROR_EXCHG__;
	*lRaw10Siz = nRaw10Size;

	l = n = 0;
	while (l < lImgStrmSiz)
	{
		int m;
		/*
		AAAA-AAAA BBBB-BBBB
		CCCC-CCCC DDDD-DDDD
		aabbccdd

		little ending raw8
		BBBB-BBBB AAAA-AAAA DDDD-DDDD CCCC-CCCC aabbccdd

		0000-00BB BBBB-BBbb
		0000-00AA AAAA-AAaa
		0000-00DD DDDD-DDdd
		0000-00CC CCCC-CCcc

		little ending => raw10
		BBBB-BBbb 0000-00BB AAAA-AAaa 0000-00AA DDDD-DDdd 0000-00DD CCCC-CCcc 0000-00CC
		*/
		raw10Ext[0] = (pImgStrmBuffer[l + 4] >> 4) & 0x03;
		raw10Ext[1] = (pImgStrmBuffer[l + 4] >> 6) & 0x03;
		raw10Ext[2] = (pImgStrmBuffer[l + 4] >> 0) & 0x03;
		raw10Ext[3] = (pImgStrmBuffer[l + 4] >> 2) & 0x03;
		for (m = 0; m < 4; m++)
		{
			pRaw10Buffer[n++] = (pImgStrmBuffer[l] << 2) + raw10Ext[m];	// low byte
			pRaw10Buffer[n++] = (pImgStrmBuffer[l++] >> 6);				// High byte only b1 b0
		}
		l++;	// skip padding
	}

	return pRaw10Buffer;
}

void freeRawExchgBuffer(unsigned char *pRawStrmBuffer)
{
	free(pRawStrmBuffer);
}
