
// MultiZebrasDemoDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MultiZebrasDemo.h"
#include "MultiZebrasDemoDlg.h"
#include "FileOpenCombo.h"
#include "afxdialogex.h"

#include "AppLoadRegisterFiles.h"
#include "AppRunTestStepRegister.h"
#include "AppGrabImages.h"
#include "AppZebraScriptDemo.h"
#include "AppI2cOperation.h"
#include "AppGetZebraTestSteps.h"
#include "AppResetZebraCard.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

TCHAR *printZebraType(int nZebraType);
TCHAR *printfZebraStatus(int nZebraStatus);
TCHAR *zsZebraBusyAction(int nZebraActId);
TCHAR *zsZebraHandleInitedStatus(int initedHandle);

// local functions
BOOL CALLBACK ZebraInfoDlg(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
void getProgramVersion(DWORD &dwMSVer, DWORD &dwLSVer);
LPTSTR lpAnsi2lpWChar(LPSTR lpstr);
LPSTR  lpWChar2lpAnsi(LPTSTR lptstr);

#ifndef ZEBRAZ4U3DLLWIN32_EXPORTS
#include "ZebraZ4U3DllWin32.h"
#else
// I2c option
#define _10BitI2C_Addr			0x1
#define	_1byteRdSubAddr			0x2
#define	_2bytesRdSubAddr		0x4
#define	_3bytesRdSubAddr		0x6
#define	_IgnoreAckChking		0x8
#define	_ReadI2cDevice			0x80

#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.

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

int lookingViewableZebras(void);		// build up zebras info to queue
void freeZebrasInfoListQueue(void);		// release lookingViewableZebras() setup queue
__PZEBRA_BOARD_INFO__ getZebraBoardInfo(__HZHANDLE__ hZhandle, TCHAR **pUsbPortName);
int ZebraCardNumber(void);
int InitMipiUsbNotifyWin(HWND hWndApp, DWORD idThrdHandle);
void StopMipiUsbNotifyWin(void);
__HZHANDLE__ bInitUsbDevice(int nZebraBroadId, __HZHANDLE__ *phZhandle); 
void CloseUsbDevice(__HZHANDLE__ hZhandle);
int LoadRegisterFiles(__HZHANDLE__ hZhandle, char *pRegFilesDir, LOG_HOOK_FUNC log_cbFunc, unsigned long logCbArg);
int qureyZebraTestStepCount(__HZHANDLE__ hZhandle);

int getAliasRunStepsCntJustDownload(__HZHANDLE__ hZhandle);
char *get1stDownloadStepAliasName(__HZHANDLE__ hZhandle);
char *getNextDownloadStepAliasName(__HZHANDLE__ hZhandle);

int getRegisterStepsCntJustDownload(__HZHANDLE__ hZhandle);
char *get1stDownloadRegisterStepName(__HZHANDLE__ hZhandle);
char *getNextDownloadRegisterStepName(__HZHANDLE__ hZhandle);

int getZebraSWVersion(__HZHANDLE__ hZhandle, PSZEBRAVERSION psZebraVersion);
int getHardwareType(__HZHANDLE__ hZhandle);

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

static CMultiZebrasDemoDlg* gThis = NULL;

// 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()
public:
//	afx_msg void OnClose();
};

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

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

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
//	ON_WM_CLOSE()
END_MESSAGE_MAP()


// CMultiZebrasDemoDlg dialog



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

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

	DDX_Control(pDX, IDC_SPIN_SELECT_UPDOWN, m_SPIN_ZebraIndx);


	DDX_Control(pDX, IDC_RDO_APP_RESET, m_RDO_AppReset);
	DDX_Control(pDX, IDC_RDO_USB_RESET, m_RDO_UsbReset);

	DDX_Control(pDX, IDC_RDO_ALIAS_RUN, m_RDO_AlaisRun);
	DDX_Control(pDX, IDC_RDO_FILENAME_RUN, m_RDO_FileRun);

	DDX_Control(pDX, IDC_CHK_STREAM_ON, m_chk_RunAsStreaming);
	DDX_Control(pDX, IDC_CHK_GET_UNSAVE, m_chk_ScriptDontSavImg);
	DDX_Control(pDX, IDC_CHK_RAW8TO10, m_chkRaw8To10);
	DDX_Control(pDX, IDC_CHK_SCRIPT_RAW8TO10, m_scriptchkRaw8To10);

	DDX_Control(pDX, IDC_CHK_I2C_IGNORE_ACK, m_chk_I2CIgnoreAck);
	DDX_Control(pDX, IDC_RDO_I2C_READ, m_RDO_I2CRead);
	DDX_Control(pDX, IDC_RDO_I2C_WRITE, m_RDO_I2CWrite);

	DDX_Control(pDX, IDC_CMB_I2C_ADDR_BITS, m_Combo_I2CAddrBits);
	DDX_Control(pDX, IDC_CMB_I2C_SUBADDR_TYPE, m_Combo_I2CRdSubAddrBytes);
	DDX_Control(pDX, IDC_CMB_RUN_NAME, m_Combo_RunNames);


	DDX_Control(pDX, IDC_STC_Z1_ID_PORT_INFO, m_stc_Z1_Id_Port_Info);
	DDX_Control(pDX, IDC_STC_Z1_ACTION_STATUS, m_stc_Z1_ActionStatus);
	DDX_Control(pDX, IDC_PROGRSS_Z1, m_Z1_progress);

	DDX_Control(pDX, IDC_STC_Z2_ID_PORT_INFO, m_stc_Z2_Id_Port_Info);
	DDX_Control(pDX, IDC_STC_Z2_ACTION_STATUS, m_stc_Z2_ActionStatus);
	DDX_Control(pDX, IDC_PROGRSS_Z2, m_Z2_progress);

	DDX_Control(pDX, IDC_STC_Z3_ID_PORT_INFO, m_stc_Z3_Id_Port_Info);
	DDX_Control(pDX, IDC_STC_Z3_ACTION_STATUS, m_stc_Z3_ActionStatus);
	DDX_Control(pDX, IDC_PROGRSS_Z3, m_Z3_progress);

	DDX_Control(pDX, IDC_STC_Z4_ID_PORT_INFO, m_stc_Z4_Id_Port_Info);
	DDX_Control(pDX, IDC_STC_Z4_ACTION_STATUS, m_stc_Z4_ActionStatus);
	DDX_Control(pDX, IDC_PROGRSS_Z4, m_Z4_progress);
}

