// UCBioBSP_EnrollDlg.cpp : implementation file
//

#include "stdafx.h"
#include "UCBioBSP_Enroll.h"
#include "UCBioBSP_EnrollDlg.h"
#include "../../../../Inc/UCBioAPI_Extension.h"
#include "../../../../Inc/UCBioAPI_Export.h"
#include "../../../../Inc/UCBioAPI_FastSearch.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

UCBioAPI_TEMPLATE_FORMAT	TemplateFormat;
UCBioAPI_TEMPLATE_TYPE		TemplateType;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

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

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CUCBioBSP_EnrollDlg dialog

CUCBioBSP_EnrollDlg::CUCBioBSP_EnrollDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CUCBioBSP_EnrollDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CUCBioBSP_EnrollDlg)
	m_strSaveDir = _T("");
	m_szPayload = _T("");
	m_striLevel = _T("4");
	m_strrLevel = _T("4");
	m_ckOverwrite = FALSE;
	m_strBitrate = _T("");
	m_chkWSQ = FALSE;
	m_chkUCT = FALSE;
	m_chkRAW = FALSE;
	m_strFormat = _T("");
	m_strType = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	m_hUCBioAPI = UCBioAPI_INVALID_HANDLE;

	m_nNumDevice = 0;
	m_pDeviceID = NULL;
	m_pDeviceInfoEx = NULL;
	m_nLastOpenedDeviceID = 0;
	m_hAuditData = NULL;
	m_hEnrolledFIR = m_hCapturedFIR = UCBioAPI_INVALID_HANDLE;
	TemplateType = UCBioAPI_TEMPLATE_TYPE_SIZE400;
}

void CUCBioBSP_EnrollDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CUCBioBSP_EnrollDlg)
	DDX_Control(pDX, IDC_CB_LIVEDETECTLEVEL, m_cbLiveDetectLevel);
	DDX_Control(pDX, IDC_CB_TERMPLATETYPE, m_cbType);
	DDX_Control(pDX, IDC_CB_TERMPLATEFORMAT, m_cbFormat);
	DDX_Control(pDX, IDC_CB_DEVICE_LIST, m_comboDeviceList);
	DDX_Text(pDX, IDC_ED_DIR, m_strSaveDir);
	DDX_Text(pDX, IDC_ED_ID, m_szPayload);
	DDV_MaxChars(pDX, m_szPayload, 8);
	DDX_CBString(pDX, IDC_CB_ILEVEL, m_striLevel);
	DDX_CBString(pDX, IDC_CB_RLEVEL, m_strrLevel);
	DDX_Check(pDX, IDC_CK_OVERWRITE, m_ckOverwrite);
	DDX_Text(pDX, IDC_ED_BITRATE, m_strBitrate);
	DDX_Check(pDX, IDC_CHECK1, m_chkWSQ);
	DDX_Check(pDX, IDC_CHECK2, m_chkUCT);
	DDX_Check(pDX, IDC_CHECK3, m_chkRAW);
	DDX_CBString(pDX, IDC_CB_TERMPLATEFORMAT, m_strFormat);
	DDX_CBString(pDX, IDC_CB_TERMPLATETYPE, m_strType);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CUCBioBSP_EnrollDlg, CDialog)
	//{{AFX_MSG_MAP(CUCBioBSP_EnrollDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BT_SEARCH, OnBtSearch)
	ON_CBN_SELCHANGE(IDC_CB_DEVICE_LIST, OnSelchangeCbDeviceList)
	ON_BN_CLICKED(IDC_BT_ENROLL, OnBtEnroll)
	ON_BN_CLICKED(IDC_BT_IDENTIFY, OnBtIdentify)
	ON_BN_CLICKED(IDC_BT_APPLY, OnBtApply)
	ON_CBN_SELCHANGE(IDC_CB_TERMPLATEFORMAT, OnSelchangeCbTermplateformat)
	ON_WM_DESTROY()
	ON_CBN_SELCHANGE(IDC_CB_TERMPLATETYPE, OnSelchangeCbTermplatetype)
	ON_CBN_SELCHANGE(IDC_CB_ILEVEL, OnSelchangeCbIlevel)
	ON_CBN_SELCHANGE(IDC_CB_RLEVEL, OnSelchangeCbRlevel)
	ON_CBN_SELCHANGE(IDC_CB_LIVEDETECTLEVEL, OnSelchangeCbLivedetectlevel)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void DisplayError(LPCTSTR szMsg, UCBioAPI_RETURN err)
{
   CString szFormat;
   szFormat.Format(_T("%s (Error : 0x%02x)"), szMsg, err);
   AfxMessageBox(szFormat, MB_ICONERROR);
}

/////////////////////////////////////////////////////////////////////////////
// CUCBioBSP_EnrollDlg message handlers