BEGIN_MESSAGE_MAP(CMultiZebrasDemoDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
//	ON_COMMAND(IDCLOSE, &CMultiZebrasDemoDlg::OnIdclose)
ON_WM_CLOSE()
//ON_WM_RBUTTONDBLCLK()
ON_WM_RBUTTONDOWN()
ON_BN_CLICKED(IDC_BTN_SELECT, &CMultiZebrasDemoDlg::OnBnClickedBtnSelect)
ON_BN_CLICKED(IDC_BTN_TEST_CFG, &CMultiZebrasDemoDlg::OnBnClickedBtnTestCfg)
ON_BN_CLICKED(IDC_BTN_LOAD_TEST_STEP, &CMultiZebrasDemoDlg::OnBnClickedBtnLoadTestStep)
ON_EN_CHANGE(IDC_EDT_SELECT_ZEBRA_BRD_INDX, &CMultiZebrasDemoDlg::OnChangeEdtSelectZebraBrdIndx)
ON_BN_CLICKED(IDC_RDO_ALIAS_RUN, &CMultiZebrasDemoDlg::OnBnClickedRdoAliasRun)
ON_BN_CLICKED(IDC_RDO_FILENAME_RUN, &CMultiZebrasDemoDlg::OnBnClickedRdoFilenameRun)
ON_BN_CLICKED(IDC_BTN_GRAB_IMG, &CMultiZebrasDemoDlg::OnBnClickedBtnGrabImg)
ON_BN_CLICKED(IDC_BTN_RUN_STEP, &CMultiZebrasDemoDlg::OnBnClickedBtnRunStep)
ON_BN_CLICKED(IDC_BTN_SELECT_SCRIPT_FILE, &CMultiZebrasDemoDlg::OnBnClickedBtnSelectScriptFile)
ON_BN_CLICKED(IDC_BTN_RUN_SCRIPT, &CMultiZebrasDemoDlg::OnBnClickedBtnRunScript)
ON_BN_CLICKED(IDC_BTN_I2C_READ_WRITE, &CMultiZebrasDemoDlg::OnBnClickedBtnI2cReadWrite)
ON_BN_CLICKED(IDC_RDO_I2C_READ, &CMultiZebrasDemoDlg::OnBnClickedRdoI2cRead)
ON_BN_CLICKED(IDC_RDO_I2C_WRITE, &CMultiZebrasDemoDlg::OnBnClickedRdoI2cWrite)
ON_BN_CLICKED(IDC_BTN_RESET, &CMultiZebrasDemoDlg::OnBnClickedBtnReset)
ON_BN_CLICKED(IDC_BTN_GET_ZEBRA_STEPS, &CMultiZebrasDemoDlg::OnBnClickedBtnGetZebraSteps)
ON_BN_CLICKED(IDC_CHK_GET_UNSAVE, &CMultiZebrasDemoDlg::OnBnClickedChkGetUnsave)
END_MESSAGE_MAP()


// CMultiZebrasDemoDlg message handlers


void CMultiZebrasDemoDlg::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 CMultiZebrasDemoDlg::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 CMultiZebrasDemoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

BOOL CMultiZebrasDemoDlg::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], szTitleName[_MAX_FNAME + _MAX_EXT];
	
	gThis = this;

	getProgramVersion(m_dwMSVer, m_dwLSVer);	// Get local program version

	getDllVersion(dllName, &dwDllMSVer, &dwDllLSVer);	// load DLL name and version

	_swprintf(szTitleName, L"MultiZebrasDemo32(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(szTitleName);

	// m_szProgVersion used when getBoardTestSteps()... to identify which software to get zebra board test-steps 
	sprintf(m_szProgVersion, "MultiZebrasDemo32(V%d.%d.%d.%d)", HIWORD(m_dwMSVer), LOWORD(m_dwMSVer), HIWORD(m_dwLSVer), LOWORD(m_dwLSVer));
	//


	// Start zebra handle threads
	hThrdStartEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
	for (int i = 1; i <= __ZebraAppMax__; i++)
	{
		m_SelectIndx = i;
		m_ExitEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
		m_ThrdHandle[i] = CreateThread(
			NULL,			// no security attributes 
			0,              // use default stack size  
			ZebraHandleThrd,// thread function 
			this,           // argument to thread function 
			0,              // use default creation flags 
			&m_ThrdId[i]);     // returns the thread identifier 

		// make sure just ready! --> m_SelectIndx to for every thread is correct!
		WaitForSingleObject(hThrdStartEvt, INFINITE);
	}

	for (int i = 1; i <= __ZebraAppMax__; i++)
	{
		memset(&m_sZebraUI[i], 0, sizeof(__sOneZebraAppPrams__));
		m_sZebraUI[i].m_AppZebraHandle = __USB_HANDLE_NOT_INIT__;
	}

	// Create average Grab image thread 141021
	for (int i = 1; i <= __ZebraAppMax__; i++)
	{
		m_SelectIndx = i;
		m_sZebraUI[i].bGrabExit = FALSE;
		m_sZebraUI[i].hGrabThrdCmd = CreateEvent(NULL, FALSE, FALSE, NULL);
		m_sZebraUI[i].hGrabThrdRslt = CreateSemaphore(NULL, 0, 100, NULL);
		m_sZebraUI[i].hGrabThrd = CreateThread(
			NULL,			// no security attributes 
			0,              // use default stack size  
			GetImageThread,// thread function 
			this,           // argument to thread function 
			0,              // use default creation flags 
			&m_sZebraUI[i].dwGrabThrdId);     // returns the thread identifier 

		// make sure just ready! --> m_SelectIndx to for every thread is correct!
		WaitForSingleObject(hThrdStartEvt, INFINITE);
	}
	CloseHandle(hThrdStartEvt);

	// Setup window procedure as USB notifyer routine
	InitMipiUsbNotifyWin(this->m_hWnd, NULL);

	// looking all Zebras
	m_FoundZebras = lookingViewableZebras();

	//if (m_FoundZebras)
	//{
	//	// turn on Zebras-info dialog 
	//	m_ZebraInfoDlgOpenMode = __zInfoDlgOpen_View__;
	//}


	m_SelectIndx = 1;
	SetDlgItemText(IDC_EDT_SELECT_ZEBRA_BRD_INDX, L"1");
	m_SPIN_ZebraIndx.SetRange(1, __ZebraAppMax__);

	SetDlgItemText(IDC_EDT_GRAB_IMG_START, L"0");
	SetDlgItemText(IDC_EDT_GRAB_IMG_END, L"0");

	SetDlgItemText(IDC_EDT_SAVE_IMG_NAME, L"multiZebras");
	SetDlgItemText(IDC_EDT_GOT_ZEBRA_STEPS_NAME, L"multiZebras");

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

	//CButton
	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_RDO_AppReset.SetCheck(BST_CHECKED);
	m_RDO_UsbReset.SetCheck(BST_UNCHECKED);

	m_Combo_RunNames.AddString(L"<None>");
	m_RDO_AlaisRun.SetCheck(BST_CHECKED);
	m_RDO_FileRun.SetCheck(BST_UNCHECKED);
	SetDlgItemText(IDC_CMB_RUN_NAME, L"<None>");


	m_RDO_I2CRead.SetCheck(BST_UNCHECKED);
	m_RDO_I2CWrite.SetCheck(BST_CHECKED);

	SetDlgItemText(IDC_EDT_I2C_ADDR, L"0x3c");

	SetDlgItemText(IDC_EDT_I2C_SUBADDR, L"0x31,0x3");

	SetDlgItemText(IDC_EDT_I2C_READ_LEN, L"10");

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


	pWnd = GetDlgItem(IDC_STC_SUB_ADDR);
	pWnd->EnableWindow(FALSE);
	pWnd = GetDlgItem(IDC_CMB_I2C_SUBADDR_TYPE);
	pWnd->EnableWindow(FALSE);
	pWnd = GetDlgItem(IDC_EDT_I2C_SUBADDR);
	pWnd->EnableWindow(FALSE);

	saveCurrentContext2Thread(1);
	saveCurrentContext2Thread(2);
	saveCurrentContext2Thread(3);
	saveCurrentContext2Thread(4);

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


DWORD WINAPI CMultiZebrasDemoDlg::ZebraHandleThrd(LPVOID pParam)
{
	CMultiZebrasDemoDlg *pMain = (CMultiZebrasDemoDlg *)pParam;
	HANDLE pHandles[1];
	int		myId = pMain->m_SelectIndx;

	pHandles[0] = pMain->m_ExitEvent[myId];

	// Signal caller this thread is enabled!
	SetEvent(pMain->hThrdStartEvt);

	while (TRUE)
	{
		pMain->m_sZebraUI[myId].m_ZebraActionStatus = Act_ZebraReadForNew;

		DWORD dwRet = MsgWaitForMultipleObjects(1, pHandles, FALSE, INFINITE, QS_POSTMESSAGE);
		if (dwRet == WAIT_OBJECT_0)	// be checked 1st for exit thread
		{
			break;
		}
		else if (dwRet == WAIT_OBJECT_0 + 1)
		{
			MSG msg;
			static char pZebraCardName[16];
			if (GetMessage(&msg, NULL, 0, 0) > 0)
			{
				if (WM_MIPI_THREAD_ACTION == msg.message)
				{
					pMain->m_sZebraUI[myId].m_ZebraActionStatus = msg.wParam;
					switch (msg.wParam)
					{
					case Act_LoadRegisterFile:
						LoadTestStepsOrRegisterFilesToZebra((void*)pMain, pMain->m_sZebraUI[myId].m_AppZebraHandle, myId, pMain->m_sZebraUI[myId].m_LoadStepRegName);
						if (pMain->m_sZebraUI[myId].m_TestStepCnt = qureyZebraTestStepCount(pMain->m_sZebraUI[myId].m_AppZebraHandle))
						{
							pMain->UpdateRunStepCmbList(pMain->m_sZebraUI[myId].m_AppZebraHandle, myId);
						}
						break;

					case Act_RunTestStepOrRegister:
						// without exculive other threads, it should be access with concurrent
						RunTestStepOrRegister((void*)pMain, pMain->m_sZebraUI[myId].m_AppZebraHandle, myId, pMain->m_sZebraUI[myId].m_RunType, pMain->m_sZebraUI[myId].m_AliasTestRegisterName, &pMain->m_sZebraUI[myId].m_TestStepImgCnt, &pMain->m_sZebraUI[myId].m_TestStepId, pMain->m_sZebraUI[myId].m_RunAsStreaming);
						break;

					case Act_GrabImageData:
						GrabImageData((void*)pMain, pMain->m_sZebraUI[myId].m_AppZebraHandle, myId, pMain->m_sZebraUI[myId].m_TestStepImgCnt, pMain->m_sZebraUI[myId].m_GrabStart, pMain->m_sZebraUI[myId].m_GrabEnd, pMain->m_sZebraUI[myId].m_GrabImgSaveName);
						break;

					case Act_RunTestStepScript:
						ZebraScriptSimulateDemo((void*)pMain, pMain->m_sZebraUI[myId].m_AppZebraHandle, myId, pMain->m_sZebraUI[myId].m_ScriptName, &pMain->m_sZebraUI[myId].m_TestStepCnt,
							pMain->m_sZebraUI[myId].m_ScriptDontSaveImage);
						break;

					case Act_I2CReadWrite:
						ZebraI2cOperationHandler((void*)pMain, pMain->m_sZebraUI[myId].m_AppZebraHandle, myId,
							pMain->m_sZebraUI[myId].m_I2C_cfgByte, pMain->m_sZebraUI[myId].m_I2C_Addr, pMain->m_sZebraUI[myId].m_I2C_SubAddr,
							pMain->m_sZebraUI[myId].m_I2C_ReadWriteLen, pMain->m_sZebraUI[myId].m_I2C_RdWrData);
						break;

					case Act_ResetZebraBrd:
						ResetAttachedZebraBoard((void *)pMain, pMain->m_sZebraUI[myId].m_AppZebraHandle, myId, 
							pMain->m_sZebraUI[myId].m_ResetByApp);
						break;

					case Act_GetBrdTestSteps:
						{
						switch (getHardwareType(pMain->m_sZebraUI[myId].m_AppZebraHandle))
						{
						case __ZebraType_Z4__:
							sprintf (pZebraCardName,"Zebra4");
							break;
						case __ZebraType_Z5__:
							sprintf(pZebraCardName, "Zebra5");
							break;
						case __ZebraType_Z4U3__:
							sprintf(pZebraCardName, "Z4U3");
							break;
						}
						GetTestStepFromZebraBoard((void *)pMain, pMain->m_sZebraUI[myId].m_AppZebraHandle, myId, 
							pMain->m_sZebraUI[myId].m_GotZebraTestStepName, 
													pZebraCardName,
							"DemoSensor1.1", pMain->m_szProgVersion);
						break;
						}

					}	// switch - command type
				}	// if - message name
			}	//  if - message got
		}
	}
	
	return 0;
}

void CMultiZebrasDemoDlg::OnBnClickedBtnSelect()
{
	// TODO: Add your control notification handler code here
	if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle >= 0)	// has attached at a Zebra
	{
		TCHAR szMsgText[256];
		swprintf(szMsgText, L"The thread %d has attached to zebra %d,\n\r do you want to close it then reconnect others?", m_SelectIndx, m_sZebraUI[m_SelectIndx].m_AppZebraId);

		if (IDNO == MessageBox(szMsgText, NULL, MB_YESNO))
			return;		// 

		// Is wait current action completed?
		//if (m_sZebraUI[m_SelectIndx].m_ZebraActionStatus != Act_ZebraReadForNew)
		//{
		//   to be implement...
		//}
		
		// Try to close this handle
		CloseUsbDevice(m_sZebraUI[m_SelectIndx].m_AppZebraHandle);
		
	}
	m_SelectIndx = GetDlgItemInt(IDC_EDT_SELECT_ZEBRA_BRD_INDX);		// which frame is try to select.

	m_ZebraInfoDlgOpenMode = __zInfoDlgOpen_Select__;
	if (DialogBoxParam(GetModuleHandle(NULL),		// Modal dialog (), // CreateDialog - for Modeless dialog
		MAKEINTRESOURCE(IDD_DIALOG_ZEBRAS),
		this->m_hWnd,
		(DLGPROC)ZebraInfoDlg, (LPARAM)this) == IDOK)
	{
		if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle >= 0)
		{
			__HZHANDLE__ locTmpZHandle;
			TCHAR *pUsbPortName, szPrintInfoBuffer[128];
			__PZEBRA_BOARD_INFO__ pZebraBdInfo;
			SZEBRAVERSION sZebraVersion;
			int nTmpHandle = m_sZebraUI[m_SelectIndx].m_AppZebraHandle;

			// update frame title
			pZebraBdInfo = getZebraBoardInfo(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, &pUsbPortName);
			if (pZebraBdInfo)
				swprintf(szPrintInfoBuffer, L"id:%04x  at  %-22s is a  %s", pZebraBdInfo->nZebraBoardId, pUsbPortName,
				printZebraType(pZebraBdInfo->nZebraType));

			switch (m_SelectIndx)
			{
			case 1:
				m_stc_Z1_Id_Port_Info.SetWindowTextW(szPrintInfoBuffer);
				// initialize this device
				if ((m_sZebraUI[m_SelectIndx].m_AppZebraHandle = bInitUsbDevice(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, &locTmpZHandle)) >= 0)
				{
					if (getZebraSWVersion(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, &sZebraVersion) > 0)
					{
						swprintf(szPrintInfoBuffer, L"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_APP_INFO, szPrintInfoBuffer);
					}
					m_stc_Z1_ActionStatus.SetWindowTextW(L"Open");
				}
				else if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle == __USB_DRV_OK_APP_NOT_READY__)
				{
					CloseUsbDevice(nTmpHandle);	// for stop the USB kernel state

					m_stc_Z1_ActionStatus.SetWindowTextW(L"*** Application isn't ready now! try open it again ***");
				}
				break;

			case 2:
				m_stc_Z2_Id_Port_Info.SetWindowTextW(szPrintInfoBuffer);
				// initialize this device
				if ((m_sZebraUI[m_SelectIndx].m_AppZebraHandle = bInitUsbDevice(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, &locTmpZHandle)) >= 0)
				{
					if (getZebraSWVersion(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, &sZebraVersion) > 0)
					{
						swprintf(szPrintInfoBuffer, L"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_APP_INFO, szPrintInfoBuffer);
					}
					m_stc_Z2_ActionStatus.SetWindowTextW(L"Open");
				}
				else if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle == __USB_DRV_OK_APP_NOT_READY__)
				{
					CloseUsbDevice(nTmpHandle);	// for stop the USB kernel state

					m_stc_Z2_ActionStatus.SetWindowTextW(L"*** Application isn't ready now! try open it again ***");
				}
				break;

			case 3:
				m_stc_Z3_Id_Port_Info.SetWindowTextW(szPrintInfoBuffer);
				// initialize this device
				if ((m_sZebraUI[m_SelectIndx].m_AppZebraHandle = bInitUsbDevice(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, &locTmpZHandle)) >= 0)
				{
					if (getZebraSWVersion(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, &sZebraVersion) > 0)
					{
						swprintf(szPrintInfoBuffer, L"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_APP_INFO, szPrintInfoBuffer);
					}
					m_stc_Z3_ActionStatus.SetWindowTextW(L"Open");
				}
				else if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle == __USB_DRV_OK_APP_NOT_READY__)
				{
					CloseUsbDevice(nTmpHandle);	// for stop the USB kernel state

					m_stc_Z3_ActionStatus.SetWindowTextW(L"*** Application isn't ready now! try open it again ***");
				}
				break;

			case 4:
				m_stc_Z4_Id_Port_Info.SetWindowTextW(szPrintInfoBuffer);
				// initialize this device
				if ((m_sZebraUI[m_SelectIndx].m_AppZebraHandle = bInitUsbDevice(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, &locTmpZHandle)) >= 0)
				{
					if (getZebraSWVersion(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, &sZebraVersion) > 0)
					{
						swprintf(szPrintInfoBuffer, L"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_APP_INFO, szPrintInfoBuffer);
					}
					m_stc_Z4_ActionStatus.SetWindowTextW(L"Open");
				}
				else if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle == __USB_DRV_OK_APP_NOT_READY__)
				{
					CloseUsbDevice(nTmpHandle);	// for stop the USB kernel state

					m_stc_Z4_ActionStatus.SetWindowTextW(L"*** Application isn't ready now! try open it again ***");
				}
				break;
			}
		}
	}
}



void CMultiZebrasDemoDlg::OnBnClickedBtnTestCfg()
{
	// TODO: Add your control notification handler code here
	CString  strFile;
	CFileOpenCombo dlgTestStepCfg(TRUE);// , L"text", strFile);
	OPENFILENAME& ofn = dlgTestStepCfg.GetOFN();
	int nModal;

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

	nModal = dlgTestStepCfg.DoModal();

	if ((IDOK == nModal))
	{
		int rtval;
		CString s = dlgTestStepCfg.GetPathName();
		SetDlgItemText(IDC_EDT_TEST_STEP_CFG, s);
		wcscpy(m_sZebraUI[m_SelectIndx].m_LoadStepRegName, s);
	}
}

void CMultiZebrasDemoDlg::OnBnClickedBtnLoadTestStep()
{
	// TODO: Add your control notification handler code here
	// check zebra is open
	if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle < 0)
	{
		MessageBox(zsZebraHandleInitedStatus(m_sZebraUI[m_SelectIndx].m_AppZebraHandle));
		return;
	}
	// check zebra is ready!
	if (m_sZebraUI[m_SelectIndx].m_ZebraActionStatus != Act_ZebraReadForNew)
	{
		MessageBox(zsZebraBusyAction(m_sZebraUI[m_SelectIndx].m_ZebraActionStatus));
		return;
	}
	GetDlgItemText(IDC_EDT_TEST_STEP_CFG, m_sZebraUI[m_SelectIndx].m_LoadStepRegName, MAX_PATH);
	PostThreadMessage(m_ThrdId[m_SelectIndx], WM_MIPI_THREAD_ACTION, Act_LoadRegisterFile, 0x0);
}