BOOL CUCBioBSP_EnrollDlg::OnInitDialog()
{
	CDialog::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)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		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
	m_chkWSQ = TRUE;
	m_chkUCT = TRUE;
	m_chkRAW = FALSE;

	UCBioAPI_RETURN err = UCBioAPI_Init(&m_hUCBioAPI);
	if (err != UCBioAPIERROR_NONE) 
	{
		DisplayError(_T("Failed to initialize UCBioBSP!"), err);
	} 
	else 
	{
		UCBioAPI_VERSION  ver;
		memset(&ver, 0, sizeof(UCBioAPI_VERSION));

		if (UCBioAPI_GetVersion(m_hUCBioAPI, &ver) == UCBioAPIERROR_NONE) 
		{
			 CString szVer;
			 szVer.Format(_T("UCBioBSP Version : v%d.%04d"), ver.Major, ver.Minor);
			 SetWindowText(szVer);
		}

		UCBioAPI_INIT_INFO_0 InitInfo0;
		memset(&InitInfo0, 0, sizeof(UCBioAPI_INIT_INFO_0));

		UCBioAPI_RETURN err = UCBioAPI_GetInitInfo(m_hUCBioAPI, 0, &InitInfo0);
		if (err == UCBioAPIERROR_NONE) 
		{
			m_strrLevel.Format("%d", InitInfo0.SecurityLevelForEnroll);
			m_striLevel.Format("%d", InitInfo0.SecurityLevelForIdentify);
		} 
		else 
		{
			DisplayError(_T("Failed to get init information!"), err);
		}

		EnumDeviceList();
		OnSelchangeCbDeviceList();

		UCBioAPI_InitFastSearchEngine(m_hUCBioAPI);
   }


	// WSQ
	m_hWSQ_library = LoadLibrary(TEXT("WSQ_library.dll"));
	if(m_hWSQ_library)
	{
		pSaveBMPToFile = (SaveBMPToFile) GetProcAddress(m_hWSQ_library, "_SaveBMPToFile");
		pSetShowFilePropertiesDialog = (SetShowFilePropertiesDialog) GetProcAddress(m_hWSQ_library, "_SetShowFilePropertiesDialog");
		pGenerateSerialNumber = (GenerateSerialNumber) GetProcAddress(m_hWSQ_library, "_GenerateSerialNumber");
		pUnlockWSQLibrary = (UnlockWSQLibrary) GetProcAddress(m_hWSQ_library, "_UnlockWSQLibrary");
		pWriteWSQ_bitrate = (WriteWSQ_bitrate) GetProcAddress(m_hWSQ_library, "_WriteWSQ_bitrate");
		pReadWSQ_bitrate = (ReadWSQ_bitrate) GetProcAddress(m_hWSQ_library, "_ReadWSQ_bitrate");
		pEncodeStream = (WSQ_encode_stream) GetProcAddress(m_hWSQ_library, "_WSQ_encode_stream");

		Unlock_WSQ_Libary();

		double bitrate = pReadWSQ_bitrate();
		m_strBitrate.Format("%.2f", (float)bitrate);
	}
	
#ifdef _COLOMBIA
	m_cbFormat.SetCurSel(2);
	m_cbType.SetCurSel(2);
	OnSelchangeCbTermplateformat();
	m_cbFormat.EnableWindow(FALSE);
#else
	m_cbFormat.SetCurSel(0);
	m_cbType.SetCurSel(2);
	m_cbLiveDetectLevel.SetCurSel(0);
	OnSelchangeCbTermplateformat();
	OnSelchangeCbTermplatetype();
	OnSelchangeCbLivedetectlevel();
#endif
	UpdateData(FALSE);

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


void CUCBioBSP_EnrollDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
	FreeLibrary(m_hWSQ_library);
	
    if (m_hEnrolledFIR != UCBioAPI_INVALID_HANDLE)
		UCBioAPI_FreeFIRHandle(m_hEnrolledFIR);
    if (m_hCapturedFIR != UCBioAPI_INVALID_HANDLE)
		UCBioAPI_FreeFIRHandle(m_hCapturedFIR);
    if (m_nLastOpenedDeviceID != 0)
		UCBioAPI_CloseDevice(m_hUCBioAPI, m_nLastOpenedDeviceID);

	UCBioAPI_ClearFastSearchDB(m_hUCBioAPI);
	UCBioAPI_TerminateFastSearchEngine(m_hUCBioAPI);
    UCBioAPI_Terminate(m_hUCBioAPI);	
}

void CUCBioBSP_EnrollDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::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 CUCBioBSP_EnrollDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (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
	{
		CDialog::OnPaint();
	}
}

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