void CMultiZebrasDemoDlg::UpdateRunStepCmbList(__HZHANDLE__ hZhandle, int nZebraApIndex)
{
	SetDlgItemInt(IDC_STC_LOADED_STEPS_CNT, m_sZebraUI[nZebraApIndex].m_TestStepCnt);

	if (m_RDO_AlaisRun.GetCheck() == BST_CHECKED)
	{
		if (getAliasRunStepsCntJustDownload(hZhandle))
		{
			char *pAlias;
			// set run alais combo box ...
			for (int i = m_Combo_RunNames.GetCount() - 1; i >= 0; i--)
				m_Combo_RunNames.DeleteString(i);

			pAlias = get1stDownloadStepAliasName(hZhandle);
			if (pAlias)
			{
				TCHAR *pwAliasName;
				BOOL bFistName = FALSE;
				do
				{
					pwAliasName = lpAnsi2lpWChar(pAlias);

					m_Combo_RunNames.AddString(pwAliasName);
					if (bFistName == FALSE)
					{
						SetDlgItemText(IDC_CMB_RUN_NAME, pwAliasName);
						bFistName = TRUE;
					}
					free(pwAliasName);
				} while (pAlias = getNextDownloadStepAliasName(hZhandle));
			}
			else
			{
				SetDlgItemText(IDC_CMB_RUN_NAME, L"<None>");
			}
		}
	}
	else if (m_RDO_FileRun.GetCheck() == BST_CHECKED)
	{
		if (getRegisterStepsCntJustDownload(hZhandle))
		{
			char *pRegisterFile;

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

			pRegisterFile = get1stDownloadRegisterStepName(hZhandle);
			if (pRegisterFile)
			{
				TCHAR *pwRegisterName;
				BOOL bFistName = FALSE;
				do
				{
					pwRegisterName = lpAnsi2lpWChar(pRegisterFile);

					m_Combo_RunNames.AddString(pwRegisterName);
					if (bFistName == FALSE)
					{
						SetDlgItemText(IDC_CMB_RUN_NAME, pwRegisterName);
						bFistName = TRUE;
					}
					free(pwRegisterName);
				} while (pRegisterFile = getNextDownloadRegisterStepName(hZhandle));
			}
			else
			{
				SetDlgItemText(IDC_CMB_RUN_NAME, L"<None>");
			}
		}
	}
}


void CMultiZebrasDemoDlg::OnBnClickedRdoAliasRun()
{
	// TODO: Add your control notification handler code here
	UpdateRunStepCmbList(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, m_SelectIndx);
}


void CMultiZebrasDemoDlg::OnBnClickedRdoFilenameRun()
{
	// TODO: Add your control notification handler code here
	UpdateRunStepCmbList(m_sZebraUI[m_SelectIndx].m_AppZebraHandle, m_SelectIndx);
}


void CMultiZebrasDemoDlg::OnBnClickedBtnRunStep()
{
	// TODO: Add your control notification handler code here
	TCHAR wzPrintbuffer[256];

	if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle < 0)
	{
		MessageBox(zsZebraHandleInitedStatus(m_sZebraUI[m_SelectIndx].m_AppZebraHandle));
		return;
	}
	// check zebra is ready!
	if (m_sZebraUI[m_SelectIndx].m_ZebraActionStatus != Act_ZebraReadForNew)
	{
		MessageBox(zsZebraBusyAction(m_sZebraUI[m_SelectIndx].m_ZebraActionStatus));
		return;
	}

	if (m_RDO_AlaisRun.GetCheck() == BST_CHECKED)
	{
		m_sZebraUI[m_SelectIndx].m_RunType = __Run_Step_by_AliasName;
		GetDlgItemText(IDC_CMB_RUN_NAME, m_sZebraUI[m_SelectIndx].m_AliasTestRegisterName, MAX_PATH);
		swprintf(wzPrintbuffer, L"Run alias \"%s\"", m_sZebraUI[m_SelectIndx].m_AliasTestRegisterName);
		UpdateProgressMsg(m_SelectIndx, 0, wzPrintbuffer);
	}
	else if (m_RDO_FileRun.GetCheck() == BST_CHECKED)
	{
		m_sZebraUI[m_SelectIndx].m_RunType = __Run_Step_by_FileName;
		GetDlgItemText(IDC_CMB_RUN_NAME, m_sZebraUI[m_SelectIndx].m_AliasTestRegisterName, MAX_PATH);
		swprintf(wzPrintbuffer, L"Run register \"%s\"", m_sZebraUI[m_SelectIndx].m_AliasTestRegisterName);
		UpdateProgressMsg(m_SelectIndx, 0, wzPrintbuffer);
	}
	else
	{
		// No option to select here!
		m_sZebraUI[m_SelectIndx].m_RunType = __Run_Step_by_Id;
		m_sZebraUI[m_SelectIndx].m_AliasTestRegisterName[0] = 0x0;
		swprintf(wzPrintbuffer, L"Run test step %d", 0x0);
		UpdateProgressMsg(m_SelectIndx, 0, wzPrintbuffer);
	}
	PostThreadMessage(m_ThrdId[m_SelectIndx], WM_MIPI_THREAD_ACTION, Act_RunTestStepOrRegister, 0x0);
}


void CMultiZebrasDemoDlg::OnBnClickedBtnGrabImg()
{
	// TODO: Add your control notification handler code here
	TCHAR wzPrintbuffer[256];

	if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle < 0)
	{
		MessageBox(zsZebraHandleInitedStatus(m_sZebraUI[m_SelectIndx].m_AppZebraHandle));
		return;
	}
	// check zebra is ready!
	if (m_sZebraUI[m_SelectIndx].m_ZebraActionStatus != Act_ZebraReadForNew)
	{
		MessageBox(zsZebraBusyAction(m_sZebraUI[m_SelectIndx].m_ZebraActionStatus));
		return;
	}

	m_sZebraUI[m_SelectIndx].m_GrabStart = GetDlgItemInt(IDC_EDT_GRAB_IMG_START);
	m_sZebraUI[m_SelectIndx].m_GrabEnd = GetDlgItemInt(IDC_EDT_GRAB_IMG_END);
	GetDlgItemText(IDC_EDT_SAVE_IMG_NAME, m_sZebraUI[m_SelectIndx].m_GrabImgSaveName, MAX_PATH);

	swprintf(wzPrintbuffer, L"Grabbing image from %d to %d...", m_sZebraUI[m_SelectIndx].m_GrabStart, m_sZebraUI[m_SelectIndx].m_GrabEnd);
	UpdateProgressMsg(m_SelectIndx, 0, wzPrintbuffer);

	PostThreadMessage(m_ThrdId[m_SelectIndx], WM_MIPI_THREAD_ACTION, Act_GrabImageData, 0x0);
}


void CMultiZebrasDemoDlg::OnBnClickedBtnSelectScriptFile()
{
	// TODO: Add your control notification handler code here
	CString  strFile = L"*.script;*.Script";
	CFileOpenCombo 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);
		wcscpy(m_sZebraUI[m_SelectIndx].m_ScriptName, s);
	}
}


void CMultiZebrasDemoDlg::OnBnClickedBtnRunScript()
{
	// TODO: Add your control notification handler code here
	
	if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle < 0)
	{
		MessageBox(zsZebraHandleInitedStatus(m_sZebraUI[m_SelectIndx].m_AppZebraHandle));
		return;
	}
	// check zebra is ready!
	if (m_sZebraUI[m_SelectIndx].m_ZebraActionStatus != Act_ZebraReadForNew)
	{
		MessageBox(zsZebraBusyAction(m_sZebraUI[m_SelectIndx].m_ZebraActionStatus));
		return;
	}

	if (m_chk_ScriptDontSavImg.GetCheck() == BST_CHECKED)
		m_sZebraUI[m_SelectIndx].m_ScriptDontSaveImage = 1;
	else
		m_sZebraUI[m_SelectIndx].m_ScriptDontSaveImage = 0;

	GetDlgItemText(IDC_EDT_SCRIPT_NAME, m_sZebraUI[m_SelectIndx].m_ScriptName, MAX_PATH);

	PostThreadMessage(m_ThrdId[m_SelectIndx], WM_MIPI_THREAD_ACTION, Act_RunTestStepScript, 0x0);
}


void CMultiZebrasDemoDlg::OnBnClickedRdoI2cRead()
{
	// TODO: Add your control notification handler code here
	CWnd *pWnd;

	pWnd = GetDlgItem(IDC_EDT_I2C_READ_LEN);
	pWnd->EnableWindow(TRUE);
	pWnd = GetDlgItem(IDC_STC_READ_BYTES);
	pWnd->EnableWindow(TRUE);


	pWnd = GetDlgItem(IDC_STC_SUB_ADDR);
	pWnd->EnableWindow(TRUE);
	pWnd = GetDlgItem(IDC_CMB_I2C_SUBADDR_TYPE);
	pWnd->EnableWindow(TRUE);
	pWnd = GetDlgItem(IDC_EDT_I2C_SUBADDR);
	pWnd->EnableWindow(TRUE);

	pWnd = GetDlgItem(IDC_BTN_I2C_READ_WRITE);
	pWnd->SetWindowText(L"I2C read");
}


void CMultiZebrasDemoDlg::OnBnClickedRdoI2cWrite()
{
	// TODO: Add your control notification handler code here
	CWnd *pWnd;
	pWnd = GetDlgItem(IDC_EDT_I2C_READ_LEN);
	pWnd->EnableWindow(FALSE);
	pWnd = GetDlgItem(IDC_STC_READ_BYTES);
	pWnd->EnableWindow(FALSE);


	pWnd = GetDlgItem(IDC_STC_SUB_ADDR);
	pWnd->EnableWindow(FALSE);
	pWnd = GetDlgItem(IDC_CMB_I2C_SUBADDR_TYPE);
	pWnd->EnableWindow(FALSE);
	pWnd = GetDlgItem(IDC_EDT_I2C_SUBADDR);
	pWnd->EnableWindow(FALSE);

	pWnd = GetDlgItem(IDC_BTN_I2C_READ_WRITE);
	pWnd->SetWindowText(L"I2C write");
}


void CMultiZebrasDemoDlg::OnBnClickedBtnI2cReadWrite()
{
	// TODO: Add your control notification handler code here
	TCHAR szI2cInfoBuffer[256];

	if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle < 0)
	{
		MessageBox(zsZebraHandleInitedStatus(m_sZebraUI[m_SelectIndx].m_AppZebraHandle));
		return;
	}
	// check zebra is ready!
	if (m_sZebraUI[m_SelectIndx].m_ZebraActionStatus != Act_ZebraReadForNew)
	{
		MessageBox(zsZebraBusyAction(m_sZebraUI[m_SelectIndx].m_ZebraActionStatus));
		return;
	}

	m_sZebraUI[m_SelectIndx].m_I2C_cfgByte = 0;
	if (m_RDO_I2CRead.GetCheck() == BST_CHECKED)
	{
		char *pI2cSubAddr = NULL;
		m_sZebraUI[m_SelectIndx].m_I2C_cfgByte |= _ReadI2cDevice;

		// Get i2c read bytes
		m_sZebraUI[m_SelectIndx].m_I2C_ReadWriteLen = GetDlgItemInt(IDC_EDT_I2C_READ_LEN);
		
		switch (m_Combo_I2CRdSubAddrBytes.GetCurSel())
		{
		case 0:
			break;
		case 1:
			m_sZebraUI[m_SelectIndx].m_I2C_cfgByte |= _1byteRdSubAddr;

			GetDlgItemText(IDC_EDT_I2C_SUBADDR, szI2cInfoBuffer, 256);
			fnDecodeHexStr2Values(pI2cSubAddr = lpWChar2lpAnsi(szI2cInfoBuffer), m_sZebraUI[m_SelectIndx].m_I2C_SubAddr, 4, 1);
			break;
		case 2:
			m_sZebraUI[m_SelectIndx].m_I2C_cfgByte |= _2bytesRdSubAddr;

			GetDlgItemText(IDC_EDT_I2C_SUBADDR, szI2cInfoBuffer, 256);
			fnDecodeHexStr2Values(pI2cSubAddr = lpWChar2lpAnsi(szI2cInfoBuffer), m_sZebraUI[m_SelectIndx].m_I2C_SubAddr, 4, 2);
			break;
		case 3:
			m_sZebraUI[m_SelectIndx].m_I2C_cfgByte |= _3bytesRdSubAddr;

			GetDlgItemText(IDC_EDT_I2C_SUBADDR, szI2cInfoBuffer, 256);
			fnDecodeHexStr2Values(pI2cSubAddr = lpWChar2lpAnsi(szI2cInfoBuffer), m_sZebraUI[m_SelectIndx].m_I2C_SubAddr, 4, 3);
			break;
		}
		if (pI2cSubAddr)free(pI2cSubAddr);
	}
	else if (m_RDO_I2CWrite.GetCheck() == BST_CHECKED)
	{
		// m_sZebraUI[m_SelectIndx].m_I2C_ReadWriteLen write length calculated from actual write edite-box
		char *pI2cWrData;
		GetDlgItemText(IDC_EDT_I2C_DATA, szI2cInfoBuffer, 256);
		m_sZebraUI[m_SelectIndx].m_I2C_ReadWriteLen = fnDecodeHexStr2Values(pI2cWrData = lpWChar2lpAnsi(szI2cInfoBuffer), m_sZebraUI[m_SelectIndx].m_I2C_RdWrData, 256, 256);
		free(pI2cWrData);
	}

	if (m_Combo_I2CAddrBits.GetCurSel() == 1)	// 10 bits
	{
		m_sZebraUI[m_SelectIndx].m_I2C_cfgByte |= _10BitI2C_Addr;
	}

	GetDlgItemText(IDC_EDT_I2C_ADDR, szI2cInfoBuffer, 256);
	swscanf(szI2cInfoBuffer, L"0x%x", &m_sZebraUI[m_SelectIndx].m_I2C_Addr);

	if (m_chk_I2CIgnoreAck.GetCheck() == BST_CHECKED)
	{
		m_sZebraUI[m_SelectIndx].m_I2C_cfgByte |= _IgnoreAckChking;
	}

	PostThreadMessage(m_ThrdId[m_SelectIndx], WM_MIPI_THREAD_ACTION, Act_I2CReadWrite, 0x0);
}