void CUCBioBSP_EnrollDlg::OnBtSearch() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);

	LPMALLOC pMalloc;

	if(SHGetMalloc (&pMalloc)!= NOERROR) return;

	BROWSEINFO		bInfo;
	LPITEMIDLIST	pidl;

	ZeroMemory((PVOID) &bInfo,sizeof (BROWSEINFO));

	if(!m_strInitDir.IsEmpty())
	{
		OLECHAR       olePath[MAX_PATH];
		ULONG         chEaten;
		ULONG         dwAttributes;
		HRESULT       hr;
		LPSHELLFOLDER pDesktopFolder;

		if(SUCCEEDED(SHGetDesktopFolder(&pDesktopFolder)))
		{
			MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, m_strInitDir.GetBuffer(MAX_PATH), -1, olePath, MAX_PATH);

			m_strInitDir.ReleaseBuffer(-1);
			hr = pDesktopFolder->ParseDisplayName(NULL,
												NULL,
												olePath,
												&chEaten,
												&pidl,
												&dwAttributes);
			if(FAILED(hr))
			{
				pMalloc->Free (pidl);
				pMalloc->Release ();
				return;
			}

			bInfo.pidlRoot = pidl;
		}
	}

	bInfo.hwndOwner = NULL;
	bInfo.pszDisplayName = m_strSaveDir.GetBuffer(MAX_PATH);
	bInfo.lpszTitle = "";
	bInfo.ulFlags = BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS;
	bInfo.lpfn = NULL;				// address of callback function
	bInfo.lParam = (LPARAM)this;    // pass address of object to callback function

	if((pidl = ::SHBrowseForFolder(&bInfo)) != NULL)
	{
		if(::SHGetPathFromIDList(pidl, m_strSaveDir.GetBuffer(MAX_PATH)) == FALSE)
		{
			
		}
	}

	pMalloc->Free(pidl);
	pMalloc->Release();
	UpdateData(FALSE);
	
	//////////////////////////////////////////////////////////////////////////////
	// 
	UpdateData();
	UCBioAPI_ClearFastSearchDB(m_hUCBioAPI);

	HANDLE	hFindFile = NULL;
	UCBioAPI_FIR_HANDLE hNewFIR=NULL;
	WIN32_FIND_DATA wfd = { 0 };
	BYTE Template[UCBioAPI_TEMPLATE_TYPE_SIZE800*2*10];
	char szPath[MAX_PATH+1];

	sprintf(szPath, "%s\\*.uct", m_strSaveDir);
	
	if(m_strSaveDir.GetLength() == 0)
	{
		AfxMessageBox("Invalid save path");
		return;
	}
	
	hFindFile = FindFirstFile(szPath, &wfd);

	CString strOldFileName;
	int nUserID=0;
	int nOldUserID=0;
	int nCurUserID=0;
	int idx = 0;
	strOldFileName = wfd.cFileName;
	int nIndex = strOldFileName.Find("-", 0);
	nOldUserID = atoi(strOldFileName.Mid(0, nIndex));

	if(hFindFile != INVALID_HANDLE_VALUE)
	{
		do
		{
			FILE * fp;
			sprintf(szPath, "%s\\%s", m_strSaveDir, wfd.cFileName);
			if((fp = fopen( szPath, "rb")) == NULL )
				return;

			char Buff[UCBioAPI_TEMPLATE_TYPE_SIZE800*2]={0,};
			fread(Buff, TemplateType*2, 1, fp);

			CString strFileName;
			strFileName = wfd.cFileName;

			int nIndex = strFileName.Find("-", 0);
			nUserID = atoi(strFileName.Mid(0, nIndex));

			if(nOldUserID != nUserID)
			{
				nOldUserID = nUserID;

				UCBioAPI_RETURN err = UCBioAPI_TemplateToFIREx(m_hUCBioAPI, Template, idx*TemplateType*2, TemplateType, TemplateType, UCBioAPI_FIR_PURPOSE_IDENTIFY, &hNewFIR);
				UCBioAPI_INPUT_FIR inputFIR;
				inputFIR.Form = UCBioAPI_FIR_FORM_HANDLE;
				inputFIR.InputFIR.FIRinBSP = &hNewFIR;
		
				err = UCBioAPI_AddFIRToFastSearchDB(m_hUCBioAPI, &inputFIR, nCurUserID, NULL);
				UCBioAPI_FreeFIRHandle(hNewFIR);
				idx = 0;
				fclose(fp);

				memset(Template, 0, sizeof(Template));
				memcpy(&Template[idx*TemplateType*2], Buff, TemplateType*2);
				idx ++;
				int nIndex = strFileName.Find("-", 0);
				nCurUserID = atoi(strFileName.Mid(0, nIndex));
			}
			else
			{
				memcpy(&Template[idx*TemplateType*2], Buff, TemplateType*2);
				idx ++;
				int nIndex = strFileName.Find("-", 0);
				nCurUserID = atoi(strFileName.Mid(0, nIndex));
				fclose(fp);
			}
		}while (FindNextFile(hFindFile, &wfd));
	}

	UCBioAPI_RETURN err = UCBioAPI_TemplateToFIREx(m_hUCBioAPI, Template, idx*TemplateType*2, TemplateType, TemplateType, UCBioAPI_FIR_PURPOSE_IDENTIFY, &hNewFIR);

	UCBioAPI_INPUT_FIR inputFIR;
	inputFIR.Form = UCBioAPI_FIR_FORM_HANDLE;
	inputFIR.InputFIR.FIRinBSP = &hNewFIR;

	err = UCBioAPI_AddFIRToFastSearchDB(m_hUCBioAPI, &inputFIR, nCurUserID, NULL);	
	UCBioAPI_FreeFIRHandle(hNewFIR);
}