void CMultiZebrasDemoDlg::OnBnClickedBtnReset()
{
	// TODO: Add your control notification handler code here

	if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle < 0)
	{
		MessageBox(zsZebraHandleInitedStatus(m_sZebraUI[m_SelectIndx].m_AppZebraHandle));
		return;
	}
	// check zebra is ready!
	if (m_sZebraUI[m_SelectIndx].m_ZebraActionStatus != Act_ZebraReadForNew)
	{
		MessageBox(zsZebraBusyAction(m_sZebraUI[m_SelectIndx].m_ZebraActionStatus));
		return;
	}

	if (m_RDO_AppReset.GetCheck() == BST_CHECKED)
	{
		m_sZebraUI[m_SelectIndx].m_ResetByApp = 1;
	}
	else if (m_RDO_UsbReset.GetCheck() == BST_CHECKED)
	{
		m_sZebraUI[m_SelectIndx].m_ResetByApp = 0;
	}

	PostThreadMessage(m_ThrdId[m_SelectIndx], WM_MIPI_THREAD_ACTION, Act_ResetZebraBrd, 0x0);
}


void CMultiZebrasDemoDlg::OnBnClickedBtnGetZebraSteps()
{
	// TODO: Add your control notification handler code here
	TCHAR szGotTestStepName[256];
	char *pGotZebraStepNmae;

	if (m_sZebraUI[m_SelectIndx].m_AppZebraHandle < 0)
	{
		MessageBox(zsZebraHandleInitedStatus(m_sZebraUI[m_SelectIndx].m_AppZebraHandle));
		return;
	}
	// check zebra is ready!
	if (m_sZebraUI[m_SelectIndx].m_ZebraActionStatus != Act_ZebraReadForNew)
	{
		MessageBox(zsZebraBusyAction(m_sZebraUI[m_SelectIndx].m_ZebraActionStatus));
		return;
	}

	GetDlgItemText(IDC_EDT_GOT_ZEBRA_STEPS_NAME, szGotTestStepName, 256);

	strcpy(m_sZebraUI[m_SelectIndx].m_GotZebraTestStepName, pGotZebraStepNmae = lpWChar2lpAnsi(szGotTestStepName));

	PostThreadMessage(m_ThrdId[m_SelectIndx], WM_MIPI_THREAD_ACTION, Act_GetBrdTestSteps, 0x0);
	free(pGotZebraStepNmae);
}


void CMultiZebrasDemoDlg::UpdateProgressMsg(int nZId, int PrgCnt, TCHAR *pMsg)
{
	switch (nZId)
	{
	case 1:
		if (PrgCnt >= 0)
			gThis->m_Z1_progress.SetPos(PrgCnt);

		if (pMsg)
			gThis->SetDlgItemTextW(IDC_STC_Z1_ACTION_STATUS, pMsg);
		break;
	case 2:
		if (PrgCnt >= 0)
			gThis->m_Z2_progress.SetPos(PrgCnt);
		if (pMsg)
			gThis->SetDlgItemTextW(IDC_STC_Z2_ACTION_STATUS, pMsg);
		break;
	case 3:
		if (PrgCnt >= 0)
			gThis->m_Z3_progress.SetPos(PrgCnt);
		if (pMsg)
			gThis->SetDlgItemTextW(IDC_STC_Z3_ACTION_STATUS, pMsg);
		break;
	case 4:
		if (PrgCnt >= 0)
			gThis->m_Z4_progress.SetPos(PrgCnt);
		if (pMsg)
			gThis->SetDlgItemTextW(IDC_STC_Z4_ACTION_STATUS, pMsg);
		break;
	}
}


void CMultiZebrasDemoDlg::OnChangeEdtSelectZebraBrdIndx()
{
	// TODO:  If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialogEx::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.

	// TODO:  Add your control notification handler code here
	if (m_SelectIndx > 0) 
		saveCurrentContext2Thread(m_SelectIndx);

	m_SelectIndx = GetDlgItemInt(IDC_EDT_SELECT_ZEBRA_BRD_INDX);		// which frame is try to select.
	if (m_SelectIndx > 0)
		restoreThreadContext(m_SelectIndx);
}