void CUCBioBSP_EnrollDlg::EnumDeviceList()
{
   CString strItem;

   UCBioAPI_RETURN err = UCBioAPI_EnumerateDevice(m_hUCBioAPI, &m_nNumDevice, &m_pDeviceID, &m_pDeviceInfoEx);
   if (err) {
      DisplayError(_T("Failed to enumerate device!"), err);
      return;
   }

   int nIndex;

   if (m_nNumDevice == 0) {
      nIndex = m_comboDeviceList.AddString(_T("--NO DEVICE--"));
      m_comboDeviceList.SetItemData(nIndex, UCBioAPI_DEVICE_ID_NONE);
      return;
   }

   nIndex = m_comboDeviceList.AddString(_T("Auto_Detect"));
   m_comboDeviceList.SetItemData(nIndex, UCBioAPI_DEVICE_ID_AUTO);

   DWORD i;
   CString szDevice;

   for (i = 0 ; i < m_nNumDevice; i++) {
      szDevice.Format(_T("%s - %s"), m_pDeviceInfoEx[i].Name, m_pDeviceInfoEx[i].Description);
      nIndex = m_comboDeviceList.AddString(szDevice);
      m_comboDeviceList.SetItemData(nIndex, m_pDeviceInfoEx[i].NameID);
   }   
   m_comboDeviceList.SetCurSel(0);

   UpdateData(FALSE);
   //UpdateButtonStatus();
}


void CUCBioBSP_EnrollDlg::OnSelchangeCbDeviceList() 
{
	// TODO: Add your control notification handler code here
	UpdateData();

   INT nIndex = m_comboDeviceList.GetCurSel();
   UCBioAPI_DEVICE_ID nDeviceID = (UCBioAPI_DEVICE_ID)m_comboDeviceList.GetItemData(nIndex);

   if (nDeviceID != UCBioAPI_DEVICE_ID_NONE) {
      UCBioAPI_CloseDevice(m_hUCBioAPI, m_nLastOpenedDeviceID);

      UCBioAPI_RETURN err = UCBioAPI_OpenDevice(m_hUCBioAPI, nDeviceID);
      if (err == UCBioAPIERROR_NONE) {
         m_nLastOpenedDeviceID = nDeviceID;

         UCBioAPI_DEVICE_INFO_0 deviceInfo0;
         memset(&deviceInfo0, 0, sizeof(UCBioAPI_DEVICE_INFO_0));
         err = UCBioAPI_GetDeviceInfo(m_hUCBioAPI, nDeviceID, 0, &deviceInfo0);
         if (err == UCBioAPIERROR_NONE) {
            //m_nDeviceWidth = deviceInfo0.ImageWidth;
            //m_nDeviceHeight = deviceInfo0.ImageHeight;
            UpdateData(FALSE);
         }
      } else {
         DisplayError(_T("Failed to open device!"), err);
      }
   }
	
}

void SaveBMP(BYTE* biRawData, long nImgWidth, long nImgHeight, int Length)
{
	 BYTE* imgBuf;
	 DWORD imgBufSize = 0;

	 // Convert to BMP from RAW data.
	 BITMAPFILEHEADER bmpHeader;
	 memset(&bmpHeader, 0, sizeof(bmpHeader));

	 UINT bmpInfoSize = sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD);
	 UINT headerSize = sizeof(bmpHeader) + bmpInfoSize;

	 bmpHeader.bfType = ((WORD)('M'<<8) | 'B');
	 bmpHeader.bfSize = nImgWidth * nImgHeight + headerSize;
	 bmpHeader.bfOffBits = headerSize;

	 LPBITMAPINFO     bmpInfo = (LPBITMAPINFO)malloc(bmpInfoSize);
	 if (bmpInfo) 
	 {
		memset(bmpInfo, 0, sizeof(bmpInfo));

		bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bmpInfo->bmiHeader.biWidth = nImgWidth;
		bmpInfo->bmiHeader.biHeight = nImgHeight;
		bmpInfo->bmiHeader.biPlanes = 1;
		bmpInfo->bmiHeader.biBitCount = 8;
		bmpInfo->bmiHeader.biCompression = BI_RGB;
     	bmpInfo->bmiHeader.biSizeImage = nImgWidth * nImgHeight;
		bmpInfo->bmiHeader.biXPelsPerMeter = 2834;
		bmpInfo->bmiHeader.biYPelsPerMeter = 2834;
		bmpInfo->bmiHeader.biClrUsed = 256;
		bmpInfo->bmiHeader.biClrImportant = 256;

		int i, j = 0;
		for(i = 0; i < 256; i++)
		 {
			 bmpInfo->bmiColors[i].rgbRed = i;
			 bmpInfo->bmiColors[i].rgbGreen = i;
			 bmpInfo->bmiColors[i].rgbBlue = i;
			 bmpInfo->bmiColors[i].rgbReserved = 0;
		 }

		imgBufSize = sizeof(bmpHeader) + bmpInfoSize + (nImgWidth * nImgHeight);
		imgBuf = new BYTE[imgBufSize];

		memcpy(imgBuf, &bmpHeader, sizeof(bmpHeader));
		memcpy(imgBuf + sizeof(bmpHeader), bmpInfo, bmpInfoSize);

		for (i = nImgHeight-1; i >= 0; i--) 
		{
		   memcpy(imgBuf + sizeof(bmpHeader) + bmpInfoSize + (j * nImgWidth), &(biRawData[i*nImgWidth]), nImgWidth);
		   j++;
		}

		free(bmpInfo);
	 }

	 // Save BMP if filetype is 1
	 FILE* fp = NULL;
	 fp = fopen((LPCTSTR)"c:\\TempImage.bmp", "wb");
	 if ( fp )
	 {
		fwrite(imgBuf, imgBufSize, 1, fp);
	 }

	 fclose(fp);
	 delete [] imgBuf;
}

void CUCBioBSP_EnrollDlg::Unlock_WSQ_Libary() 
{
	int result;
	int generated_unlock_code_int;
	CString generated_unlock_code, temp_string;
	char* generated_serial_number_char;
	char* generated_unlock_code_char = NULL;

	generated_serial_number_char = (pGenerateSerialNumber)();

	generated_unlock_code_int = 5031 & ((int)generated_serial_number_char[0] + 1645);
	generated_unlock_code_int += 6541 | ((int)generated_serial_number_char[1] -  756);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code = temp_string;
	generated_unlock_code_int = 953 & ((int)generated_serial_number_char[2] +  853);
	generated_unlock_code_int += 786 & ((int)generated_serial_number_char[3] * 563);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 3327 | ((int)generated_serial_number_char[4] +  8713);
	generated_unlock_code_int += 7542 | ((int)generated_serial_number_char[5] - 5433);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 8751 & ((int)generated_serial_number_char[6] * 5956);
	generated_unlock_code_int += 9875 & ((int)generated_serial_number_char[7] + 4822);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 4301 & ((int)generated_serial_number_char[8] - 654);
	generated_unlock_code_int += 6452 & ((int)generated_serial_number_char[9] + 730);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 8736 | ((int)generated_serial_number_char[10] * 546);
	generated_unlock_code_int += 3057 | ((int)generated_serial_number_char[11] - 9572);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 102 & ((int)generated_serial_number_char[12] * 481);
	generated_unlock_code_int += 684 & ((int)generated_serial_number_char[13] * 683);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 302 & ((int)generated_serial_number_char[14] + 3145);
	generated_unlock_code_int += 860 | ((int)generated_serial_number_char[15] - 276);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 7564| ((int)generated_serial_number_char[16] * 67);
	generated_unlock_code_int += 6241 | ((int)generated_serial_number_char[17] + 759);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 7523 | ((int)generated_serial_number_char[18] - 893);
	generated_unlock_code_int += 1131 & ((int)generated_serial_number_char[19] * 91);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 8765 & ((int)generated_serial_number_char[20] - 147);
	generated_unlock_code_int += 8765 & ((int)generated_serial_number_char[21] + 9756);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 3027 | ((int)generated_serial_number_char[22] * 51);
	generated_unlock_code_int += 875 & ((int)generated_serial_number_char[23] * 31);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 194 | ((int)generated_serial_number_char[24] - 633);
	generated_unlock_code_int += 9187 | ((int)generated_serial_number_char[25] - 187);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 6731 | ((int)generated_serial_number_char[26] * 11);
	generated_unlock_code_int += 31 & ((int)generated_serial_number_char[27] + 631);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 213 | ((int)generated_serial_number_char[28] - 756);
	generated_unlock_code_int += 9876 | ((int)generated_serial_number_char[29] - 3671);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;
	generated_unlock_code_int = 7561 & ((int)generated_serial_number_char[30] - 8406);
	generated_unlock_code_int += 8767 & ((int)generated_serial_number_char[31] * 67);
	temp_string.Format("%d", generated_unlock_code_int);
	generated_unlock_code += temp_string;

	if(generated_unlock_code_char!=NULL)
	{delete generated_unlock_code_char; generated_unlock_code_char = NULL;}

	generated_unlock_code_char = new char[generated_unlock_code.GetLength()+1];
	strcpy(generated_unlock_code_char, generated_unlock_code);

	result = (pUnlockWSQLibrary)(generated_unlock_code_char);

	delete generated_unlock_code_char;
//	if (result == 1)
//	{MessageBox(NULL, "Registration succeeded", NULL, MB_OK);}
}