void CMultiZebrasDemoDlg::saveCurrentContext2Thread(int ThrdIndex)
{
	TCHAR szTmpBuffer[256];
	char *pAnsiTmpPtr;

	m_sZebraUI[ThrdIndex].m_TestStepCnt = GetDlgItemInt(IDC_STC_LOADED_STEPS_CNT);
	GetDlgItemText(IDC_EDT_TEST_STEP_CFG, m_sZebraUI[ThrdIndex].m_LoadStepRegName, MAX_PATH);

	m_sZebraUI[ThrdIndex].m_ResetByApp = (m_RDO_AppReset.GetCheck() == BST_CHECKED);

	m_sZebraUI[ThrdIndex].m_TestStepImgCnt = GetDlgItemInt(IDC_STC_RUN_IMG_CNT);

	if (m_chk_RunAsStreaming.GetCheck() == BST_CHECKED)
		m_sZebraUI[ThrdIndex].m_RunAsStreaming = __OPT_STREAMING_ON__;
	else
		m_sZebraUI[ThrdIndex].m_RunAsStreaming = __OPT_STREAMING_OFF__;

	if (m_RDO_AlaisRun.GetCheck() == BST_CHECKED)
		m_sZebraUI[ThrdIndex].m_RunType = __Run_Step_by_AliasName;
	else if (m_RDO_FileRun.GetCheck() == BST_CHECKED)
		m_sZebraUI[ThrdIndex].m_RunType = __Run_Step_by_FileName;
	else
		m_sZebraUI[ThrdIndex].m_RunType = __Run_Step_by_Id;
	
	m_sZebraUI[ThrdIndex].m_TestStepId = GetDlgItemInt(IDC_STC_RUN_STEP_ID);
	GetDlgItemText(IDC_CMB_RUN_NAME, m_sZebraUI[ThrdIndex].m_AliasTestRegisterName, MAX_PATH);

	GetDlgItemText(IDC_EDT_GOT_ZEBRA_STEPS_NAME, szTmpBuffer, 256);
	strcpy(m_sZebraUI[ThrdIndex].m_GotZebraTestStepName, pAnsiTmpPtr = lpWChar2lpAnsi(szTmpBuffer));
	free(pAnsiTmpPtr);

	m_sZebraUI[ThrdIndex].m_GrabStart = GetDlgItemInt(IDC_EDT_GRAB_IMG_START);
	m_sZebraUI[ThrdIndex].m_GrabEnd	= GetDlgItemInt(IDC_EDT_GRAB_IMG_END);

	if (m_chkRaw8To10.GetCheck() == BST_CHECKED)
		m_sZebraUI[ThrdIndex].m_ImgRaw8To10 = 1;
	else
		m_sZebraUI[ThrdIndex].m_ImgRaw8To10 = 0;

	GetDlgItemText(IDC_EDT_SAVE_IMG_NAME, m_sZebraUI[ThrdIndex].m_GrabImgSaveName, MAX_PATH);

	GetDlgItemText(IDC_EDT_APP_INFO, m_sZebraUI[ThrdIndex].m_ZebraAppInfo, 128);

	// script
	if (m_chk_ScriptDontSavImg.GetCheck() == BST_CHECKED)
		m_sZebraUI[ThrdIndex].m_ScriptDontSaveImage = 1;
	else
		m_sZebraUI[ThrdIndex].m_ScriptDontSaveImage = 0;

	if (m_scriptchkRaw8To10.GetCheck() == BST_CHECKED)
		m_sZebraUI[ThrdIndex].m_ScriptImgRaw8To10 = 1;
	else
		m_sZebraUI[ThrdIndex].m_ScriptImgRaw8To10 = 0;

	GetDlgItemText(IDC_EDT_SCRIPT_NAME, m_sZebraUI[ThrdIndex].m_ScriptName, MAX_PATH);

	// I2c
	if (m_RDO_I2CRead.GetCheck() == BST_CHECKED)
		m_sZebraUI[ThrdIndex].m_I2C_cfgByte |= _ReadI2cDevice;
	else
		m_sZebraUI[ThrdIndex].m_I2C_cfgByte &= ~_ReadI2cDevice;

	m_sZebraUI[ThrdIndex].m_I2C_ReadWriteLen = GetDlgItemInt(IDC_EDT_I2C_READ_LEN);

	GetDlgItemText(IDC_CMB_I2C_ADDR_BITS, m_sZebraUI[ThrdIndex].m_I2cAddrTypeTxt, 16);

	GetDlgItemText(IDC_EDT_I2C_ADDR, szTmpBuffer, 256);
	swscanf(szTmpBuffer, L"0x%x", &m_sZebraUI[ThrdIndex].m_I2C_Addr);

	GetDlgItemText(IDC_CMB_I2C_SUBADDR_TYPE, m_sZebraUI[ThrdIndex].m_I2cSubAddrByteCntTxt, 16);
	GetDlgItemText(IDC_EDT_I2C_SUBADDR, m_sZebraUI[ThrdIndex].m_I2cSubAddrContext, 32);

	if (m_chk_I2CIgnoreAck.GetCheck() == BST_CHECKED)
	{
		m_sZebraUI[ThrdIndex].m_I2C_cfgByte |= _IgnoreAckChking;
	}
	else
		m_sZebraUI[ThrdIndex].m_I2C_cfgByte &= ~_IgnoreAckChking;

	GetDlgItemText(IDC_EDT_I2C_DATA, szTmpBuffer, 256);
	strcpy((char *)m_sZebraUI[ThrdIndex].m_I2C_RdWrData, pAnsiTmpPtr= lpWChar2lpAnsi(szTmpBuffer));
	free(pAnsiTmpPtr);
}

void CMultiZebrasDemoDlg::restoreThreadContext(int ThrdIndex)
{
	TCHAR szTmpBuffer[256];
	LPTSTR pzwTestStepName;
	SetDlgItemInt(IDC_STC_LOADED_STEPS_CNT, m_sZebraUI[ThrdIndex].m_TestStepCnt);
	SetDlgItemText(IDC_EDT_TEST_STEP_CFG, m_sZebraUI[ThrdIndex].m_LoadStepRegName);

	if (m_sZebraUI[ThrdIndex].m_ResetByApp)
	{
		m_RDO_AppReset.SetCheck(BST_CHECKED);
		m_RDO_UsbReset.SetCheck(BST_UNCHECKED);
	}
	else
	{
		m_RDO_AppReset.SetCheck(BST_UNCHECKED);
		m_RDO_UsbReset.SetCheck(BST_CHECKED);
	}
	
	SetDlgItemInt(IDC_STC_RUN_IMG_CNT, m_sZebraUI[ThrdIndex].m_TestStepImgCnt);

	if (m_sZebraUI[ThrdIndex].m_RunAsStreaming == __OPT_STREAMING_ON__)
		m_chk_RunAsStreaming.SetCheck(BST_CHECKED);
	else
		m_chk_RunAsStreaming.SetCheck(BST_UNCHECKED);

	if (m_sZebraUI[ThrdIndex].m_RunType == __Run_Step_by_AliasName)
	{
		m_RDO_AlaisRun.SetCheck(BST_CHECKED);
		m_RDO_FileRun.SetCheck(BST_UNCHECKED);

	}
	else if (m_sZebraUI[ThrdIndex].m_RunType == __Run_Step_by_FileName)
	{
		m_RDO_AlaisRun.SetCheck(BST_UNCHECKED);
		m_RDO_FileRun.SetCheck(BST_CHECKED);
	}
	else
	{
		m_RDO_AlaisRun.SetCheck(BST_UNCHECKED);
		m_RDO_FileRun.SetCheck(BST_UNCHECKED);
	}
	SetDlgItemInt(IDC_STC_RUN_STEP_ID, m_sZebraUI[ThrdIndex].m_TestStepId);
	SetDlgItemText(IDC_CMB_RUN_NAME, m_sZebraUI[ThrdIndex].m_AliasTestRegisterName);

	SetDlgItemText(IDC_EDT_GOT_ZEBRA_STEPS_NAME, pzwTestStepName = lpAnsi2lpWChar(m_sZebraUI[ThrdIndex].m_GotZebraTestStepName));
	free(pzwTestStepName);

	SetDlgItemInt(IDC_EDT_GRAB_IMG_START, m_sZebraUI[ThrdIndex].m_GrabStart);
	SetDlgItemInt(IDC_EDT_GRAB_IMG_END, m_sZebraUI[ThrdIndex].m_GrabEnd);
	SetDlgItemText(IDC_EDT_SAVE_IMG_NAME, m_sZebraUI[ThrdIndex].m_GrabImgSaveName);
	if (m_sZebraUI[ThrdIndex].m_ImgRaw8To10 == 1)
		m_chkRaw8To10.SetCheck(BST_CHECKED);
	else
		m_chkRaw8To10.SetCheck(BST_UNCHECKED);

	SetDlgItemText(IDC_EDT_APP_INFO, m_sZebraUI[ThrdIndex].m_ZebraAppInfo);

	// Script
	if (m_sZebraUI[ThrdIndex].m_ScriptDontSaveImage == 1)
		m_chk_ScriptDontSavImg.SetCheck(BST_CHECKED);
	else
		m_chk_ScriptDontSavImg.SetCheck(BST_UNCHECKED);

	if (m_sZebraUI[ThrdIndex].m_ScriptImgRaw8To10 == 1)
		m_scriptchkRaw8To10.SetCheck(BST_CHECKED);
	else
		m_scriptchkRaw8To10.SetCheck(BST_UNCHECKED);

	SetDlgItemText(IDC_EDT_SCRIPT_NAME, m_sZebraUI[ThrdIndex].m_ScriptName);

	// i2c 
	if (m_sZebraUI[ThrdIndex].m_I2C_cfgByte & _ReadI2cDevice)
	{
		m_RDO_I2CRead.SetCheck(BST_CHECKED);
		m_RDO_I2CWrite.SetCheck(BST_UNCHECKED);
		OnBnClickedRdoI2cRead();
	}
	else
	{
		m_RDO_I2CRead.SetCheck(BST_UNCHECKED);
		m_RDO_I2CWrite.SetCheck(BST_CHECKED);
		OnBnClickedRdoI2cWrite();
	}
	SetDlgItemInt(IDC_EDT_I2C_READ_LEN, m_sZebraUI[ThrdIndex].m_I2C_ReadWriteLen);

	SetDlgItemText(IDC_CMB_I2C_ADDR_BITS, m_sZebraUI[ThrdIndex].m_I2cAddrTypeTxt);

	swprintf(szTmpBuffer, L"0x%x", m_sZebraUI[ThrdIndex].m_I2C_Addr);
	SetDlgItemText(IDC_EDT_I2C_ADDR, szTmpBuffer);

	SetDlgItemText(IDC_CMB_I2C_SUBADDR_TYPE, m_sZebraUI[ThrdIndex].m_I2cSubAddrByteCntTxt);
	SetDlgItemText(IDC_EDT_I2C_SUBADDR, m_sZebraUI[ThrdIndex].m_I2cSubAddrContext);

	if (m_sZebraUI[ThrdIndex].m_I2C_cfgByte &_IgnoreAckChking)
	{
		m_chk_I2CIgnoreAck.SetCheck(BST_CHECKED);
	}
	else
		m_chk_I2CIgnoreAck.SetCheck(BST_UNCHECKED);

	SetDlgItemText(IDC_EDT_I2C_DATA, pzwTestStepName = lpAnsi2lpWChar((char *)m_sZebraUI[ThrdIndex].m_I2C_RdWrData));
	free(pzwTestStepName);
}

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

	switch (message)
	{
	case WM_MIPI_DEVICEARRIVAL:
		// show zebra info dialog box
		m_ZebraInfoDlgOpenMode = __zInfoDlgOpen_View__;
		DialogBoxParam(GetModuleHandle(NULL),		// Modal dialog (), // CreateDialog - for Modeless dialog
			MAKEINTRESOURCE(IDD_DIALOG_ZEBRAS),
			this->m_hWnd,
			(DLGPROC)ZebraInfoDlg, (LPARAM)this);
		break;

	case WM_MIPI_DEVICEREMOVECOMPLETE:
		hZhandle = (__HZHANDLE__)wParam;
		for (int i = 1; i < (__ZebraAppMax__+1); i++)
		{
			if (m_sZebraUI[i].m_AppZebraHandle == hZhandle)
			{
				// set ui 
				switch (hZhandle)
				{
				case 0:
				case 1:
				case 2:
				case 3:
					break;
				default:
					break;
				}	// switch

				// set board info
				pZebraBoardInfo = getZebraBoardInfo(hZhandle, NULL);
				pZebraBoardInfo->nZebraStatus = __Zebra_Removed__;
				CloseUsbDevice(hZhandle);

				// set App open handle to not found
				m_sZebraUI[i].m_AppZebraHandle = __USB_HANDLE_NOT_FOUND__;
			}
		}

		// show zebra info dialog box
		m_ZebraInfoDlgOpenMode = __zInfoDlgOpen_View__;
		DialogBoxParam(GetModuleHandle(NULL),		// Modal dialog (), // CreateDialog - for Modeless dialog
			MAKEINTRESOURCE(IDD_DIALOG_ZEBRAS),
			this->m_hWnd,
			(DLGPROC)ZebraInfoDlg, (LPARAM)this);
		break;
	}	// switch
	return CDialogEx::WindowProc(message, wParam, lParam);
}


void CMultiZebrasDemoDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
#if 1
	m_ZebraInfoDlgOpenMode = __zInfoDlgOpen_View__;
	if (DialogBoxParam(GetModuleHandle(NULL),		// Modal dialog (), // CreateDialog - for Modeless dialog
		MAKEINTRESOURCE(IDD_DIALOG_ZEBRAS),
		this->m_hWnd,
		(DLGPROC)ZebraInfoDlg, (LPARAM)this) == IDOK)
	{
		// to be added ...
	}
#else
	if (!IsWindow(g_hwndZebrs))
	{
		g_hwndZebrs = ::CreateDialog(GetModuleHandle(NULL),
			MAKEINTRESOURCE(IDD_DIALOG_ZEBRAS),
			this->m_hWnd,
			(DLGPROC)ZebraInfoDlg);
		::ShowWindow(g_hwndZebrs, SW_SHOW);
		// 
		// use DestroyWindow(hwndDlg) at IDCANCEL dialog box!!!
		// and reset g_hwndZebrs to NULL in ZebraInfoDlg procedure
	}
#endif
	CDialogEx::OnRButtonDown(nFlags, point);
}


void CMultiZebrasDemoDlg::OnClose()
{
	// TODO: Add your message handler code here and/or call default
	int i;

	m_FoundZebras = ZebraCardNumber();
	for (i = 0; i < m_FoundZebras; i++)		// traversing all found zebra
	{
		__PZEBRA_BOARD_INFO__ pZebraBdInfo;
		pZebraBdInfo = getZebraBoardInfo(i, NULL);
		if (pZebraBdInfo->nZebraStatus >= __Zebra_Open_DrvNoApp__)	// is open by me!
		{
			CloseUsbDevice(i);		// only shutdown that i had open Zebra 
		}
	}

	// Stop monitor procedure
	StopMipiUsbNotifyWin();

	freeZebrasInfoListQueue();

	// Stop all handle thread!
	for (int i = 1; i <= __ZebraAppMax__; i++)
	{
		SetEvent(m_ExitEvent[i]);	// Quit thread
		WaitForSingleObject(m_ThrdHandle[i], INFINITE);		// Wait thread exit
		CloseHandle(m_ExitEvent[i]);
	}

	// Close average image grab-thread
	for (int i = 1; i <= __ZebraAppMax__; i++)
	{
		m_sZebraUI[i].bGrabExit = TRUE;
		SetEvent(m_sZebraUI[i].hGrabThrdCmd);
		WaitForSingleObject(m_sZebraUI[i].hGrabThrd, INFINITE);
		CloseHandle(m_sZebraUI[i].hGrabThrdCmd);
		CloseHandle(m_sZebraUI[i].hGrabThrdRslt);
	}
	CDialogEx::OnClose();
}


void CMultiZebrasDemoDlg::OnBnClickedChkGetUnsave()
{
	// TODO: Add your control notification handler code here
	if (m_chk_ScriptDontSavImg.GetCheck() == BST_CHECKED)
	{
		m_scriptchkRaw8To10.EnableWindow(FALSE);
	}
	else
	{
		m_scriptchkRaw8To10.EnableWindow(TRUE);
	}
}






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);
}

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

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

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

	return lptNew;
}


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

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

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

	return lpstr;
}


TCHAR *zsZebraBusyAction(int nZebraActId)
{
	switch (nZebraActId)
	{
	case Act_ZebraReadForNew:
		return L"Zebra ready for a new action";
	case 	Act_LoadRegisterFile:
		return L"Zebra loading test/register steps";
	case Act_RunTestStepOrRegister:
		return L"Zebra running a test step";
	case Act_GrabImageData:
		return L"Zebra grabbing image";
	case Act_RunTestStepScript:
		return L"Zebra running test script";
	case Act_I2CReadWrite:
		return L"Zebra i2c reading/writing";
	case Act_ResetZebraBrd:
		return L"Zebra resetting now";
	case Act_GetBrdTestSteps:
		return L"Zebra getting its test steps";
	default:
		return L"Zebra doing an unkown action";
	}
}

TCHAR *zsZebraHandleInitedStatus(int initedHandle)
{
	switch (initedHandle)
	{
	case __USB_HANDLE_NOT_INIT__:
		return L"this handle hasn't initiated";
	case __USB_HANDLE_NOT_FOUND__:
		return L"this handle not found in scanned table";
	case __USB_DRV_OK_APP_NOT_READY__:
		return L"USB driver ready, but applcation isn't ready";
	case -1:
		return L"can't open this device(USB)";
	case -2:
		return L"can't get USB descriptor";
	case -3:
		return L"can't retrive mipi pipi (end points)";
	case -4:
		return L"can't get USB i2c interface";
	case -5:
		return L"can't retrive i2c pipi";
	case -6:
		return L"can't get USB uart interface";
	case -7:
		return L"can't retrive uart pipi";
	case -8:
		return L"can't find zebra from assigned board id";
	case -9:
		return L"locked by other process";
	default:
		return L"unknow Zebra initated at unknown state";
	}
}