void CUCBioBSP_EnrollDlg::OnBtEnroll() 
{
	// TODO: Add your control notification handler code here
	UpdateData();

	//UCBioAPI_TEMPLATE_FORMAT TemplateFormat;
	//TemplateFormat = m_cbFormat.GetCurSel();
	//UCBioAPI_SetTemplateFormat(m_hUCBioAPI, TemplateFormat);
	
	UCBioAPI_FIR_HANDLE hNewFIR;
	UCBioAPI_INPUT_FIR inputFIR;
	inputFIR.Form = UCBioAPI_FIR_FORM_HANDLE;
	inputFIR.InputFIR.FIRinBSP = &m_hEnrolledFIR;

	UCBioAPI_FIR_PAYLOAD payload;
	payload.Length = (lstrlen(m_szPayload) + 1) * sizeof(TCHAR);
	payload.Data = new UCBioAPI_UINT8 [payload.Length];
	memset(payload.Data, 0, payload.Length);
	lstrcpy((LPTSTR)payload.Data, m_szPayload);

	//UCBioAPI_RETURN err = UCBioAPI_Enroll(m_hUCBioAPI, &inputFIR, &hNewFIR, &payload, UCBioAPI_USE_DEFAULT_TIMEOUT, &m_hAuditData, NULL);
	UCBioAPI_RETURN err = UCBioAPI_Enroll(m_hUCBioAPI, &inputFIR, &hNewFIR, &payload, UCBioAPI_NO_TIMEOUT, &m_hAuditData, NULL);

	if (err == UCBioAPIERROR_NONE) {
	  UCBioAPI_FreeFIRHandle(m_hEnrolledFIR);
	  m_hEnrolledFIR = hNewFIR;
	}

	if(payload.Data)
	{
		delete[] payload.Data;
		payload.Data = NULL;
	}

	// Remove
	if (m_hEnrolledFIR != UCBioAPI_INVALID_HANDLE && m_chkUCT) 
	{
		char szMsg[100];
		sprintf(szMsg, "%d:%d", TemplateFormat, TemplateType);
		// DB에추가
		err = UCBioAPI_AddFIRToFastSearchDB(m_hUCBioAPI, &inputFIR, atoi(m_szPayload), NULL);
		// 특징점 저장

		UCBioAPI_EXPORT_DATA exportData;
		err = UCBioAPI_FIRToTemplate(m_hUCBioAPI, &inputFIR, &exportData, TemplateType);
		
		if(err == UCBioAPIERROR_NONE)
		{
			for(int i = 0; i < exportData.FingerNum; i ++)
			{
				char szPath[MAX_PATH+1]={0,};
				sprintf(szPath, "%s\\%s-%02d.uct", m_strSaveDir, m_szPayload, exportData.FingerInfo[i].FingerID);
				FILE* fp;
				fp = _tfopen(szPath, _T("r"));
				if(fp && m_ckOverwrite == FALSE)
				{
					AfxMessageBox("Duplicate ID !!!");
					fclose(fp);
					break;
				}
				fp = _tfopen(szPath, _T("wb"));
				
				if(fp)
				{
					BYTE * pTemplate=NULL;
					pTemplate = (BYTE*)malloc(exportData.SamplesPerFinger*TemplateType);
					memset(pTemplate, 0, exportData.SamplesPerFinger*TemplateType);
					for(int j = 0; j < exportData.SamplesPerFinger; j ++)
					{
						memcpy((char*)&pTemplate[j*TemplateType], exportData.FingerInfo[i].TemplateInfo[j].Data, exportData.FingerInfo[i].TemplateInfo[j].Length);
					}
					fwrite(pTemplate, 1, exportData.SamplesPerFinger*TemplateType, fp);
					fclose(fp);
					if(pTemplate) free(pTemplate);
				}
			}
			
			UCBioAPI_FreeExportData(&exportData);
			if ( m_hEnrolledFIR )
			{
				UCBioAPI_FreeFIRHandle(m_hEnrolledFIR);
				m_hEnrolledFIR = UCBioAPI_INVALID_HANDLE;
			}

		}

		inputFIR.Form = UCBioAPI_FIR_FORM_HANDLE;
		inputFIR.InputFIR.FIRinBSP = &m_hAuditData;

		UCBioAPI_EXPORT_AUDIT_DATA exportAuditData;
		err = UCBioAPI_AuditFIRToImage(m_hUCBioAPI, &inputFIR, &exportAuditData);

		if(err == UCBioAPIERROR_NONE)
		{
			for(int i = 0; i < exportAuditData.FingerNum; i ++)
			{
				for(int j = 0; j < exportAuditData.SamplesPerFinger; j ++)
				{
					char szPath[MAX_PATH+1]={0,};
					sprintf(szPath, "%s\\%s-%02d-%02d.wsq", m_strSaveDir, m_szPayload, exportAuditData.AuditData[i].FingerID, j);
					SaveBMP(exportAuditData.AuditData[i].Image[j].Data, exportAuditData.ImageWidth, exportAuditData.ImageHeight, exportAuditData.ImageWidth*exportAuditData.ImageHeight);
					HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,"c:\\TempImage.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); 
					if(hBitmap)
					{
					
						if(m_chkWSQ)
						{
							(pSetShowFilePropertiesDialog)(0);
							(pSaveBMPToFile)(hBitmap, szPath, 1);
						}
						if(m_chkRAW)
						{
							sprintf(szPath, "%s\\%s-%02d-%02d.raw", m_strSaveDir, m_szPayload, exportAuditData.AuditData[i].FingerID, j);
							FILE* fp = fopen(szPath, "wb");
							if(fp)
							{
								fwrite(exportAuditData.AuditData[i].Image[j].Data, 1, exportAuditData.ImageWidth*exportAuditData.ImageHeight, fp);
								fclose(fp);
							}
						}
					}
				}
			}

			UCBioAPI_FreeExportAuditData(&exportAuditData);
			if ( m_hAuditData )
			{
			  UCBioAPI_FreeFIRHandle(m_hAuditData);
			  m_hAuditData = UCBioAPI_INVALID_HANDLE;
			}		
		}
	}
}

void CUCBioBSP_EnrollDlg::OnBtIdentify() 
{
	// TODO: Add your control notification handler code here
	UCBioAPI_FIR_HANDLE hCaptureFIR;
	UCBioAPI_RETURN err = UCBioAPI_Capture(m_hUCBioAPI, UCBioAPI_FIR_PURPOSE_VERIFY, &hCaptureFIR, UCBioAPI_USE_DEFAULT_TIMEOUT, NULL, NULL);
	if (err == UCBioAPIERROR_NONE)
	{
		UCBioAPI_INPUT_FIR inputFIR;
		inputFIR.Form = UCBioAPI_FIR_FORM_HANDLE;
		inputFIR.InputFIR.FIRinBSP = &hCaptureFIR;
		UCBioAPI_FASTSEARCH_FP_INFO	fpInfo;
		err = UCBioAPI_IdentifyFIRFromFastSearchDB(m_hUCBioAPI, &inputFIR, atoi(m_striLevel), &fpInfo, NULL);
		if (err == UCBioAPIERROR_NONE)
		{
			CString strResult;
			strResult.Format("Matched ID : %d", fpInfo.ID);
			AfxMessageBox(strResult);
		}
		else
		{
			CString strResult;
			strResult.Format("Matching failed");
			AfxMessageBox(strResult);
		}
	}
}

void CUCBioBSP_EnrollDlg::OnBtApply() 
{
	// TODO: Add your control notification handler code here
	UpdateData();
	if(m_strBitrate.GetLength() > 0)
		pWriteWSQ_bitrate(atof(m_strBitrate)); 
	else
		AfxMessageBox("Invalid bitrate value !!");
}

void CUCBioBSP_EnrollDlg::OnSelchangeCbTermplateformat() 
{
	// TODO: Add your control notification handler code here
	UpdateData();

	switch(m_cbFormat.GetCurSel()) {
	case 0:
		TemplateFormat = UCBioAPI_TEMPLATE_FORMAT_UNION400;
		OnSelchangeCbTermplatetype();
		m_cbType.EnableWindow(TRUE);
		break;
	case 1:
		TemplateFormat = UCBioAPI_TEMPLATE_FORMAT_ISO500;
		TemplateType = UCBioAPI_TEMPLATE_TYPE_SIZE500;
		m_cbType.EnableWindow(FALSE);
		break;
	case 2:
		TemplateFormat = UCBioAPI_TEMPLATE_FORMAT_ISO600;
		TemplateType = UCBioAPI_TEMPLATE_TYPE_SIZE600;
		m_cbType.EnableWindow(FALSE);
		break;
	default:
		TemplateFormat = UCBioAPI_TEMPLATE_FORMAT_UNION400;
	}
	
	UCBioAPI_INIT_INFO_0 initInfo0;
	memset(&initInfo0, 0, sizeof(UCBioAPI_INIT_INFO_0));

	UCBioAPI_RETURN err = UCBioAPI_GetInitInfo(m_hUCBioAPI, 0, &initInfo0);
	if (err == UCBioAPIERROR_NONE) 
	{
		initInfo0.TemplateFormat = TemplateFormat;
		err = UCBioAPI_SetInitInfo(m_hUCBioAPI, 0, &initInfo0);

		if (err != UCBioAPIERROR_NONE) 
			DisplayError(_T("Failed to set init information!"), err);
	} 
	else 
	{
		DisplayError(_T("Failed to get init information!"), err);
	}
}

void CUCBioBSP_EnrollDlg::OnSelchangeCbTermplatetype() 
{
	// TODO: Add your control notification handler code here

	switch(m_cbType.GetCurSel()) {
	case 0:
		TemplateType = UCBioAPI_TEMPLATE_TYPE_SIZE256;
		break;
	case 1:
		TemplateType = UCBioAPI_TEMPLATE_TYPE_SIZE320;
		break;
	case 2:
		TemplateType = UCBioAPI_TEMPLATE_TYPE_SIZE400;
		break;
	case 3:
		TemplateType = UCBioAPI_TEMPLATE_TYPE_SIZE800;
		break;
	case 4:
		TemplateType = UCBioAPI_TEMPLATE_TYPE_FMR;
		break;
	case 5:
		TemplateType = UCBioAPI_TEMPLATE_TYPE_ANSI;
		break;
	default:
		TemplateType = UCBioAPI_TEMPLATE_TYPE_SIZE400;
	}
}

void CUCBioBSP_EnrollDlg::OnSelchangeCbIlevel() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	UCBioAPI_INIT_INFO_0 initInfo0;
	memset(&initInfo0, 0, sizeof(UCBioAPI_INIT_INFO_0));

	UCBioAPI_RETURN err = UCBioAPI_GetInitInfo(m_hUCBioAPI, 0, &initInfo0);
	if (err == UCBioAPIERROR_NONE) 
	{
		initInfo0.SecurityLevelForIdentify = atoi(m_striLevel);
		err = UCBioAPI_SetInitInfo(m_hUCBioAPI, 0, &initInfo0);

		if (err != UCBioAPIERROR_NONE) 
			DisplayError(_T("Failed to set init information!"), err);
	} 
	else 
	{
		DisplayError(_T("Failed to get init information!"), err);
	}	
}

void CUCBioBSP_EnrollDlg::OnSelchangeCbRlevel() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	UCBioAPI_INIT_INFO_0 initInfo0;
	memset(&initInfo0, 0, sizeof(UCBioAPI_INIT_INFO_0));

	UCBioAPI_RETURN err = UCBioAPI_GetInitInfo(m_hUCBioAPI, 0, &initInfo0);
	if (err == UCBioAPIERROR_NONE) 
	{
		initInfo0.SecurityLevelForEnroll = atoi(m_strrLevel);
		err = UCBioAPI_SetInitInfo(m_hUCBioAPI, 0, &initInfo0);

		if (err != UCBioAPIERROR_NONE) 
			DisplayError(_T("Failed to set init information!"), err);
	} 
	else 
	{
		DisplayError(_T("Failed to get init information!"), err);
	}		
}

void CUCBioBSP_EnrollDlg::OnSelchangeCbLivedetectlevel() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);

	UCBioAPI_LIVE_DETECT_LEVEL LiveDetectLevel;

	switch(m_cbLiveDetectLevel.GetCurSel()) {
	case 0:
		LiveDetectLevel = UCBioAPI_LIVE_DETECT_LEVEL_NONE;
		break;
	case 1:
		LiveDetectLevel = UCBioAPI_LIVE_DETECT_LEVEL_TOUCH_ONLY;
		break;
	case 2:
		LiveDetectLevel = UCBioAPI_LIVE_DETECT_LEVEL_LOW;
		break;
	case 3:
		LiveDetectLevel = UCBioAPI_LIVE_DETECT_LEVEL_HIGH;
		break;
	case 4:
		LiveDetectLevel = UCBioAPI_LIVE_DETECT_LEVEL_HIGHEST;
		break;
	default:
		LiveDetectLevel = UCBioAPI_LIVE_DETECT_LEVEL_NONE;
	}	

	UCBioAPI_SetLiveDetectLevel(m_hUCBioAPI, LiveDetectLevel);
}
