using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Media;
using Aratek.TrustFinger;

namespace Demo
{
    public partial class MainForm : Form
    {
        private bool isOpen = false;
        private bool LFDFlag = false;
        private Profile _profile;
        private TrustFingerDevice dev = null;
        private bool isCapture = false;
        //private bool istask = false;
        private int devCount = 0;
        private string pGuid;
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                TrustFingerManager.GlobalInitialize();
            }
            catch
            {
                ShowMessage("Init SDK fail");
                BindProfile();
                return;
            }
            
            comboBoxDevType.SelectedIndex = 0;
            comboBoxUsbDev.SelectedIndex = 0;
            //buttonRefresh.Text = Char.ConvertFromUtf32(81);
            BindProfile();
            BindDevice();
            
            //BindUser();
        }
        private void ShowMessage(string message)
        {
            this.BeginInvoke(new Action(() => {
                toolStripStatusMsg.Text = message;
                toolStripStatusMsg.ForeColor = Color.Red;
            }));
        }

        private void ShowErrorMessage(string errMsg)
        {
            this.BeginInvoke(new Action(() => {
                toolStripStatusMsg.Text = errMsg;
                toolStripStatusMsg.ForeColor = Color.Red;
            }));
            
        }

        private void ResizePictureBox(DeviceDescription desc)
        {
            double zoomFactor = desc.ImagePixelWidth / desc.ImagePixelHeight;
            //Set Preview Image size
            int maxH = 265;
            if(desc.ImagePixelHeight>maxH)
            {
                pictureBoxCapturePre.Height = maxH;
                pictureBoxCapturePre.Width = (maxH * desc.ImagePixelWidth) / desc.ImagePixelHeight;
            }
            else
            {
                pictureBoxCapturePre.Width = desc.ImagePixelWidth;
                pictureBoxCapturePre.Height = desc.ImagePixelHeight;
            }

            maxH = 120;
            if (desc.ImagePixelHeight > maxH)
            {
                pictureBoxEnroll1.Height = maxH;
                pictureBoxEnroll1.Width = (maxH * desc.ImagePixelWidth) / desc.ImagePixelHeight;

                pictureBoxEnroll2.Height = maxH;
                pictureBoxEnroll2.Width = (maxH * desc.ImagePixelWidth) / desc.ImagePixelHeight;

                pictureBoxEnroll3.Height = maxH;
                pictureBoxEnroll3.Width = (maxH * desc.ImagePixelWidth) / desc.ImagePixelHeight;
            }
            else
            {
                pictureBoxEnroll1.Height = desc.ImagePixelWidth;
                pictureBoxEnroll1.Width = desc.ImagePixelHeight;

                pictureBoxEnroll2.Height = desc.ImagePixelWidth;
                pictureBoxEnroll2.Width = desc.ImagePixelHeight;

                pictureBoxEnroll3.Height = desc.ImagePixelWidth;
                pictureBoxEnroll3.Width = desc.ImagePixelHeight;
            }

            maxH = 134;
            if (desc.ImagePixelHeight > maxH)
            {
                pictureBoxEnrolledPre.Height = maxH;
                pictureBoxEnrolledPre.Width = (maxH * desc.ImagePixelWidth) / desc.ImagePixelHeight;
            }
            else
            {
                pictureBoxEnrolledPre.Width = desc.ImagePixelWidth;
                pictureBoxEnrolledPre.Height = desc.ImagePixelHeight;
            }

            maxH = 241;
            if (desc.ImagePixelHeight > maxH)
            {
                pictureBoxVerifyPreview.Height = maxH;
                pictureBoxVerifyPreview.Width = (maxH * desc.ImagePixelWidth) / desc.ImagePixelHeight;
            }
            else
            {
                pictureBoxVerifyPreview.Width = desc.ImagePixelWidth;
                pictureBoxVerifyPreview.Height = desc.ImagePixelHeight;
            }

            maxH = 260;
            if (desc.ImagePixelHeight > maxH)
            {
                pictureBoxIndentify.Height = maxH;
                pictureBoxIndentify.Width = (maxH * desc.ImagePixelWidth) / desc.ImagePixelHeight;
            }
            else
            {
                pictureBoxIndentify.Width = desc.ImagePixelWidth;
                pictureBoxIndentify.Height = desc.ImagePixelHeight;
            }
            



        }
        private void BindDevice()
        {
            try
            {
               devCount= TrustFingerManager.GetDeviceCount();
                comboBoxUsbDev.Items.Clear();
                comboBoxUsbDev.Items.Add(new DeviceItem() { Name = "AUTO", DeviceIndex = 0 });
                string filter = string.Empty;

                switch (comboBoxDevType.SelectedIndex)
                {
                    case 0:
                        filter = string.Empty;
                        break;
                    case 1:
                        filter = "A400";
                        break;
                    case 2:
                        filter = "A600";
                        break;
                    case 3:
                        filter = "EM1920";
                        break;
                    case 4:
                        filter = "EM2010";
                        break;
                    case 5:
                        filter = "EM3011";
                        break;
                    case 6:
                        filter = "EM4010";
                        break;
                    case 7:
                        filter = "EM033011";
                        break;
                    case 8:
                        filter = "EM034010";
                        break;
                    case 9:
                        filter = "FRT610";
                        break;
                }

               
                int chooseDevCnt = 0;
                for (int index = 0; index < devCount; index++)
                {
                    var dev = TrustFingerManager.GetDeviceDescription(index);
                    var item = new DeviceItem();
                    if(!string.IsNullOrEmpty(filter)&& !dev.ProductModel.Contains(filter))
                    {
                        continue;
                    }
                    
                    item.Name = $"{index}:{dev.ProductModel}-{dev.SerialNumber}";
                    item.DeviceIndex = index;
                    chooseDevCnt += 1;
                    comboBoxUsbDev.Items.Add(item);
                }
                devCount = chooseDevCnt;
                comboBoxUsbDev.SelectedIndex = 0;
                
                DeviceItem autodev = comboBoxUsbDev.Items[0] as DeviceItem;
                DeviceItem firstdev= comboBoxUsbDev.Items[1] as DeviceItem;
                autodev.DeviceIndex = firstdev.DeviceIndex;
            }
            catch(Exception ex)
            {
                ShowErrorMessage("The fingerprint reader driver not install");
            }
           
        }

        private void BindDeviceDescription(DeviceDescription desc)
        {
            textBoxManufacturer.Text = desc.Manufacturer;
            textBoxModel.Text = desc.ProductModel;
            textBoxDeviceId.Text = desc.DeviceId.ToString();
            textBoxFWVersion.Text = desc.FirmwareVersion;
            textBoxSN.Text = desc.SerialNumber;
            textBoxWidth.Text = desc.ImagePixelWidth.ToString();
            textBoxHeight.Text = desc.ImagePixelHeight.ToString();
            textBoxDPI.Text = desc.Resolution.ToString();

            ResizePictureBox(desc);
            checkBoxLED.Enabled = desc.IsLedSupported;
            

        }

        

        private void UpdateDeviceCombox(TrustFingerDevice device)
        {
            var desc = device.ScannerDescription;
            switch(desc.ProductModel)
            {
                case "A400":
                    comboBoxDevType.SelectedIndex = 1;
                    break;
                case "A600":
                    comboBoxDevType.SelectedIndex = 2;
                    break;
                case "EM1920":
                    comboBoxDevType.SelectedIndex = 3;
                    break;
                case "EM2010":
                    comboBoxDevType.SelectedIndex = 4;
                    break;
                case "EM3011":
                    comboBoxDevType.SelectedIndex = 5;
                    break;
                case "EM4010":
                    comboBoxDevType.SelectedIndex = 6;
                    break;
                case "EM033011":
                    comboBoxDevType.SelectedIndex = 7;
                    break;
                case "EM034010":
                    comboBoxDevType.SelectedIndex = 8;
                    break;
                case "FRT610":
                    comboBoxDevType.SelectedIndex = 9;
                    break;
            }

            int i;

            for(i=1; i< comboBoxUsbDev.Items.Count;i++)
            {
                DeviceItem evedev= comboBoxUsbDev.Items[i] as DeviceItem;
                if(device.DeviceIndex==evedev.DeviceIndex)
                {
                    break;
                }
            }

            comboBoxUsbDev.SelectedIndex = i;
        }
        private void buttonOpenDev_Click(object sender, EventArgs e)
        {
            if (devCount == 0)
            {
                player.SoundLocation = "no_fingerprint_device_detected.wav";
                player.Load();
                player.Play();
                MessageBox.Show("Please connected ARATEK fingerprint reader!");
                return;
            }
                
            DeviceItem selectDev = comboBoxUsbDev.SelectedItem as DeviceItem;

            if (isOpen==true)
            {
                buttonOpenDev.Text = "Open Device";
                comboBoxDevType.Enabled = true;
                comboBoxUsbDev.Enabled = true;
                buttonRefresh.Enabled = true;
                tabControlMain.Enabled = false;
                
                
                buttonOpenDev.ForeColor = System.Drawing.Color.Black;

                var desc = dev.ScannerDescription;

                int FV = 0;
                int.TryParse(desc.FirmwareVersion, out FV);

                if (desc.DeviceId==600&&FV>=5400)
                {                 
                    try
                    {
                        comboBoxLFDLevel.SelectedIndex = 0;
                        comboBoxLFDLevel.Enabled = false;
                        if (dev.IsLFD)
                        {
                            dev.EnableLFD(false, 3);//, false);
                        }                      
                        //checkBoxExportIMG.Enabled = false;
                        label35.Enabled = false;
                        LFDFlag = false;
                    }
                    catch(Exception ex)
                    {
                        ShowErrorMessage(ex.Message);
                    }                   
                }

                capturing = false;
                switch (tabControlMain.SelectedIndex)
                {
                    case 0:
                        ResetCaptureTab(true,true);
                        break;
                    case 1:
                        //capturing = false;
                        ResetEnrollTab();
                        break;
                    case 2:
                        ResetVerify();
                        break;
                    case 3:
                        ResetIdentifyTab();
                        break;
                }               
                dev?.Dispose();
                ShowMessage($"Close {selectDev.Name} succeed.");
                checkBoxLED.Enabled = false;
            }
            else
            {
                dev?.Dispose();
                dev = new TrustFingerDevice();

                try
                {
                    dev.Open(selectDev.DeviceIndex);
                }
                catch(TrustFingerException ex)
                {
                    MessageBox.Show("Open device fail,Error code:"+ex.ErrorCode);
                    return;
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return;
                }
                
                var desc = dev.ScannerDescription;
                BindDeviceDescription(desc);
               
                switch(desc.DeviceId)
                {
                    case 400:
                        if(desc.ProductModel!="A400")
                        {
                            MessageBox.Show("DeviceDescription check fail.");
                            dev.Close();
                            ShowMessage($"Open fail.");
                            return;
                        }
                        break;
                    case 600:
                        if (desc.ProductModel != "A600")
                        {
                            MessageBox.Show("DeviceDescription check fail.");
                            dev.Close();
                            ShowMessage($"Open fail.");
                            return;
                        }
                        else
                        {
                            int FV = 0;
                            int.TryParse(desc.FirmwareVersion, out FV);
                            if(FV>=5400)
                            {
                                comboBoxLFDLevel.Enabled = true;
                                //checkBoxExportIMG.Enabled = true;
                                label35.Enabled = true;
                                comboBoxLFDLevel.SelectedIndex = 0;
                                LFDFlag = true;
                            }                       
                        }
                        break;
                }

                buttonOpenDev.ForeColor=System.Drawing.Color.Red;
                buttonOpenDev.Text = "Close Device";

                comboBoxDevType.Enabled = false;
                comboBoxUsbDev.Enabled = false;
                buttonRefresh.Enabled = false;
                
                ShowMessage($"Open {selectDev.Name} succeed.");

                UpdateDeviceCombox(dev);
                               
                TaskEx.Delay(1)
               .ContinueWith(t => OpenDevice_BindUser());
                tabControlMain.Enabled = true;
            }
            isOpen = !isOpen;
        }

        private void BindProfile()
        {
            _profile = Profile.LoadProfile();
            if(_profile!=null)
            {
                //
                checkBoxLED.Checked = _profile.EnableLED;
                //Capure Tab
                checkBoxAutoSave.Checked = _profile.CaptureTab.AutoSave;
                textBoxDir.Text = _profile.CaptureTab.StorageDirectory;
                numericUpDownQulity.Value = _profile.CaptureTab.ImageQulity;
                comboBoxMinuFmt.SelectedIndex = _profile.CaptureTab.MinuFormat;
                comboBoxFormat.SelectedIndex = _profile.CaptureTab.CaptureImageFormat;

                comboBoxMinuFmt.Enabled = checkBoxAutoSave.Checked;
                comboBoxFormat.Enabled = checkBoxAutoSave.Checked;

                //
                numericUpDownImg.Value = _profile.EnrollTabProfile.ImageQulity;

                //Verify Tab
                numericUpDownVerify.Value = _profile.VerifyTabProfile.ImageQulity;
                comboBoxSecurityLevel.SelectedIndex = _profile.VerifyTabProfile.SecurityLevelCombox;

                //Identify Tab
                numericUpDownIdentifyQu.Value = _profile.IdentifyTabProfile.ImageQulity;
               
                comboBoxIndentifyLevel.SelectedIndex = _profile.IdentifyTabProfile.SecurityLevelCombox;

                comboBoxLFDLevel.SelectedIndex = 0;
            }
        }

        private void SaveProfile()
        {
            _profile.CaptureTab.AutoSave=checkBoxAutoSave.Checked ;
             _profile.CaptureTab.StorageDirectory= textBoxDir.Text;
             _profile.CaptureTab.ImageQulity= (int)numericUpDownQulity.Value;
            _profile.CaptureTab.MinuFormat = comboBoxMinuFmt.SelectedIndex;
            _profile.CaptureTab.CaptureImageFormat=comboBoxFormat.SelectedIndex ;

            _profile.EnrollTabProfile.ImageQulity= (int)numericUpDownImg.Value;

            //
            //Verify Tab
            _profile.VerifyTabProfile.ImageQulity = (int)numericUpDownVerify.Value;
             _profile.VerifyTabProfile.SecurityLevelCombox = comboBoxSecurityLevel.SelectedIndex;

            //Indenify
            _profile.IdentifyTabProfile.ImageQulity = (int)numericUpDownIdentifyQu.Value;
            
            _profile.IdentifyTabProfile.SecurityLevelCombox = comboBoxIndentifyLevel.SelectedIndex;

            _profile.Save();
        }
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            SaveProfile();
            if(dev!=null&&dev.IsLFD)
            {
                try
                {
                    dev.EnableLFD(false, 3);//, false);
                }catch(Exception ex)
                { }
            }
            dev?.Dispose();
            TrustFingerManager.GlobalFree();
        }

        private Bitmap ConvertBytesToImage(byte[] imageData)
        {
            if (imageData == null || imageData.Length == 0) return null;
            Bitmap bmp;
            using (var ms = new MemoryStream(imageData))
            {
                bmp = new Bitmap(ms);
            }
            return bmp;
        }

        private void StopCaptureFingerprint()
        {
            groupBoxCaptureSet.Enabled = true;
            isCapture = false;

            verticalProgressBarCapture.Value = 0;
            textBoxCaptureQulity.Text = "";
            pictureBoxCapturePre.Image?.Dispose();
            pictureBoxCapturePre.Image = null;

            pictureCaptureFail.Visible = false;
            pictureCapturePass.Visible = false;
            labelCaptureSucceed.Visible = false;
            labelCaptureFail.Visible = false;
            labelCFP.Visible = false;
            labelCIQ.Visible = false;
            labelCapfingerpos.Text = "";
            labelCaptureImageQuality.Text = "";
            dev.EndLiveCapture();
            TurnOffA600RedLight();
            TurnOffA600GreenLight();
            
        }

        /// <summary>
        /// Capture Table view
        /// </summary>
        SoundPlayer player = new SoundPlayer();
        private void StartCaptureFingerprint(CheckBox ckb)
        {
            //int r = (int)numericUpDownQulity.Value;
            if (checkBoxAutoSave.Checked&&numericUpDownQulity.Controls[1].Text == "")
            {
                MessageBox.Show("Image Quality Threshold could not be empty!");
                ckb.CheckedChanged -= ChangeCaptureFinger;
                ckb.Checked = false;
                ckb.CheckedChanged += ChangeCaptureFinger;
                return;
            }

            int pos = 0;
            if (checkBoxAutoSave.Checked == true)
            {
                var checkedButton = panelCaptureImg.Controls.OfType<CheckBox>()
                                 .FirstOrDefault(r => r.Checked);
                if (checkedButton == null)
                {
                    MessageBox.Show("Must choose one finger position!");
                    ShowErrorMessage("Must choose one finger position!");
                    //isStart = false;
                    return;
                }
                pos = int.Parse(checkedButton.Tag.ToString());
            }
            verticalProgressBarCapture.Value = 0;
            textBoxCaptureQulity.Text = "";
            pictureBoxCapturePre.Image?.Dispose();
            pictureBoxCapturePre.Image = null;
            groupBoxCaptureSet.Enabled = false;
            //buttonCapture.Text = "Stop Capture Image";

            int fmtIndex = comboBoxFormat.SelectedIndex;
            int mutIndex = comboBoxMinuFmt.SelectedIndex;

            pGuid = Guid.NewGuid().ToString();

            //while (true)
            //{
                //if(istask==false)
                //{
                    TaskEx.Delay(100).ContinueWith(t =>
                    {
                        string token = pGuid;
                        //istask = true;
                        ShowMessage("Capturing...");
                        //player.Load();
                        //player.Play();
                        //player.PlaySync();
                        try
                        {
                            dev.BeginLiveCapture();
                        }
                        catch (TrustFingerException e)
                        {
                            if(token==pGuid)
                            {
                                this.BeginInvoke(new Action(() =>
                                {
                                    ShowErrorMessage("BeginLiveCapture Error code:" + e.ErrorCode);
                                    ResetCaptureTab(true, true);
                                }));
                                
                            }                           
                            //istask = false;
                            return;
                        }

                        //if(fmtIndex == 1)
                        //{
                        //    ShowErrorMessage("WSQ not support.");
                        //    return;
                        //}
                        if (!Directory.Exists(textBoxDir.Text))
                        {
                            Directory.CreateDirectory(textBoxDir.Text);
                        }

                        TurnOnA600RedLight();

                        player.SoundLocation = "please_press_your_finger.wav";
                        player.Load();
                        player.Play();

                        LiveCaptureFingerprintBitmapData bitmap = null;
                        LiveCaptureFingerprintBitmapData bitmap1 = null;
                        LiveCaptureFingerprintBitmapData bitmap2 = null;
                        isCapture = true;
                        int raisefinger = 0;
                        int raisesound = 0;
                        int qulitytemp = 0;
                        int qulity = 0;
                        int qulityThreshold = (int)numericUpDownQulity.Value;
                        FingerPosition fingerprintPosition = (FingerPosition)pos;
                        IFingerprintFeature fearture = null;
                        //ANSIFingerprintFeature ansiFearture;
                        //ISOFingerprintFeature isoFearture;
                        try
                        {
                            while (isCapture&&(token==pGuid))
                            {
                                //ShowMessage("Capturing...");
                                try
                                {
                                    bitmap = null;
                                    bitmap = dev.LiveCaptureBitmapData();
                                }
                                catch (CaptureException e)
                                {
                                    if(token==pGuid)
                                    {
                                        this.BeginInvoke(new Action(() =>
                                        {
                                            ShowErrorMessage("Capture image fail,Error code:"+e.Message);
                                            ResetCaptureTab(false, true);
                                        }));
                                        
                                    }                                    
                                    break;
                                }
                                //catch (TrustFingerException e)
                                //{
                                //    if(token==pGuid)
                                //    {
                                //        this.BeginInvoke(new Action(() =>
                                //        {
                                //            ShowErrorMessage("LiveCaptureBitmapData fail,Error code:" + e.ErrorCode);
                                //            ResetCaptureTab(false, true);
                                //        }));

                                //    }                                   
                                //    //istask = false;
                                //    break;
                                //}
                                //catch (InvalidOperationException e)
                                //{
                                //    if(token==pGuid)
                                //    {
                                //        this.BeginInvoke(new Action(() =>
                                //        {
                                //            ShowErrorMessage(e.Message);
                                //            ResetCaptureTab(false, true);
                                //        }));

                                //    }                                   
                                //    break;
                                //}

                                bitmap2 = bitmap;//for invoke show picture

                                if (bitmap.CaptureStatus == LiveCaptureStatus.Stop)
                                {
                                    isCapture = false;
                                    //istask = false;
                                    //if(bitmap.FakeFingerStatus==IsFakeFinger.TRUE)
                                    //{
                                    //    if (token == pGuid)
                                    //    {
                                    //        this.BeginInvoke(new Action(() =>
                                    //        {

                                    //            ShowErrorMessage("Fake Finger");
                                                

                                    //            textBoxCaptureQulity.Text = "0";
                                    //            verticalProgressBarCapture.Value = 0;

                                    //            //if (checkBoxExportIMG.Checked == true)
                                    //            //{
                                    //            Bitmap previewBitmap1 = ConvertBytesToImage(bitmap2.FingerprintImageData);
                                    //            pictureBoxCapturePre.Image?.Dispose();
                                    //            pictureBoxCapturePre.Image = previewBitmap1;
                                    //            //}
                                    //            //else
                                    //            //{
                                    //            //    pictureBoxCapturePre.Image?.Dispose();
                                    //            //    pictureBoxCapturePre.Image = null;
                                    //            //}
                                    //            if (checkBoxAutoSave.Checked == true)
                                    //            {
                                    //                groupBoxCaptureSet.Enabled = true;
                                    //                pictureCaptureFail.Visible = true;
                                    //                pictureCapturePass.Visible = false;
                                    //                labelCaptureSucceed.Visible = false;
                                    //                labelCaptureFail.Visible = true;
                                    //                labelCFP.Visible = false;
                                    //                labelCIQ.Visible = false;
                                    //                labelCapfingerpos.Text = "";
                                    //                labelCaptureImageQuality.Text = "";

                                    //                //ResetCaptureTab(false, false);
                                    //            }
                                                
                                                
                                    //        }));
                                    //        //if(checkBoxAutoSave.Checked!=true)
                                    //        //{
                                    //        //    isCapture = true;
                                    //        //    continue;
                                    //        //}
                                    //        isCapture = true;
                                    //        continue;
                                    //    }
                                            
                                    //}
                                    
                                    break;
                                }
                                else
                                {
                                    if(bitmap.FakeFingerStatus == IsFakeFinger.UNKNOWN)
                                    {
                                        ShowErrorMessage("Unknown Finger");
                                    }
                                    else if(bitmap.FakeFingerStatus==IsFakeFinger.TRUE)
                                    {
                                        ShowErrorMessage("Fake Finger");
                                    }
                                    else
                                    {
                                        ShowErrorMessage("");
                                    }
                                    
                                    Bitmap previewBitmap = ConvertBytesToImage(bitmap.FingerprintImageData);
                                    try
                                    {
                                        qulity = dev.ImageQuality(previewBitmap);
                                    }
                                    catch (ArgumentNullException e)
                                    {
                                        if(token==pGuid)
                                        {
                                            this.BeginInvoke(new Action(() =>
                                            {
                                                ShowErrorMessage("The image is null.");
                                                ResetCaptureTab(false, true);
                                            }));
                                            
                                        }                                        
                                        //istask = false;
                                        break;
                                    }
                                    catch(TrustFingerException ex)
                                    {
                                        if (token == pGuid)
                                        {
                                            this.BeginInvoke(new Action(() =>
                                            {
                                                ShowErrorMessage("Get image quality fail,Error code:"+ex.ErrorCode);
                                                ResetCaptureTab(false, true);
                                            }));

                                        }
                                        //istask = false;
                                        break;
                                    }

                                    if (checkBoxAutoSave.Checked)//Auto Save
                                    {
                                        if (qulity > qulitytemp && bitmap.FakeFingerStatus == IsFakeFinger.FALSE)
                                        {
                                            bitmap1 = null;
                                            bitmap1 = bitmap;
                                            qulitytemp = qulity;
                                            if (qulity >= qulityThreshold)
                                            {
                                                try
                                                {
                                                    switch (mutIndex)
                                                    {
                                                        case 0:
                                                            fearture = dev.ExtractFeature(fingerprintPosition);
                                                            break;
                                                        case 1:
                                                            fearture = dev.ExtractANSIFeature(fingerprintPosition);
                                                            break;
                                                        case 2:
                                                            fearture = dev.ExtractISOFeature(fingerprintPosition);
                                                            break;
                                                    }
                                                }
                                                catch (InvalidOperationException ex)
                                                {
                                                    if(token==pGuid)
                                                    {
                                                        dev.EndLiveCapture();
                                                        this.BeginInvoke(new Action(() =>
                                                        {

                                                            ShowErrorMessage(ex.Message);
                                                            //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                                            Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                                            groupBoxCaptureSet.Enabled = true;
                                                            pictureBoxCapturePre.Image?.Dispose();
                                                            pictureBoxCapturePre.Image = previewBitmap1;
                                                            textBoxCaptureQulity.Text = qulitytemp.ToString();
                                                            verticalProgressBarCapture.Value = qulitytemp;

                                                            pictureCaptureFail.Visible = true;
                                                            pictureCapturePass.Visible = false;
                                                            labelCaptureSucceed.Visible = false;
                                                            labelCaptureFail.Visible = true;
                                                            labelCFP.Visible = false;
                                                            labelCIQ.Visible = false;
                                                            labelCapfingerpos.Text = "";
                                                            labelCaptureImageQuality.Text = "";

                                                            isCapture = false;
                                                            ResetCaptureTab(false, false);
                                                        }));
                                                    }
                                                    
                                                    break;
                                                }
                                                catch (ExtractFeatureException ex)
                                                {
                                                    if(token==pGuid)
                                                    {
                                                        dev.EndLiveCapture();
                                                        this.BeginInvoke(new Action(() =>
                                                        {

                                                            ShowErrorMessage("Extract feature failure,Please try again.");
                                                            //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                                            Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                                            groupBoxCaptureSet.Enabled = true;
                                                            pictureBoxCapturePre.Image?.Dispose();
                                                            pictureBoxCapturePre.Image = previewBitmap1;
                                                            textBoxCaptureQulity.Text = qulitytemp.ToString();
                                                            verticalProgressBarCapture.Value = qulitytemp;

                                                            pictureCaptureFail.Visible = true;
                                                            pictureCapturePass.Visible = false;
                                                            labelCaptureSucceed.Visible = false;
                                                            labelCaptureFail.Visible = true;
                                                            labelCFP.Visible = false;
                                                            labelCIQ.Visible = false;
                                                            labelCapfingerpos.Text = "";
                                                            labelCaptureImageQuality.Text = "";

                                                            isCapture = false;
                                                            ResetCaptureTab(false, false);
                                                        }));
                                                    }
                                                    
                                                    break;
                                                }
                                                catch (TrustFingerException ex)
                                                {
                                                    if(token==pGuid)
                                                    {
                                                        dev.EndLiveCapture();
                                                        this.BeginInvoke(new Action(() =>
                                                        {
                                                            ShowErrorMessage("Extract feature failure,Error code:"+ex.ErrorCode);
                                                            //ShowErrorMessage("Extract feature failure,Please try again.");
                                                            //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                                            Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                                            groupBoxCaptureSet.Enabled = true;
                                                            pictureBoxCapturePre.Image?.Dispose();
                                                            pictureBoxCapturePre.Image = previewBitmap1;
                                                            textBoxCaptureQulity.Text = qulitytemp.ToString();
                                                            verticalProgressBarCapture.Value = qulitytemp;

                                                            pictureCaptureFail.Visible = true;
                                                            pictureCapturePass.Visible = false;
                                                            labelCaptureSucceed.Visible = false;
                                                            labelCaptureFail.Visible = true;
                                                            labelCFP.Visible = false;
                                                            labelCIQ.Visible = false;
                                                            labelCapfingerpos.Text = "";
                                                            labelCaptureImageQuality.Text = "";

                                                            isCapture = false;
                                                            ResetCaptureTab(false, false);
                                                        }));
                                                    }
                                                    
                                                    break;
                                                }


                                                if (raisesound == 0)
                                                {
                                                    TurnOffA600RedLight();
                                                    TurnOnA600GreenLight();


                                                    player.SoundLocation = "please_raise_your_finger.wav";
                                                    player.Load();
                                                    player.Play();

                                                    raisesound = 1;
                                                }
                                            }

                                        }

                                        if (qulity <= 20 && raisesound == 1)
                                        {
                                            raisefinger = 1;
                                        }

                                        //if (qulity >= qulityThreshold)
                                        //{


                                        //}
                                        if (raisefinger == 1)
                                        {
                                            TurnOffA600GreenLight();


                                            string time = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                                            string fileName = $"AratekTrustFinger_{time}_{fingerprintPosition}_{qulitytemp}";
                                            string filePath = null;

                                            try
                                            {
                                                switch (fmtIndex)
                                                {
                                                    case 0:
                                                        filePath = Path.Combine(textBoxDir.Text, fileName + ".bmp");
                                                        bitmap1.Save(filePath);
                                                        break;
                                                    case 1:
                                                        filePath = Path.Combine(textBoxDir.Text, fileName + ".wsq");//TODO
                                                        byte[] wsqRaw = FingerprintImageHelper.BitmapToRaw(bitmap1.FingerprintImageData, bitmap1.Width, bitmap1.Height);
                                                        byte[] wsq = FingerprintImageHelper.RawToWSQ(wsqRaw, 0.75, bitmap1.Width, bitmap1.Height,  dev.ScannerDescription.Resolution);
                                                        File.WriteAllBytes(filePath, wsq);
                                                        break;
                                                    case 2:
                                                        filePath = Path.Combine(textBoxDir.Text, fileName + ".raw");
                                                        byte[] raw = FingerprintImageHelper.BitmapToRaw(bitmap1.FingerprintImageData, bitmap1.Width, bitmap1.Height);
                                                        File.WriteAllBytes(filePath, raw);
                                                        break;
                                                    case 3:
                                                        filePath = Path.Combine(textBoxDir.Text, fileName + ".iso-fir");
                                                        byte[] isoRaw = FingerprintImageHelper.BitmapToRaw(bitmap1.FingerprintImageData, bitmap1.Width, bitmap1.Height);
                                                        byte[] iso = FingerprintImageHelper.RawToISO(isoRaw, bitmap1.Width, bitmap1.Height,
                                                            fingerprintPosition, 0, dev.ScannerDescription.DeviceId);
                                                        File.WriteAllBytes(filePath, iso);
                                                        break;
                                                    case 4:
                                                        filePath = Path.Combine(textBoxDir.Text, fileName + ".ansi-fir");
                                                        byte[] ansiRaw = FingerprintImageHelper.BitmapToRaw(bitmap1.FingerprintImageData, bitmap1.Width, bitmap1.Height);
                                                        byte[] ansi = FingerprintImageHelper.RawToANSI(ansiRaw, bitmap1.Width, bitmap1.Height,
                                                            fingerprintPosition, 0, dev.ScannerDescription.DeviceId);
                                                        File.WriteAllBytes(filePath, ansi);
                                                        break;
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                if(token==pGuid)
                                                {
                                                    ShowErrorMessage("Image data conversion fail. Error code:" + ex.Message);
                                                    dev.EndLiveCapture();
                                                    this.BeginInvoke(new Action(() =>
                                                    {
                                                        Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                                        groupBoxCaptureSet.Enabled = true;
                                                        pictureBoxCapturePre.Image?.Dispose();
                                                        pictureBoxCapturePre.Image = previewBitmap1;
                                                        textBoxCaptureQulity.Text = qulitytemp.ToString();
                                                        verticalProgressBarCapture.Value = qulitytemp;

                                                        pictureCaptureFail.Visible = false;
                                                        pictureCapturePass.Visible = true;
                                                        labelCaptureSucceed.Visible = true;
                                                        labelCaptureFail.Visible = false;
                                                        labelCFP.Visible = true;
                                                        labelCIQ.Visible = true;
                                                        labelCapfingerpos.Text = $"{FormatHelper.FormatFingerprintPosition((FingerPosition)pos)}";
                                                        labelCaptureImageQuality.Text = $"{qulitytemp}";

                                                        isCapture = false;
                                                        //buttonCapture.Text = "Start Capture Image";
                                                        ResetCaptureTab(false, false);

                                                        //ShowMessage($"Capture succeed!");
                                                    }));
                                                }
                                                
                                                break;
                                                //return;
                                                //ignore
                                            }



                                            fileName = $"AratekTrustFinger_{time}_{fingerprintPosition}_{qulitytemp}";


                                            switch (mutIndex)
                                            {
                                                case 0:
                                                    filePath = Path.Combine(textBoxDir.Text, fileName + ".bione");
                                                    //var fearture = dev.ExtractFeature(fingerprintPosition);
                                                    File.WriteAllBytes(filePath, fearture.FeatureData);
                                                    break;
                                                case 1:
                                                    filePath = Path.Combine(textBoxDir.Text, fileName + ".ansi-fmr");
                                                    //var ansiFearture = dev.ExtractANSIFeature(fingerprintPosition);
                                                    File.WriteAllBytes(filePath, fearture.FeatureData);
                                                    break;
                                                case 2:
                                                    filePath = Path.Combine(textBoxDir.Text, fileName + ".iso-fmr");
                                                    //var isoFearture = dev.ExtractISOFeature(fingerprintPosition);
                                                    File.WriteAllBytes(filePath, fearture.FeatureData);
                                                    break;
                                            }


                                            dev.EndLiveCapture();
                                            this.BeginInvoke(new Action(() =>
                                            {
                                                Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                                groupBoxCaptureSet.Enabled = true;
                                                pictureBoxCapturePre.Image?.Dispose();
                                                pictureBoxCapturePre.Image = previewBitmap1;
                                                textBoxCaptureQulity.Text = qulitytemp.ToString();
                                                verticalProgressBarCapture.Value = qulitytemp;

                                                pictureCaptureFail.Visible = false;
                                                pictureCapturePass.Visible = true;
                                                labelCaptureSucceed.Visible = true;
                                                labelCaptureFail.Visible = false;
                                                labelCFP.Visible = true;
                                                labelCIQ.Visible = true;
                                                labelCapfingerpos.Text = $"{FormatHelper.FormatFingerprintPosition((FingerPosition)pos)}";
                                                labelCaptureImageQuality.Text = $"{qulitytemp}";

                                                isCapture = false;
                                                //buttonCapture.Text = "Start Capture Image";
                                                ResetCaptureTab(false, false);

                                                ShowMessage($"Capture succeed!");
                                            }));
                                            break;
                                        }

                                    }
                                    this.BeginInvoke(new Action(() =>
                                    {
                                        if (isCapture)
                                        {
                                            pictureBoxCapturePre.Image?.Dispose();
                                            pictureBoxCapturePre.Image = previewBitmap;
                                            textBoxCaptureQulity.Text = qulity.ToString();
                                            verticalProgressBarCapture.Value = qulity;
                                        }

                                    }));
                                }

                            }
                        }
                        catch (Exception ex)
                        {
                            //Ignore
                            this.BeginInvoke(new Action(() =>
                            {
                                if (isCapture)
                                {
                                    pictureBoxCapturePre.Image?.Dispose();
                                    pictureBoxCapturePre.Image = null;
                                    textBoxCaptureQulity.Text = qulity.ToString();
                                    verticalProgressBarCapture.Value = qulity;
                                }
                            }));
                            //istask = false;
                        }
                        ///istask = false;
                    });
                    //break;
               // }               
            //}            
        }


        /// <summary>
        /// Enroll Table view
        /// </summary>
        #region Enroll Tab
        private bool enrollCapture = false;
        private bool capturing = false;
        private bool CaptureLiveFingerprint(string userId,string firstName, string lastName, FingerPosition pos)
        {
            string token = pGuid;
            //istask = true;
            ShowMessage("Enrolling...");
            enrolltime++;
            capturing = true;
            //isstop = false;
            int qulityThreshold = (int)numericUpDownImg.Value;
            int qulity = 0;
            

            List<CaptureFingerprintItem> captureItems = new List<CaptureFingerprintItem>();
            PictureBox showImage = pictureBoxEnroll1;
            Label qualitylabel = labelQuality1;
           
            int width = dev.ImageWidth;
            int height = dev.ImageHeight;

            
        Retry:
           
            int score = 0;
            

            for (int i = 0; i < 3; i++)
            {
                if (pGuid!=token)
                {
                    //dev.EndLiveCapture();
                    //TurnOffA600RedLight();
                    return false;
                }
                switch (i)
                {
                    case 0:
                        showImage = pictureBoxEnroll1;
                        qualitylabel = labelQuality1;
                        break;
                    case 1:
                        showImage = pictureBoxEnroll2;
                        qualitylabel = labelQuality2;
                        break;
                    case 2:
                        showImage = pictureBoxEnroll3;
                        qualitylabel = labelQuality3;
                        break;
                }

                int raisefinger = 0;
                int raisesound = 0;
                int qulitytemp = 0;
                LiveCaptureFingerprintBitmapData bitmap1 = null;

                CaptureFingerprintItem item = new CaptureFingerprintItem();

                TurnOffA600GreenLight();
                TurnOffA600RedLight();
                TurnOnA600RedLight();
                
                
                player.SoundLocation = "please_press_your_finger.wav";
                player.Load();
                player.Play();

                LiveCaptureFingerprintBitmapData bitmap;

                try
                {
                    dev.BeginLiveCapture();
                }
                catch (TrustFingerException e)
                {
                    ShowErrorMessage("BeginLiveCapture Error code:" + e.ErrorCode);
                    dev.EndLiveCapture();
                    if (token==pGuid)
                    {
                        
                        RestoreToEnrollAgain();
                    }                   
                    //istask = false;
                    return false;
                }

                while (capturing&&(pGuid==token))//do
                {
                    try
                    {
                        bitmap = dev.LiveCaptureBitmapData();
                    }
                    catch(CaptureException e)
                    {
                        ShowErrorMessage("Capture image fail,Error code:"+e.Message);
                        dev.EndLiveCapture();
                        if (pGuid == token)
                        {
                            
                            RestoreToEnrollAgain();
                        }
                        
                        // = false;
                        return false;
                    }
                    //catch(TrustFingerException e)
                    //{
                    //    ShowErrorMessage("Capture image fail,Error code:" + e.ErrorCode);
                    //    dev.EndLiveCapture();
                    //    if (pGuid == token)
                    //    {
                            
                    //        RestoreToEnrollAgain();
                    //    }
                    //    //istask = false;
                    //    return false;
                    //}
                    //catch(InvalidOperationException e)
                    //{
                    //    ShowErrorMessage(e.Message);
                    //    dev.EndLiveCapture();
                    //    if (pGuid==token)
                    //    {
                            
                    //        RestoreToEnrollAgain();
                    //    }
                    //    return false;
                    //}

                    //ShowErrorMessage("Capture image fail,Error code:");
                    //dev.EndLiveCapture();
                    //if (pGuid == token)
                    //{

                    //    RestoreToEnrollAgain();
                    //}
                    //return false;

                    if (bitmap.CaptureStatus == LiveCaptureStatus.Capturing)
                    {
                        if(bitmap.FakeFingerStatus==IsFakeFinger.UNKNOWN)
                        {
                            ShowMessage("Unknown Finger");
                        }
                        else if(bitmap.FakeFingerStatus == IsFakeFinger.TRUE)
                        {
                            ShowErrorMessage("Fake Finger");
                        }
                        else
                        {
                            ShowMessage("");
                        }
                        Bitmap previewBitmap = ConvertBytesToImage(bitmap.FingerprintImageData);
                        try
                        {                           
                            //byte[] raw = FingerprintImageHelper.BitmapToRaw(bitmap.FingerprintImageData, width, height);
                            //qulity = dev.ImageQuality(raw, width, height);
                            qulity = dev.ImageQuality(previewBitmap);
                        }
                        catch(ArgumentNullException e)
                        {
                            ShowErrorMessage("The image is null.");
                            dev.EndLiveCapture();
                            if (pGuid == token)
                            {
                                RestoreToEnrollAgain();
                            }
                            //istask = false;
                            return false;
                        }
                        catch(TrustFingerException e)
                        {
                            ShowErrorMessage("Get image quality fail.Error code:"+e.ErrorCode);
                            dev.EndLiveCapture();
                            if (pGuid == token)
                            {
                                RestoreToEnrollAgain();
                            }
                            //istask = false;
                            return false;
                        }
                        catch(Exception e)
                        {
                            ShowErrorMessage("Bmp to Raw fail,Error code:"+e.Message);
                            dev.EndLiveCapture();
                            if (pGuid == token)
                            {
                                RestoreToEnrollAgain();
                            }
                            //istask = false;
                            return false;
                        }
                        

                        this.BeginInvoke(new Action(() => {
                            if(capturing)
                            {
                                
                                pictureBoxEnrolledPre.Image?.Dispose();
                                pictureBoxEnrolledPre.Image = previewBitmap;
                                verticalProgressBarEnroll.Value = qulity;
                                textBoxEnroll.Text = qulity.ToString();
                                //txbFinger.Text = $"Qulity:{qulity.ToString()}";
                            }
                            
                        }));

                        if(qulity>qulitytemp && bitmap.FakeFingerStatus == IsFakeFinger.FALSE)
                        {
                            bitmap1 = bitmap;
                            qulitytemp = qulity;
                            if (qulity >= qulityThreshold)
                            {
                                item.Bitmap = bitmap1.FingerprintImageData;
                                try
                                {
                                    item.Fearture = dev.ExtractFeature(pos).FeatureData;
                                }
                                catch (InvalidOperationException ex)
                                {
                                    ShowErrorMessage(ex.Message);
                                    dev.EndLiveCapture();
                                    if (pGuid == token)
                                    {
                                        RestoreToEnrollAgain();
                                    }
                                    //istask = false;
                                    return false;
                                }
                                catch (ExtractFeatureException ex)
                                {
                                    ShowErrorMessage("Extract feature failure,Please enroll again.");
                                    dev.EndLiveCapture();
                                    if (pGuid == token)
                                    {
                                        RestoreToEnrollAgain();
                                    }
                                    //istask = false;
                                    return false;
                                }
                                catch (TrustFingerException ex)
                                {
                                    ShowErrorMessage("Extract feature failure,Error code:"+ex.ErrorCode);
                                    dev.EndLiveCapture();
                                    if (pGuid == token)
                                    {
                                        RestoreToEnrollAgain();
                                    }
                                    //istask = false;
                                    return false;
                                }

                                item.Qulity = qulity;

                                if (raisesound == 0)
                                {
                                    TurnOffA600RedLight();
                                    TurnOnA600GreenLight();
                                   
                                    player.SoundLocation = "please_raise_your_finger.wav";
                                    player.Load();
                                    player.Play();

                                    raisesound = 1;
                                }
                            }
                        }

                        if (qulity <= 20 && raisesound == 1)
                        {
                            raisefinger = 1;
                        }

                        //if (qulity >= qulityThreshold)
                        //{

                            

                            //item.Bitmap = bitmap.FingerprintImageData;
                            //item.Fearture = dev.ExtractFeature(pos)?.FeatureData;
                            //item.Qulity = qulity;

                            //captureItems.Add(item);
                            //TurnOffA600RedLight();
                            //TurnOnA600GreenAuto();
                            //reak;
                        //}
                        if(raisefinger==1)
                        {
                            TurnOffA600GreenLight();                                                      
                            captureItems.Add(item);
                            break;
                        }
                    }
                    else
                    {
                        capturing = false;
                        //if (bitmap.FakeFingerStatus == IsFakeFinger.TRUE)
                        //{
                        //    if(pGuid == token)
                        //    {
                        //        this.BeginInvoke(new Action(() =>
                        //        {
                        //            ShowErrorMessage("Fake Finger");

                        //            verticalProgressBarEnroll.Value = 0;
                        //            textBoxEnroll.Text = "0";

                        //            pictureBoxEnrollPass.Visible = false;
                        //            pictureBoxEnrollFail.Visible = true;
                        //            labelenrollresult.Text = $"Enroll Failed";

                        //            //if (checkBoxExportIMG.Checked == true)
                        //            //{
                        //            Bitmap previewBitmap = ConvertBytesToImage(bitmap.FingerprintImageData);
                        //            pictureBoxEnrolledPre.Image?.Dispose();
                        //            pictureBoxEnrolledPre.Image = previewBitmap;
                        //            //}
                        //            //else
                        //            //{
                        //            //    pictureBoxEnrolledPre.Image?.Dispose();
                        //            //    pictureBoxEnrolledPre.Image = null;
                        //            //}
                        //            RestoreToEnrollAgain(false);
                        //        }));
                        //    }
                            
                        //} 
                        break;
                    }

                } //while (capturing == true);

                if (pGuid != token)
                {
                    //dev.EndLiveCapture();
                    //TurnOffA600RedLight();
                    return false;
                }

                if (capturing == true)//
                {
                    this.BeginInvoke(new Action(() =>
                    {
                        showImage.Image?.Dispose();
                        Bitmap previewBitmap = ConvertBytesToImage(item.Bitmap);
                        showImage.Image = previewBitmap;
                        qualitylabel.Text = $"Quality:{item.Qulity}";
                    }));
                  
                }
                else
                {
                    break;
                }

                ShowMessage($"Finger {i+1} capture succeed.");
                dev.EndLiveCapture();
                Thread.Sleep(500);
            }

            dev.EndLiveCapture();
            TurnOffA600RedLight();
            
            
            if (capturing == true && (pGuid == token))
            {
                int isexist = 0;
                VerifyResult score1, score2, score3;
                try
                {
                    score1 = dev.Verify(3, captureItems[0].Fearture, captureItems[1].Fearture);
                    score2 = dev.Verify(3, captureItems[0].Fearture, captureItems[2].Fearture);
                    score3 = dev.Verify(3, captureItems[1].Fearture, captureItems[2].Fearture);
                }
                catch(ArgumentNullException e)
                {
                    ShowErrorMessage(e.Message);
                    RestoreToEnrollAgain();
                    return false;
                }
                catch(TrustFingerException e)
                {
                    ShowErrorMessage("Verify fail.Error code:" + e.ErrorCode);
                    RestoreToEnrollAgain();
                    //istask = false;
                    return false;
                }
                float throld =100;

                if ((score1.Similarity + score2.Similarity + score3.Similarity) / 3 > throld)
                {
                    try
                    {
                        byte[] template = dev.GeneralizeTemplate(captureItems[0].Fearture, captureItems[1].Fearture, captureItems[2].Fearture);
                        List<EnrollUser> users = new List<EnrollUser>();
                        using (TrustFingerDbContext db = new TrustFingerDbContext())
                        {
                            var usr = db.EnrollUser.Where(u => u.UserId == textBoxUserId.Text.Trim());
                            if (usr.Count() > 0)
                            {
                                this.BeginInvoke(new Action(() =>
                                {
                                    MessageBox.Show($"Duplicate user id:{textBoxUserId.Text.Trim()}");
                                    ShowErrorMessage($"Duplicate user id: {textBoxUserId.Text.Trim()}");
                                    pictureBoxEnrollPass.Visible = false;
                                    pictureBoxEnrollFail.Visible = true;
                                    labelenrollresult.Text = $"Enroll Failed";
                                    RestoreToEnrollAgain();
                                }));
                                //istask = false;
                                return false;
                            }
                            users = db.EnrollUser.ToList();
                        }
                        
                        foreach (var user in users)
                        {
                            try
                            {
                                var result = dev.Verify(4, template, user.FingerData);
                                if (result.IsMatch)
                                {
                                    isexist = 1;
                                    break;
                                }
                            }
                            catch(ArgumentNullException e)
                            {
                                ShowErrorMessage(e.Message);
                                RestoreToEnrollAgain();
                                return false;
                            }
                            catch(TrustFingerException e)
                            {
                                ShowErrorMessage("Verify fail.Error code:" + e.ErrorCode);
                                RestoreToEnrollAgain();                              
                                return false;
                            }
                        }

                        if(isexist==1)
                        {
                            this.BeginInvoke(new Action(() =>
                            {
                                MessageBox.Show("The finger already exists.");
                                ShowErrorMessage("The finger already exists.");
                                pictureBoxEnrollPass.Visible = false;
                                pictureBoxEnrollFail.Visible = true;
                                labelenrollresult.Text = $"Enroll Failed";
                                RestoreToEnrollAgain();
                            }));
                            //istask = false;
                            return false;
                        }

                        SaveEnrollment(pos,userId,firstName,lastName,template);
                        BindUser();
                        ShowMessage("Enroll succeed.");
                        this.BeginInvoke(new Action(() => {
                            pictureBoxEnrollPass.Visible = true;
                            pictureBoxEnrollFail.Visible = false;
                            labelenrollresult.Text = $"Enroll Succeed";
                            RestoreEnroll();
                        }));
                        //istask = false;
                        return true;
                    }
                    catch(TrustFingerException ex)
                    {
                        this.BeginInvoke(new Action(() =>
                        {
                            MessageBox.Show("Generalize template fail.");
                            ShowErrorMessage("Generalize template fail,Error code:"+ex.ErrorCode);
                            pictureBoxEnrollPass.Visible = false;
                            pictureBoxEnrollFail.Visible = true;
                            labelenrollresult.Text = $"Enroll Failed";
                            RestoreToEnrollAgain();
                        }));
                        //istask = false;
                        return false;
                    }
                }
                else
                {
                    this.BeginInvoke(new Action(() =>
                    {
                        MessageBox.Show("The enroll fingerprint are different.");
                        ShowErrorMessage("The enroll fingerprint are different.");
                        pictureBoxEnrollPass.Visible = false;
                        pictureBoxEnrollFail.Visible = true;
                        labelenrollresult.Text = $"Enroll Failed";
                        RestoreToEnrollAgain();
                    }));

                    //istask = false;
                    return false;

                }
            }
            //istask = false;
            return false;
        }

        /// <summary>
        /// Save the result of Enroll
        /// </summary>
        /// <param name="pos">fingerposition</param>
        /// <param name="userId"></param>
        /// <param name="firstName"></param>
        /// <param name="lastName"></param>
        /// <param name="template">templatedatas</param>
        private void SaveEnrollment(FingerPosition pos,string userId,string firstName,string lastName,byte[] template)
        {
            using (TrustFingerDbContext db = new TrustFingerDbContext())
            {
                List<EnrollUser> users = new List<EnrollUser>();
                users = db.EnrollUser.ToList();
                if(users.Count==100)
                {
                    MessageBox.Show("The Database is full.");
                    return;
                }
                EnrollUser user = new EnrollUser();
                user.CreatedTime = DateTime.Now;
                user.UserId = userId;
                user.LastName = lastName;
                user.FirstName = firstName;
                user.FingerPosition = (int)pos;
                user.FingerPositionName = FormatHelper.FormatFingerprintPosition(pos);
                user.FingerData = template;
                db.EnrollUser.Add(user);
                db.SaveChanges();
            }
        }
        #endregion

        private void buttonRefresh_Click(object sender, EventArgs e)
        {
            comboBoxDevType.SelectedIndex = 0;
            BindDevice();
        }

        private void BindUser()
        {
            //dataGridViewEnroll.AutoGenerateColumns = false;
            //dataGridViewVerify.AutoGenerateColumns = false;
            //dataGridViewIndetify.AutoGenerateColumns = false;
            using (TrustFingerDbContext db = new TrustFingerDbContext())
            {
                //var usrs = db.EnrollUser.OrderByDescending(u => u.Id).ToList();
                var usrs = db.EnrollUser.Take(100).OrderByDescending(u => u.Id).ToList();
                Invoke(new Action(() =>
                {
                    this.dataGridViewEnroll.DataSource = usrs;
                    dataGridViewVerify.DataSource = usrs;
                }));
               
            }
        }

        private void OpenDevice_BindUser()
        {
            dataGridViewEnroll.AutoGenerateColumns = false;
            dataGridViewVerify.AutoGenerateColumns = false;
            dataGridViewIndetify.AutoGenerateColumns = false;
            using (TrustFingerDbContext db = new TrustFingerDbContext())
            {
                //var usrs = db.EnrollUser.OrderByDescending(u => u.Id).ToList();
                var usrs = db.EnrollUser.Take(100).OrderByDescending(u => u.Id).ToList();
                Invoke(new Action(() =>
                {
                    this.dataGridViewEnroll.DataSource = usrs;
                    dataGridViewVerify.DataSource = usrs;
                    ShowMessage("The database loaded successfully");
                }));

            }
        }

        private bool verify = false;
        /// <summary>
        /// Veify Table View
        /// </summary>
        /// <param name="sourceTemplate">featuredata</param>
        /// <param name="pos">finger position</param>
        /// <param name="level">verify level</param>
        private void Verify(byte[] sourceTemplate, FingerPosition pos,int level)
        {
            string token = pGuid;
            //istask = true;
            ShowMessage("Capturing...");
            this.BeginInvoke(new Action(() => {
                pictureBoxVeriftPass.Visible = false;
                pictureBoxVerifyFail.Visible = false;
                labelSimilarity.Text = $"";
                labelfingerpos.Text = "";
                textBoxVerify.Text = "";
                verticalProgressBarVerify.Value = 0;
                pictureBoxVerifyPreview.Image?.Dispose();
                pictureBoxVerifyPreview.Image = null;
                tableLayoutPanel14.Enabled = false;
                comboBoxSecurityLevel.Enabled = false;
                dataGridViewVerify.Enabled = false;
                numericUpDownVerify.Enabled = false;

                buttonVerify.Text = "Stop Verify";
                verify = true;               
            }));

            TurnOffA600RedLight();
            TurnOffA600GreenLight();
            TurnOnA600RedLight();
            

            //ShowMessage("!!!!!!!!!");
            LiveCaptureFingerprintBitmapData bitmap = null;
            LiveCaptureFingerprintBitmapData bitmap1 = null;
            isCapture = true;
            int qulity = 0;
            int qulityThreshold = (int)numericUpDownVerify.Value;

            int raisefinger = 0;
            int raisesound = 0;
            int qulitytemp = 0;
            player.SoundLocation = "please_press_your_finger.wav";
            player.Load();
            player.Play();
            IFingerprintFeature fearture = null;

            try
            {
                dev.BeginLiveCapture();
            }
            catch (TrustFingerException e)
            {
                if (token == pGuid)
                {
                    this.BeginInvoke(new Action(() => {
                        ShowErrorMessage("BeginLiveCapture Error code:" + e.ErrorCode);
                        dev.EndLiveCapture();
                        ResetVerify();
                    }));
                }
                //istask = false;
                return;
            }

            while (isCapture&&(token==pGuid))
            {
                try
                {
                    bitmap = dev.LiveCaptureBitmapData();
                }
                catch (CaptureException e)
                {
                    if (token == pGuid)
                    {
                        this.BeginInvoke(new Action(() => {
                            ShowErrorMessage("Capture image fail,Error code:" + e.Message);
                            dev.EndLiveCapture();
                            ResetVerify();
                        }));
                    }
                    
                    break;
                }
                //catch (TrustFingerException e)
                //{
                //    if (token == pGuid)
                //    {
                //        this.BeginInvoke(new Action(() => {
                //            ShowErrorMessage("LiveCaptureBitmapData Error code:" + e.ErrorCode);
                //            dev.EndLiveCapture();
                //            ResetVerify();
                //        }));
                //    }
                    
                //    break;
                //}
                //catch (InvalidOperationException e)
                //{
                //    if (token == pGuid)
                //    {
                //        this.BeginInvoke(new Action(() => {
                //            ShowErrorMessage(e.Message);
                //            dev.EndLiveCapture();
                //            ResetVerify();
                //        }));
                //    }
                    
                //    break;
                //}

                if (bitmap.CaptureStatus == LiveCaptureStatus.Stop)
                {
                    isCapture = false;
                    //if (bitmap.FakeFingerStatus == IsFakeFinger.TRUE)
                    //{
                    //    if (token == pGuid)
                    //    {
                    //        this.BeginInvoke(new Action(() =>
                    //        {
                    //            ShowErrorMessage("Fake Finger");

                    //            pictureBoxVeriftPass.Visible = false;
                    //            pictureBoxVerifyFail.Visible = true;
                    //            labelSimilarity.Text = "";
                    //            labelfingerpos.Text = "";

                    //            verticalProgressBarVerify.Value = 0;
                    //            textBoxVerify.Text = "0";

                    //            //if (checkBoxExportIMG.Checked == true)
                    //            //{                               
                    //            Bitmap previewBitmap = ConvertBytesToImage(bitmap.FingerprintImageData);
                    //            pictureBoxVerifyPreview.Image?.Dispose();
                    //            pictureBoxVerifyPreview.Image = previewBitmap;
                    //            //}
                    //            //else
                    //            //{
                    //            //    pictureBoxVerifyPreview.Image?.Dispose();
                    //            //    pictureBoxVerifyPreview.Image = null;
                    //            //}

                    //        }));
                    //    }

                    //}
                    break;
                }
                else
                {
                    if(bitmap.FakeFingerStatus == IsFakeFinger.UNKNOWN)
                    {
                        ShowMessage("Unknown Finger");
                    }
                    else if(bitmap.FakeFingerStatus == IsFakeFinger.TRUE)
                    {
                        ShowErrorMessage("Fake Finger");
                    }
                    else
                    {
                        ShowMessage("");
                    }
                    Bitmap previewBitmap = ConvertBytesToImage(bitmap.FingerprintImageData);
                    try
                    {
                        qulity = dev.ImageQuality(previewBitmap);
                        //ShowErrorMessage($"{qulity}");
                    }
                    catch (ArgumentNullException e)
                    {
                        if (token == pGuid)
                        {
                            this.BeginInvoke(new Action(() => {
                                ShowErrorMessage("The image is null.");
                                dev.EndLiveCapture();
                                ResetVerify();
                            }));
                        }
                        
                        break;
                    }
                    catch(TrustFingerException e)
                    {
                        if (token == pGuid)
                        {
                            this.BeginInvoke(new Action(() => {
                                ShowErrorMessage("Get image quality fail,Error code:"+e.ErrorCode);
                                dev.EndLiveCapture();
                                ResetVerify();
                            }));
                        }

                        break;
                    }


                    this.BeginInvoke(new Action(() =>
                    {
                        if(isCapture)
                        {
                            //groupBoxSelect.Enabled = false;
                            pictureBoxVerifyPreview.Image?.Dispose();
                            pictureBoxVerifyPreview.Image = previewBitmap;
                            verticalProgressBarVerify.Value = qulity;
                            textBoxVerify.Text = qulity.ToString();
                        }
                    }));

                    if (qulity > qulitytemp && bitmap.FakeFingerStatus == IsFakeFinger.FALSE)
                    {
                        bitmap1 = bitmap;
                        qulitytemp = qulity;
                        if (qulity >= qulityThreshold)
                        {
                            try
                            {
                                fearture = dev.ExtractFeature(pos);
                            }
                            catch (InvalidOperationException ex)
                            {
                                if(token==pGuid)
                                {
                                    dev.EndLiveCapture();
                                    this.BeginInvoke(new Action(() =>
                                    {

                                        ShowErrorMessage(ex.Message);
                                        //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                        pictureBoxVeriftPass.Visible = false;
                                        pictureBoxVerifyFail.Visible = true;
                                        labelSimilarity.Text = "";
                                        labelfingerpos.Text = "";

                                        Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                        pictureBoxVerifyPreview.Image?.Dispose();
                                        pictureBoxVerifyPreview.Image = previewBitmap1;
                                        verticalProgressBarVerify.Value = qulitytemp;
                                        textBoxVerify.Text = qulitytemp.ToString();
                                    }));
                                }
                                
                                break;
                            }
                            catch (ExtractFeatureException ex)
                            {
                                if(token==pGuid)
                                {
                                    dev.EndLiveCapture();
                                    this.BeginInvoke(new Action(() =>
                                    {

                                        ShowErrorMessage("Extract feature failure,Please try again.");
                                        //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                        pictureBoxVeriftPass.Visible = false;
                                        pictureBoxVerifyFail.Visible = true;
                                        labelSimilarity.Text = "";
                                        labelfingerpos.Text = "";

                                        Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                        pictureBoxVerifyPreview.Image?.Dispose();
                                        pictureBoxVerifyPreview.Image = previewBitmap1;
                                        verticalProgressBarVerify.Value = qulitytemp;
                                        textBoxVerify.Text = qulitytemp.ToString();
                                    }));
                                }
                                
                                break;
                            }
                            catch (TrustFingerException ex)
                            {
                                if(token==pGuid)
                                {
                                    dev.EndLiveCapture();
                                    this.BeginInvoke(new Action(() =>
                                    {
                                        ShowErrorMessage("Extract feature failure,Error code:" + ex.ErrorCode);
                                        //ShowErrorMessage("Extract feature failure,Please try again.");
                                        //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                        pictureBoxVeriftPass.Visible = false;
                                        pictureBoxVerifyFail.Visible = true;
                                        labelSimilarity.Text = "";
                                        labelfingerpos.Text = "";

                                        Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                        pictureBoxVerifyPreview.Image?.Dispose();
                                        pictureBoxVerifyPreview.Image = previewBitmap1;
                                        verticalProgressBarVerify.Value = qulitytemp;
                                        textBoxVerify.Text = qulitytemp.ToString();
                                    }));
                                }
                                
                                break;
                            }
                            


                            if (raisesound == 0)
                            {
                                TurnOffA600RedLight();
                                TurnOnA600GreenLight();
                                
                                
                                player.SoundLocation = "please_raise_your_finger.wav";
                                player.Load();
                                player.Play();

                                raisesound = 1;
                            }
                        }
                    }

                    if (qulity <= 20 && raisesound == 1)
                    {
                        raisefinger = 1;
                    }

                    //if (qulity >= qulityThreshold)
                    //{
                    //    TurnOffA600RedLight();
                    //    TurnOnA600GreenAuto();
                    //    var fearture = dev.ExtractFeature(pos);
                    //    var result = dev.Verify(level, fearture.FeatureData, sourceTemplate);
                    //    ShowMessage($"Verify Pass={result.IsMatch} Similarity={result.Similarity}");

                    //    Invoke(new Action(() =>
                    //    {
                    //        pictureBoxVeriftPass.Visible = result.IsMatch;
                    //        pictureBoxVerifyFail.Visible = !result.IsMatch;
                    //        labelSimilarity.Text = $"{result.Similarity}";

                    //    }));
                    //    break;

                    //}

                    if(raisefinger==1)
                    {
                        TurnOffA600GreenLight();
                        try
                        {                           
                            var result = dev.Verify(level, fearture.FeatureData, sourceTemplate);
                            ShowMessage($"Verify Pass={result.IsMatch} Similarity={result.Similarity}");

                            Invoke(new Action(() =>
                            {
                                pictureBoxVeriftPass.Visible = result.IsMatch;
                                pictureBoxVerifyFail.Visible = !result.IsMatch;
                                labelSimilarity.Text = $"{result.Similarity}";
                                labelfingerpos.Text = $"{FormatHelper.FormatFingerprintPosition(pos)}";

                                Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                pictureBoxVerifyPreview.Image?.Dispose();
                                pictureBoxVerifyPreview.Image = previewBitmap1;
                                verticalProgressBarVerify.Value = qulitytemp;
                                textBoxVerify.Text = qulitytemp.ToString();

                            }));
                            break;
                        }
                        catch (TrustFingerException e)
                        {
                            if(token==pGuid)
                            {
                                ShowErrorMessage("Verify is fail.Error code:" + e.ErrorCode);
                                this.BeginInvoke(new Action(() =>
                                {
                                    //ShowErrorMessage("Extract feature failure,Please try again.");
                                    //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                    pictureBoxVeriftPass.Visible = false;
                                    pictureBoxVerifyFail.Visible = true;
                                    labelSimilarity.Text = "";
                                    labelfingerpos.Text = "";

                                    Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                    pictureBoxVerifyPreview.Image?.Dispose();
                                    pictureBoxVerifyPreview.Image = previewBitmap1;
                                    verticalProgressBarVerify.Value = qulitytemp;
                                    textBoxVerify.Text = qulitytemp.ToString();
                                }));
                            }
                            
                            break;
                            //ignore
                        }
                        catch(ArgumentNullException e)
                        {
                            if (token == pGuid)
                            {
                                ShowErrorMessage(e.Message);
                                this.BeginInvoke(new Action(() =>
                                {
                                    //ShowErrorMessage("Extract feature failure,Please try again.");
                                    //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                    pictureBoxVeriftPass.Visible = false;
                                    pictureBoxVerifyFail.Visible = true;
                                    labelSimilarity.Text = "";
                                    labelfingerpos.Text = "";

                                    Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                    pictureBoxVerifyPreview.Image?.Dispose();
                                    pictureBoxVerifyPreview.Image = previewBitmap1;
                                    verticalProgressBarVerify.Value = qulitytemp;
                                    textBoxVerify.Text = qulitytemp.ToString();
                                }));
                            }

                            break;
                        }
                        
                    }

                }

            }
            if(token==pGuid)
            {
                this.BeginInvoke(new Action(() => {
                    buttonVerify.Text = "Start Verify";
                    verify = false;
                    //verticalProgressBarVerify.Value = 0;
                    //textBoxVerify.Text = "0";
                    tableLayoutPanel14.Enabled = true;
                    comboBoxSecurityLevel.Enabled = true;
                    dataGridViewVerify.Enabled = true;
                    numericUpDownVerify.Enabled = true;
                }));


                dev.EndLiveCapture();
                TurnOffA600RedLight();
            }
            

            //istask = false;
        }

        private void ResetEnrollTab()
        {
            capturing = false;
            //isstop = true;
            isCapture = false;
            indentifing = false;
            pictureBoxEnroll1.Image?.Dispose();
            pictureBoxEnroll1.Image = null;

            pictureBoxEnroll2.Image?.Dispose();
            pictureBoxEnroll2.Image = null;

            pictureBoxEnroll3.Image?.Dispose();
            pictureBoxEnroll3.Image = null;

            pictureBoxEnrolledPre.Image?.Dispose();
            pictureBoxEnrolledPre.Image = null;

            verticalProgressBarEnroll.Value = 0;
            textBoxEnroll.Text = "";

            labelQuality1.Text = "Quality:";
            labelQuality2.Text = "Quality:";
            labelQuality3.Text = "Quality:";

            groupBoxEnrollSetting.Enabled = true;

            var checkBtns = panelFinger.Controls.OfType<CheckBox>();
            foreach (var chk in checkBtns)
            {
                chk.CheckedChanged -= ChangeEnrollFinger;
                chk.Checked = false;
                chk.CheckedChanged += ChangeEnrollFinger;
            }

            groupBoxEnrollSetting.Enabled = true;
            textBoxUserId.Text = string.Empty;
            textBoxFirstName.Text = string.Empty;
            textBoxLastName.Text = string.Empty;

            pictureBoxEnrollPass.Visible = false;
            pictureBoxEnrollFail.Visible = false;
            labelenrollresult.Text = "";
            TurnOffA600RedLight();
            TurnOffA600GreenLight();
            
        }
        private void ResetCaptureTab(bool cleanImag=true,bool cleanResult=true)
        {
            capturing = false;
            //isstop = true;
            indentifing = false;
            isCapture = false;
            //dev.EndLiveCapture();
            groupBoxCaptureSet.Enabled = true;
            
            //buttonCapture.Text = "Start Capture Image";
            
            if (cleanImag)
            {
                pictureBoxCapturePre.Image?.Dispose();
                pictureBoxCapturePre.Image = null;
                verticalProgressBarCapture.Value = 0;
                textBoxCaptureQulity.Text = "";
            }

            if(cleanResult)
            {
                pictureCaptureFail.Visible = false;
                pictureCapturePass.Visible = false;
                labelCaptureSucceed.Visible = false;
                labelCaptureFail.Visible = false;
                labelCFP.Visible = false;
                labelCIQ.Visible = false;
                labelCapfingerpos.Text = "";
                labelCaptureImageQuality.Text = "";
            }
           
            labelCaptureFingerPos.Text = "Select a finger";

            var checkBtns = panelCaptureImg.Controls.OfType<CheckBox>();
            foreach (var chk in checkBtns)
            {
                chk.CheckedChanged -= ChangeCaptureFinger;
                chk.Checked = false;
                chk.CheckedChanged += ChangeCaptureFinger;
            }
                dev.EndLiveCapture();
                //TurnOffA600RedLight();
                TurnOffA600RedLight();
                TurnOffA600GreenLight();
            
            
        }

        private void TurnOffA600RedLight()
        {
                if (checkBoxLED.Enabled == true && checkBoxLED.Checked == true)
                //if (checkBoxLED.Enabled == true && checkBoxLED.Checked == true)
                {
                    try
                    {
                        dev.SetLedStatus(1, LedStatus.Off);
                    }
                    catch (TrustFingerException ex)
                    {
                        ShowErrorMessage("SetLedStatus fail,Error code:" + ex.ErrorCode);
                        return;
                        //ignore 
                    }
                }
            
            
        }

        private void ResetIdentifyTab()
        {
            capturing = false;
            //isstop = true;
            isCapture = false;
            indentifing = false;

            dataGridViewIndetify.DataSource = null;

            numericUpDownIdentifyQu.Enabled = true;
           
            comboBoxIndentifyLevel.Enabled = true;
            verticalProgressBarIdentify.Value = 0;
            textBoxIdentify.Text = "";
            pictureBoxIndentify.Image?.Dispose();
            pictureBoxIndentify.Image = null;
            buttonIdentify.Text = "Start Identify";
            labelIdentifyResult.Text = string.Empty;

            dev.EndLiveCapture();
            TurnOffA600RedLight();
            TurnOffA600GreenLight();
                      
        }
        private bool indentifing = false;

        private List<IdentifyUser> IdentifyUserSet = new List<IdentifyUser>();
        /// <summary>
        /// Indentify Table View
        /// </summary>
        /// <param name="users">User list</param>
        /// <param name="pos">finger position</param>
        /// <param name="qulityThreshold">image qulityThreshold</param>
        /// <param name="level">Verify level</param>
        private void Indentify(List<EnrollUser> users, FingerPosition pos, int qulityThreshold, int level)
        {
            string token = pGuid;
            //istask = true;
            ShowMessage("Capturing...");
            this.BeginInvoke(new Action(() =>
            {
                dataGridViewIndetify.DataSource = null;
                buttonIdentify.Text = "Stop Identify";
                labelIdentifyResult.Text = string.Empty;
                numericUpDownIdentifyQu.Enabled = false;
                pictureBoxIndentify.Image?.Dispose();
                pictureBoxIndentify.Image = null;
                verticalProgressBarIdentify.Value = 0;
                textBoxIdentify.Text = string.Empty;
                comboBoxIndentifyLevel.Enabled = false;
                indentifing = true;
            }));

            LiveCaptureFingerprintBitmapData bitmap = null;
            LiveCaptureFingerprintBitmapData bitmap1 = null;
            indentifing = true;
            int qulity = 0;

            TurnOffA600GreenLight();
            TurnOffA600RedLight();
            TurnOnA600RedLight();
            int raisefinger = 0;
            int raisesound = 0;
            int qulitytemp = 0;
            player.SoundLocation = "please_press_your_finger.wav";
            player.Load();
            player.Play();
            IFingerprintFeature fearture = null;

            try
            {
                dev.BeginLiveCapture();
            }
            catch (TrustFingerException e)
            {
                if (token == pGuid)
                {
                    this.BeginInvoke(new Action(() =>
                    {
                        ShowErrorMessage("BeginLiveCapture Error code:" + e.ErrorCode);
                        dev.EndLiveCapture();
                        ResetIdentifyTab();
                    }));
                }

                //istask = false;
                return;
            }

            while (indentifing&&(token==pGuid))
            {
                try
                {
                    bitmap = dev.LiveCaptureBitmapData();
                }
                catch (CaptureException e)
                {
                    if (token == pGuid)
                    {
                        this.BeginInvoke(new Action(() =>
                        {
                            ShowErrorMessage("Capture image fail,Error code:" + e.Message);
                            dev.EndLiveCapture();
                            ResetIdentifyTab();
                        }));
                    }
                    
                    break;
                }
                //catch (TrustFingerException e)
                //{
                //    if (token == pGuid)
                //    {
                //        this.BeginInvoke(new Action(() =>
                //        {
                //            ShowErrorMessage("LiveCaptureBitmapData Error code:" + e.ErrorCode);
                //            dev.EndLiveCapture();
                //            ResetIdentifyTab();
                //        }));
                //    }
                    
                //    break;
                //}
                //catch (InvalidOperationException e)
                //{
                //    if (token == pGuid)
                //    {
                //        this.BeginInvoke(new Action(() =>
                //        {
                //            ShowErrorMessage(e.Message);
                //            dev.EndLiveCapture();
                //            ResetIdentifyTab();
                //        }));
                //    }
                    
                //    break;
                //}

                if (bitmap.CaptureStatus == LiveCaptureStatus.Stop)
                {
                    indentifing = false;
                    //if (bitmap.FakeFingerStatus == IsFakeFinger.TRUE)
                    //{
                    //    if (token == pGuid)
                    //    {
                    //        this.BeginInvoke(new Action(() =>
                    //        {
                    //            ShowErrorMessage("Fake Finger");

                    //            labelIdentifyResult.Text = "Fake Finger";
                    //            labelIdentifyResult.ForeColor = Color.Red;
                    //            dataGridViewIndetify.DataSource = null;

                    //            verticalProgressBarIdentify.Value = 0;
                    //            textBoxIdentify.Text = "0";

                    //            //if (checkBoxExportIMG.Checked == true)
                    //            //{
                    //            Bitmap previewBitmap = ConvertBytesToImage(bitmap.FingerprintImageData);
                    //            pictureBoxIndentify.Image?.Dispose();
                    //            pictureBoxIndentify.Image = previewBitmap;
                    //            //}
                    //            //else
                    //            //{
                    //            //    pictureBoxIndentify.Image?.Dispose();
                    //            //    pictureBoxIndentify.Image = null;
                    //            //}

                    //        }));
                    //    }

                    //}
                    break;
                }
                else
                {
                    if (bitmap.FakeFingerStatus == IsFakeFinger.UNKNOWN)
                    {
                        ShowMessage("Unknown Finger");
                    }
                    else if(bitmap.FakeFingerStatus == IsFakeFinger.TRUE)
                    {
                        ShowErrorMessage("Fake Finger");
                    }
                    else
                    {
                        ShowMessage("");
                    }
                    Bitmap previewBitmap = ConvertBytesToImage(bitmap.FingerprintImageData);
                    try
                    {
                        qulity = dev.ImageQuality(previewBitmap);
                    }
                    catch (ArgumentNullException e)
                    {
                        if (token == pGuid)
                        {
                            this.BeginInvoke(new Action(() =>
                            {
                                ShowErrorMessage("The image is null.");
                                dev.EndLiveCapture();
                                ResetIdentifyTab();
                            }));
                        }
                        
                        break;
                    }
                    catch (TrustFingerException e)
                    {
                        if (token == pGuid)
                        {
                            this.BeginInvoke(new Action(() =>
                            {
                                ShowErrorMessage("Get image quality fail,Error code:"+e.ErrorCode);
                                dev.EndLiveCapture();
                                ResetIdentifyTab();
                            }));
                        }

                        break;
                    }

                    this.BeginInvoke(new Action(() =>
                    {
                        if(indentifing)
                        {
                            //groupBoxSelect.Enabled = true;
                            pictureBoxIndentify.Image?.Dispose();
                            pictureBoxIndentify.Image = previewBitmap;
                            verticalProgressBarIdentify.Value = qulity;
                            textBoxIdentify.Text = qulity.ToString();
                            //textBoxVerify.Text = qulity.ToString();
                        }
                    }));

                    if (qulity > qulitytemp && bitmap.FakeFingerStatus == IsFakeFinger.FALSE)
                    {
                        bitmap1 = bitmap;
                        qulitytemp = qulity;
                        if (qulity >= qulityThreshold)
                        {
                            try
                            {
                                fearture = dev.ExtractFeature(pos);
                            }
                            catch (InvalidOperationException ex)
                            {
                                if(token==pGuid)
                                {
                                    dev.EndLiveCapture();
                                    this.BeginInvoke(new Action(() =>
                                    {

                                        ShowErrorMessage(ex.Message);
                                        //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                        labelIdentifyResult.Text = "";
                                        dataGridViewIndetify.DataSource = null;

                                        Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                        pictureBoxIndentify.Image?.Dispose();
                                        pictureBoxIndentify.Image = previewBitmap1;
                                        verticalProgressBarIdentify.Value = qulitytemp;
                                        textBoxIdentify.Text = qulitytemp.ToString();
                                    }));
                                }
                                
                                break;
                            }
                            catch (ExtractFeatureException ex)
                            {
                                if(token==pGuid)
                                {
                                    dev.EndLiveCapture();
                                    this.BeginInvoke(new Action(() =>
                                    {

                                        ShowErrorMessage("Extract feature failure,Please try again.");
                                        //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                        labelIdentifyResult.Text = "";
                                        dataGridViewIndetify.DataSource = null;

                                        Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                        pictureBoxIndentify.Image?.Dispose();
                                        pictureBoxIndentify.Image = previewBitmap1;
                                        verticalProgressBarIdentify.Value = qulitytemp;
                                        textBoxIdentify.Text = qulitytemp.ToString();
                                    }));
                                }
                                
                                break;
                            }
                            catch (TrustFingerException ex)
                            {
                                if(token==pGuid)
                                {
                                    dev.EndLiveCapture();
                                    this.BeginInvoke(new Action(() =>
                                    {
                                        ShowErrorMessage("Extract feature failure,Error code:" + ex.ErrorCode);
                                        //ShowErrorMessage("Extract feature failure,Please try again.");
                                        //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                        labelIdentifyResult.Text = "";
                                        dataGridViewIndetify.DataSource = null;

                                        Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                        pictureBoxIndentify.Image?.Dispose();
                                        pictureBoxIndentify.Image = previewBitmap1;
                                        verticalProgressBarIdentify.Value = qulitytemp;
                                        textBoxIdentify.Text = qulitytemp.ToString();
                                    }));
                                }
                                
                                break;
                            }
                            
                            

                            if (raisesound == 0)
                            {
                                TurnOffA600RedLight();
                                TurnOnA600GreenLight();
                                

                                player.SoundLocation = "please_raise_your_finger.wav";
                                player.Load();
                                player.Play();

                                raisesound = 1;
                            }
                        }
                    }

                    if (qulity <= 20 && raisesound == 1)
                    {
                        raisefinger = 1;
                    }

                    if(raisefinger==1)
                    {
                        TurnOffA600GreenLight();
                        
                        IdentifyUserSet.Clear();
                        foreach (var user in users)
                        {
                            try
                            {
                                var result = dev.Verify(level, fearture.FeatureData, user.FingerData);
                                IdentifyUser identifyUser = new IdentifyUser();
                                identifyUser.UserID = user.UserId;
                                identifyUser.FirstName = user.FirstName;
                                identifyUser.LastName = user.LastName;
                                identifyUser.Score = result.Similarity;
                                identifyUser.IsMatch = result.IsMatch;
                                IdentifyUserSet.Add(identifyUser);
                            }
                            catch (TrustFingerException e)
                            {
                                if(token==pGuid)
                                {
                                    ShowErrorMessage("Verify is fail.Error code:" + e.ErrorCode);
                                    this.BeginInvoke(new Action(() =>
                                    {
                                        //ShowErrorMessage("Extract feature failure,Please try again.");
                                        //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                        labelIdentifyResult.Text = "";
                                        dataGridViewIndetify.DataSource = null;

                                        Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                        pictureBoxIndentify.Image?.Dispose();
                                        pictureBoxIndentify.Image = previewBitmap1;
                                        verticalProgressBarIdentify.Value = qulitytemp;
                                        textBoxIdentify.Text = qulitytemp.ToString();
                                    }));
                                }
                                
                                break;
                                //ignore
                            }
                            catch(ArgumentNullException e)
                            {
                                if (token == pGuid)
                                {
                                    ShowErrorMessage(e.Message);
                                    this.BeginInvoke(new Action(() =>
                                    {
                                        //ShowErrorMessage("Extract feature failure,Please try again.");
                                        //MessageBox.Show("Extract feature failure.\nPlease try again.");
                                        labelIdentifyResult.Text = "";
                                        dataGridViewIndetify.DataSource = null;

                                        Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                                        pictureBoxIndentify.Image?.Dispose();
                                        pictureBoxIndentify.Image = previewBitmap1;
                                        verticalProgressBarIdentify.Value = qulitytemp;
                                        textBoxIdentify.Text = qulitytemp.ToString();
                                    }));
                                }

                                break;
                            }
                        }

                        ShowMessage($"Identify completed.");

                        Invoke(new Action(() =>
                        {
                            var result = IdentifyUserSet.Where(u => u.IsMatch == true).OrderByDescending(u => u.Score).ToList();
                            int index = 1;
                            foreach (var u in result)
                            {
                                u.Ranking = index;
                                index += 1;
                            }
                            if (result.Count == 0)
                            {
                                labelIdentifyResult.Text = "No match users found.";
                                labelIdentifyResult.ForeColor = Color.Red;
                                ShowMessage("No match user found.");
                            }
                            else
                            {
                                
                                labelIdentifyResult.Text = $"Match users:{result.Count}";
                                labelIdentifyResult.ForeColor = Color.Red;
                            }
                            dataGridViewIndetify.DataSource = result;

                            

                            Bitmap previewBitmap1 = ConvertBytesToImage(bitmap1.FingerprintImageData);
                            pictureBoxIndentify.Image?.Dispose();
                            pictureBoxIndentify.Image = previewBitmap1;
                            verticalProgressBarIdentify.Value = qulitytemp;
                            textBoxIdentify.Text = qulitytemp.ToString();

                        }));
                        break;
                    }

                    //if (qulity >= qulityThreshold)
                    //{
                    //    FingerprintFeature feature = null;
                    //    IdentifyUserSet.Clear();
                    //    feature = dev.ExtractFeature(pos);
                    //    TurnOffA600RedLight();
                    //    TurnOnA600GreenAuto();
                    //    foreach (var user in users)
                    //    {
                    //        var result = dev.Verify(level, feature.FeatureData, user.FingerData);
                    //        IdentifyUser identifyUser = new IdentifyUser();
                    //        identifyUser.UserID = user.UserId;
                    //        identifyUser.FirstName = user.FirstName;
                    //        identifyUser.LastName = user.LastName;
                    //        identifyUser.Score = result.Similarity;
                    //        identifyUser.IsMatch = result.IsMatch;
                    //        IdentifyUserSet.Add(identifyUser);
                    //    }
                       
                    //    ShowMessage($"Identify Complete.");

                    //    Invoke(new Action(() =>
                    //    {
                    //        var result = IdentifyUserSet.Where(u=>u.IsMatch==true).OrderByDescending(u => u.Score).ToList();
                    //        int index = 1;
                    //        foreach(var u in result)
                    //        {
                    //            u.Ranking = index;
                    //            index += 1;
                    //        }
                    //        if (result.Count == 0)
                    //        {
                    //            labelIdentifyResult.Text = "No match users found.";
                    //            labelIdentifyResult.ForeColor = Color.Red;
                    //            ShowErrorMessage("No match user found.");
                    //        }
                    //        else
                    //        {
                    //            labelIdentifyResult.Text = $"Match users:{result.Count}";
                    //            labelIdentifyResult.ForeColor = Color.Black;
                    //        }
                    //        dataGridViewIndetify.DataSource = result;
                           

                    //    }));
                    //    break;

                    //}

                }

            }

            if(token==pGuid)
            {
                indentifing = false;
                BeginInvoke(new Action(() =>
                {
                    numericUpDownIdentifyQu.Enabled = true;
                    comboBoxIndentifyLevel.Enabled = true;
                    //verticalProgressBarIdentify.Value = 0;
                    //textBoxIdentify.Text = string.Empty;
                    //pictureBoxIndentify.Image?.Dispose();
                    //pictureBoxIndentify.Image = null;
                    buttonIdentify.Text = "Start Identify";
                }));
                dev.EndLiveCapture();
            }
            
            
        }

        private void comboBoxDevType_SelectedIndexChanged(object sender, EventArgs e)
        {
            BindDevice();
        }

        private void checkBoxAutoSave_CheckedChanged(object sender, EventArgs e)
        {
            textBoxDir.Enabled= checkBoxAutoSave.Checked;
            buttonBrowser.Enabled= checkBoxAutoSave.Checked;
            comboBoxMinuFmt.Enabled = checkBoxAutoSave.Checked;
            comboBoxFormat.Enabled = checkBoxAutoSave.Checked;
            numericUpDownQulity.Enabled= checkBoxAutoSave.Checked;
        }

       
        //private bool isstop = false;
        private void ResetVerify()
        {
            capturing = false;
            //isstop = true;
            isCapture = false;
            indentifing = false;
            pictureBoxVerifyPreview.Image?.Dispose();
            pictureBoxVerifyPreview.Image = null;

            textBoxVerify.Text = "";
            labelSimilarity.Text = "";
            labelfingerpos.Text = "";

            verticalProgressBarVerify.Value = 0;

            pictureBoxVeriftPass.Visible = false;
            pictureBoxVerifyFail.Visible = false;

            labelFileVerify.Text = $"Please click Start Verify button to select a fingerprint feature file for verification.";

            buttonVerify.Text = "Start Verify";
            verify = false;
            //numericUpDownVerify.Enabled = true;

            numericUpDownVerify.Enabled = true;

            if (radioButtonFile.Checked)
            {
                dataGridViewVerify.Visible = false;
                var chkBts = panelVerify.Controls.OfType<CheckBox>();
                foreach (CheckBox chk in chkBts)
                {
                    chk.Checked = false;
                }
            }
            else
            {
                dataGridViewVerify.Visible = true;
                if(dataGridViewVerify.RowCount == 0)
                {
                    var chkBts = panelVerify.Controls.OfType<CheckBox>();
                    foreach (CheckBox chk in chkBts)
                    {
                        chk.Checked = false;
                    }
                }
            }
            dev.EndLiveCapture();
            TurnOffA600RedLight();
            TurnOffA600GreenLight();
                     
        }
        private void RestoreEnroll()
        {
            //pictureBoxEnroll1.Image?.Dispose();
            //pictureBoxEnroll1.Image = null;

            //pictureBoxEnroll2.Image?.Dispose();
            //pictureBoxEnroll2.Image = null;

            //pictureBoxEnroll3.Image?.Dispose();
            //pictureBoxEnroll3.Image = null;

            pictureBoxEnrolledPre.Image?.Dispose();
            pictureBoxEnrolledPre.Image = null;

            verticalProgressBarEnroll.Value = 0;
            textBoxEnroll.Text = "";

            isCapture = false;
            panelFinger.Enabled = true;

            var checkBtns = panelFinger.Controls.OfType<CheckBox>();
            foreach (var chk in checkBtns)
            {
                chk.CheckedChanged -= ChangeEnrollFinger;
                chk.Checked = false;
                chk.CheckedChanged += ChangeEnrollFinger;
            }

            groupBoxEnrollSetting.Enabled = true;
            textBoxUserId.Text=string.Empty;
            textBoxFirstName.Text = string.Empty;
            textBoxLastName.Text = string.Empty;
            dev.EndLiveCapture();
            
        }

        private void RestoreToEnrollAgain(bool cleanimg=true)
        {
            this.BeginInvoke(new Action(() => {
                if(cleanimg)
                {
                    pictureBoxEnroll1.Image?.Dispose();
                    pictureBoxEnroll1.Image = null;

                    pictureBoxEnroll2.Image?.Dispose();
                    pictureBoxEnroll2.Image = null;

                    pictureBoxEnroll3.Image?.Dispose();
                    pictureBoxEnroll3.Image = null;

                    pictureBoxEnrolledPre.Image?.Dispose();
                    pictureBoxEnrolledPre.Image = null;

                    verticalProgressBarEnroll.Value = 0;
                    textBoxEnroll.Text = "";

                    labelQuality1.Text = "Quality:";
                    labelQuality2.Text = "Quality:";
                    labelQuality3.Text = "Quality:";
                }
               
                isCapture = false;
                panelFinger.Enabled = true;

                var checkBtns = panelFinger.Controls.OfType<CheckBox>();
                foreach (var chk in checkBtns)
                {
                    chk.CheckedChanged -= ChangeEnrollFinger;
                    chk.Checked = false;
                    chk.CheckedChanged += ChangeEnrollFinger;
                }

                groupBoxEnrollSetting.Enabled = true;
            }));
        }
        private void ChangeCaptureFinger(object sender, EventArgs e)
        {
            CheckBox checkBx = sender as CheckBox;
            bool isChecked = checkBx.Checked;
            var checkBtns = panelCaptureImg.Controls.OfType<CheckBox>().Where(c => c.Equals(checkBx) == false);
            foreach(var chk in checkBtns)
            {
                chk.CheckedChanged -= ChangeCaptureFinger;
                chk.Checked = false;
                chk.CheckedChanged += ChangeCaptureFinger;
            }
            if (isChecked == true)
            {
                int pos = int.Parse(checkBx.Tag.ToString());
                FingerPosition position = (FingerPosition)pos;
                labelCaptureFingerPos.Text=FormatHelper.FormatFingerprintPosition(position);
                StopCaptureFingerprint();//Call stop live capture everytime
                //Thread.Sleep(300);
                StartCaptureFingerprint(checkBx);
            }
            else
            {
                StopCaptureFingerprint();
                ShowMessage("Capture stopped");
            }
        }
       
        public void StartEnroll(FingerPosition fingerprintPos,CheckBox ckb)
        {
            if (numericUpDownImg.Controls[1].Text == "")
            {
                MessageBox.Show("Image Quality Threshold could not be empty!");
                ckb.CheckedChanged -= ChangeEnrollFinger;
                ckb.Checked = false;
                ckb.CheckedChanged += ChangeEnrollFinger;
                return;
            }

            if (string.IsNullOrEmpty(textBoxUserId.Text))
            {
                MessageBox.Show("User Id  could not be empty!");
                ShowErrorMessage("User Id  could not be empty!");
                //isStart = false;
                return;
            }
            if (string.IsNullOrEmpty(textBoxFirstName.Text))
            {
                MessageBox.Show("First Name could not be empty!");
                ShowErrorMessage("First Name could not be empty!");
                //isStart = false;
                return;
            }

            pictureBoxEnroll1.Image?.Dispose();
            pictureBoxEnroll1.Image = null;

            pictureBoxEnroll2.Image?.Dispose();
            pictureBoxEnroll2.Image = null;

            pictureBoxEnroll3.Image?.Dispose();
            pictureBoxEnroll3.Image = null;

            pictureBoxEnrolledPre.Image?.Dispose();
            pictureBoxEnrolledPre.Image = null;


            verticalProgressBarEnroll.Value = 0;
            textBoxEnroll.Text = "";

            labelQuality1.Text = "Quality:";
            labelQuality2.Text = "Quality:";
            labelQuality3.Text = "Quality:";

            pictureBoxEnrollFail.Visible = false;
            pictureBoxEnrollPass.Visible = false;
            labelenrollresult.Text = "";

            //var checkedButton = panelFinger.Controls.OfType<RadioButton>()
            //                          .FirstOrDefault(r => r.Checked);
            //if (checkedButton == null)
            //{
            //    MessageBox.Show("Must choose one finger position to enroll!");
            //    ShowErrorMessage("Must choose one finger position to enroll!");
            //    //isStart = false;
            //    return;
            //}
            //int pos = int.Parse(checkedButton.Tag.ToString());
            string userId = textBoxUserId.Text;
            string firstName = textBoxFirstName.Text;
            string lastName = textBoxLastName.Text;


            groupBoxEnrollSetting.Enabled = false;

            pGuid = Guid.NewGuid().ToString();

            //while(true)
            //{
                //if(istask==false)
                //{
                    TaskEx.Delay(100)
                .ContinueWith(t => CaptureLiveFingerprint(userId, firstName, lastName, fingerprintPos));
                    //break;
                //}
            //}

            
        }

        public void StopEnroll()
        {
            capturing = false;
            //isstop = true;

            pictureBoxEnroll1.Image?.Dispose();
            pictureBoxEnroll1.Image = null;

            pictureBoxEnroll2.Image?.Dispose();
            pictureBoxEnroll2.Image = null;

            pictureBoxEnroll3.Image?.Dispose();
            pictureBoxEnroll3.Image = null;

            pictureBoxEnrolledPre.Image?.Dispose();
            pictureBoxEnrolledPre.Image = null;

            verticalProgressBarEnroll.Value = 0;
            textBoxEnroll.Text = "";

            labelQuality1.Text = "Quality:";
            labelQuality2.Text = "Quality:";
            labelQuality3.Text = "Quality:";

            dev.EndLiveCapture();
            TurnOffA600RedLight();
            TurnOffA600GreenLight();
            
        }
      
        private void buttonAddUser_Click(object sender, EventArgs e)
        {
            DialogResult result = openFileDialogVerify.ShowDialog();
            if (result == DialogResult.OK)
            {
                if (File.Exists(openFileDialogVerify.FileName))
                {
                    string extension = Path.GetExtension(openFileDialogVerify.FileName);
                    string fileNameWithoutExtension= Path.GetFileNameWithoutExtension(openFileDialogVerify.FileName);
                    if (extension != ".iso-fmr" && extension != ".bione" && extension != ".ansi-fmr" )
                    {
                        MessageBox.Show("Please select a fingerprint featrue file!");
                        ShowErrorMessage("Please select a fingerprint featrue file!");
                        return;
                    }
                    else
                    {
                        byte[] fea = File.ReadAllBytes(openFileDialogVerify.FileName);
                        List<EnrollUser> users = new List<EnrollUser>();
                        using (TrustFingerDbContext db = new TrustFingerDbContext())
                        {
                            //var ret=db.Database.SqlQuery<EnrollUser>("SELECT * FROM EnrollUsers");
                            users = db.EnrollUser.ToList();
                        }
                        foreach (var user in users)
                        {
                            try
                            {
                                var re = dev.Verify(4, fea, user.FingerData);
                                if (re.IsMatch)
                                {
                                    MessageBox.Show("The finger already exists.");
                                    ShowErrorMessage("The finger already exists.");
                                    return;
                                }
                            }
                            catch {
                                MessageBox.Show("Database check fail.");
                                ShowErrorMessage("Database check fail.");
                                return; }
                        }

                        string[] fs = fileNameWithoutExtension.Split('_');
                        FingerPosition position = FingerPosition.UnKnow;
                        if (fs.Length == 4)
                        {
                            position = FormatHelper.ConvertToFingerPosition(fs[2]);
                        }
                        ImportForm frm = new ImportForm(position, openFileDialogVerify.FileName);
                        frm.Imported += Frm_Imported;
                        frm.ShowDialog();
                    }                   
                }
                //else
                //{
                //    buttonVerify.Text = "Start Verify";
                //    verify = false;
                //}
            }
        }

        private void Frm_Imported(object sender, EnrollUser e)
        {
            ImportForm frm = sender as ImportForm;
            frm.Imported -= Frm_Imported;
            SaveEnrollment((FingerPosition)e.FingerPosition,e.UserId, e.FirstName, e.LastName, e.FingerData);
            BindUser();
        }

        private void buttonRemove_Click(object sender, EventArgs e)
        {
            if (dataGridViewEnroll.RowCount == 0)
            {
                MessageBox.Show("The database is empty.");
                ShowErrorMessage("The database is empty.");
                return;
            }

            if (dataGridViewEnroll.SelectedRows == null || dataGridViewEnroll.SelectedRows.Count == 0)
            {
                MessageBox.Show("Please selected one user.");
                ShowErrorMessage("Please selected one user.");
                return;
            }

            DialogResult dr = MessageBox.Show("Remove the selected user?", "Warning", MessageBoxButtons.OKCancel);
            if(dr==DialogResult.OK)
            {
                DataGridViewRow removeItem = dataGridViewEnroll.SelectedRows[0];
                int id = int.Parse(removeItem.Cells[0].Value?.ToString());
                using (TrustFingerDbContext db = new TrustFingerDbContext())
                {
                    var usr = db.EnrollUser.Where(u => u.Id == id).FirstOrDefault();
                    if (usr != null)
                    {
                        db.EnrollUser.Remove(usr);
                        db.SaveChanges();

                        //dataGridViewEnroll.Rows.Remove(removeItem);
                    }
                }
                BindUser();
            }

            
        }

        private void buttonRemoveAll_Click(object sender, EventArgs e)
        {
            if(dataGridViewEnroll.RowCount==0)
            {
                MessageBox.Show("The database is empty.");
                ShowErrorMessage("The database is empty.");
                return;
            }
            DialogResult dr = MessageBox.Show("Remove all?", "Warning", MessageBoxButtons.OKCancel);
            if(dr==DialogResult.OK)
            {
                using (TrustFingerDbContext db = new TrustFingerDbContext())
                {
                    string del = "DELETE FROM EnrollUsers";
                    db.Database.ExecuteSqlCommand(del);
                    BindUser();
                }
            }

            
        }

        private void tabControlMain_Deselected(object sender, TabControlEventArgs e)
        {
            //capturing = false;
            switch (e.TabPageIndex)
            {
                case 0:
                    ResetCaptureTab();
                    break;
                case 1:                
                    ResetEnrollTab();
                    break;
                case 2:
                    ResetVerify();
                    break;
                case 3:
                    ResetIdentifyTab();
                    break;
            }
        }

        private void buttonIdentify_Click(object sender, EventArgs e)
        {
            if (indentifing == false)
            {
                if (numericUpDownIdentifyQu.Controls[1].Text == "")
                {
                    MessageBox.Show("Image Quality Threshold could not be empty!");
                    return;
                }

                //dataGridViewIndetify.DataSource = null;
                //buttonIdentify.Text = "Stop Identify";
                //labelIdentifyResult.Text = string.Empty;
                //numericUpDownIdentifyQu.Enabled = false;
                //pictureBoxIndentify.Image?.Dispose();
                //pictureBoxIndentify.Image = null;
                //verticalProgressBarIdentify.Value = 0;
                //textBoxIdentify.Text = string.Empty;
                //comboBoxIndentifyLevel.Enabled = false;
                //indentifing = true;

                dev.EndLiveCapture();
                
                int level = comboBoxIndentifyLevel.SelectedIndex + 1;
                int qulity = (int)numericUpDownIdentifyQu.Value;
               
                FingerPosition pos = FingerPosition.UnKnow;
                List<EnrollUser> users = new List<EnrollUser>();
                using (TrustFingerDbContext db = new TrustFingerDbContext())
                {
                    users = db.EnrollUser.ToList();

                }
                
                if (users?.Count > 0)
                {
                    pGuid = Guid.NewGuid().ToString();
                    //while(true)
                    //{
                        //if(istask==false)
                        //{
                            TaskEx.Delay(100)
               .ContinueWith(t => Indentify(users, pos, qulity, level));
                           // break;
                        //}
                    //}                  
                }
                else
                {                  
                    ShowMessage("No enroll users found.");
                }

            }
            else
            {
                
                indentifing = false;

                numericUpDownIdentifyQu.Enabled = true;                
                comboBoxIndentifyLevel.Enabled = true;

                buttonIdentify.Text = "Start Identify";
                ShowMessage("Capture stopped");

                dev.EndLiveCapture();
                TurnOffA600RedLight();
                TurnOffA600GreenLight();
            }
        }

        private void buttonBrowser_Click(object sender, EventArgs e)
        {
            var result = folderBrowserDialogStorage.ShowDialog();
            if (result == DialogResult.OK)
            {
                textBoxDir.Text = folderBrowserDialogStorage.SelectedPath;
            }
        }

        private void textBoxUserId_KeyPress(object sender, KeyPressEventArgs e)
        {
            //if (!(e.KeyChar >= '0' && e.KeyChar <= '9') && e.KeyChar != (char)8)
            //{
            //    e.Handled = true;
            //}
            //if (!(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
            //{
            //    e.Handled = true;
            //}
            if (!((e.KeyChar >= '0' && e.KeyChar <= '9') || (e.KeyChar >= 'A' && e.KeyChar <= 'Z') || (e.KeyChar >= 'a' && e.KeyChar <= 'z') || e.KeyChar == '_') && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
        }

        private void textBoxFirstName_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!((e.KeyChar >= '0' && e.KeyChar <= '9') || (e.KeyChar >= 'A' && e.KeyChar <= 'Z') || (e.KeyChar >= 'a' && e.KeyChar <= 'z') || e.KeyChar == '_') && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
        }
        private void textBoxLastName_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!((e.KeyChar >= '0' && e.KeyChar <= '9') || (e.KeyChar >= 'A' && e.KeyChar <= 'Z') || (e.KeyChar >= 'a' && e.KeyChar <= 'z') || e.KeyChar == '_') && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
        }

        int enrolltime = 0;
        private void ChangeEnrollFinger(object sender, EventArgs e)
        {
            CheckBox checkBx = sender as CheckBox;
            bool isChecked = checkBx.Checked;

            if (string.IsNullOrWhiteSpace(textBoxUserId.Text)||string.IsNullOrWhiteSpace(textBoxFirstName.Text))
            {
                MessageBox.Show("User id or first name could not be empty.");
                ShowErrorMessage("User id or first name could not be empty.");
                checkBx.CheckedChanged -= ChangeEnrollFinger;
                checkBx.Checked = false;
                checkBx.CheckedChanged += ChangeEnrollFinger;
                return;
            }

            panelFinger.Enabled = false;
            ShowMessage("Database searching...");
            using (TrustFingerDbContext db = new TrustFingerDbContext())
            {
                var usr=db.EnrollUser.Where(u => u.UserId == textBoxUserId.Text.Trim());
                if (usr.Count() > 0)
                {
                    MessageBox.Show($"Duplicate user id:{textBoxUserId.Text.Trim()}");
                    ShowErrorMessage($"Duplicate user id: {textBoxUserId.Text.Trim()}");
                    checkBx.CheckedChanged -= ChangeEnrollFinger;
                    checkBx.Checked = false;
                    checkBx.CheckedChanged += ChangeEnrollFinger;
                    panelFinger.Enabled = true;
                    return;
                }
            }
            panelFinger.Enabled = true;

            var checkBtns = panelFinger.Controls.OfType<CheckBox>().Where(c => c.Equals(checkBx) == false);
            foreach (var chk in checkBtns)
            {
                chk.CheckedChanged -= ChangeEnrollFinger;
                chk.Checked = false;
                chk.CheckedChanged += ChangeEnrollFinger;
            }
            if (isChecked == true)
            {
                int pos = int.Parse(checkBx.Tag.ToString());
                StopEnroll();//Call stop live capture everytime
                //RestoreToEnrollAgain();
                //Thread.Sleep(300);
                StartEnroll((FingerPosition)pos,checkBx);
                
            }
            else
            {
                //TurnOffA600RedLight();
                StopEnroll();
                ShowMessage("Enroll stopped");
                RestoreToEnrollAgain();
            }
        }

        private void buttonVerify_Click(object sender, EventArgs e)
        {
            if (verify == false)
            {
                if (numericUpDownVerify.Controls[1].Text == "")
                {
                    MessageBox.Show("Image Quality Threshold could not be empty!");
                    return;
                }

                byte[] toVerifyTemplate = null;
                int level = comboBoxSecurityLevel.SelectedIndex + 1;
                FingerPosition pos = FingerPosition.UnKnow;
                
                if (radioButtonLocalDB.Checked)
                {
                    if (dataGridViewVerify.RowCount == 0)
                    {
                        MessageBox.Show("The database is null,please enroll first or try another way.");
                        //buttonVerify.Text = "Start Verify";
                        //verify = false;
                        //numericUpDownVerify.Enabled = true;
                        return;
                    }
                    if (dataGridViewVerify.SelectedRows == null || dataGridViewVerify.SelectedRows.Count == 0)
                    {
                        MessageBox.Show("Please selected user to verify.");
                        //ShowErrorMessage("Please selected user to verify.");
                        //buttonVerify.Text = "Start Verify";
                        //verify = false;
                        //numericUpDownVerify.Enabled = true;
                        return;
                    }

                    DataGridViewRow removeItem = dataGridViewVerify.SelectedRows[0];
                    int id = int.Parse(removeItem.Cells[0].Value?.ToString());

                    using (TrustFingerDbContext db = new TrustFingerDbContext())
                    {
                        var usr = db.EnrollUser.Where(u => u.Id == id).FirstOrDefault();
                        toVerifyTemplate = usr?.FingerData;
                        pos = (FingerPosition)usr?.FingerPosition;
                    }

                    if (toVerifyTemplate != null)
                    {
                        //pictureBoxVeriftPass.Visible = false;
                        //pictureBoxVerifyFail.Visible = false;
                        //labelSimilarity.Text = $"";
                        //labelfingerpos.Text = "";
                        //textBoxVerify.Text = "";
                        //verticalProgressBarVerify.Value = 0;
                        //pictureBoxVerifyPreview.Image?.Dispose();
                        //pictureBoxVerifyPreview.Image = null;
                        //tableLayoutPanel14.Enabled = false;
                        //comboBoxSecurityLevel.Enabled = false;
                        //dataGridViewVerify.Enabled = false;
                        //numericUpDownVerify.Enabled = false;

                        pGuid = Guid.NewGuid().ToString();

                        //while(true)
                        //{
                            //if(istask==false)
                            //{
                                
                                TaskEx.Delay(100).ContinueWith(t =>
                                {
                                    Verify(toVerifyTemplate, pos, level);
                                });
                                //buttonVerify.Text = "Stop Verify";
                                //verify = true;
                                //break;
                            //}
                       // }
                        
                        
                    }

                }
                else
                {
                    DialogResult result = openFileDialogVerify.ShowDialog();
                    if (result == DialogResult.OK)
                    {
                        if (File.Exists(openFileDialogVerify.FileName))
                        {
                            string extension = Path.GetExtension(openFileDialogVerify.FileName);
                            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(openFileDialogVerify.FileName);
                            if (extension != ".iso-fmr" && extension != ".bione" && extension != ".ansi-fmr")
                            {
                                MessageBox.Show("Please select a fingerprint featrue file!");
                                //ShowErrorMessage("Please select a fingerprint featrue file!");
                                //buttonVerify.Text = "Start Verify";
                                //verify = false;
                                //numericUpDownVerify.Enabled = true;
                            }
                            else
                            {
                                labelFileVerify.Text = $"FilePath:{openFileDialogVerify.FileName}";
                                //pictureBoxVeriftPass.Visible = false;
                                //pictureBoxVerifyFail.Visible = false;
                                //labelSimilarity.Text = $"";
                                //labelfingerpos.Text = "";
                                //textBoxVerify.Text = "";
                                //verticalProgressBarVerify.Value = 0;
                                //pictureBoxVerifyPreview.Image?.Dispose();
                                //pictureBoxVerifyPreview.Image = null;
                                //tableLayoutPanel14.Enabled = false;
                                //comboBoxSecurityLevel.Enabled = false;
                                //dataGridViewVerify.Enabled = false;
                                toVerifyTemplate = File.ReadAllBytes(openFileDialogVerify.FileName);
                                //numericUpDownVerify.Enabled = false;

                                string[] fs = fileNameWithoutExtension.Split('_');

                                if (fs.Length == 4)
                                {
                                    pos = FormatHelper.ConvertToFingerPosition(fs[2]);
                                }
                                string posCode = ((int)pos).ToString();
                                var chkBts = panelVerify.Controls.OfType<CheckBox>();
                                foreach (CheckBox chk in chkBts)
                                {
                                    chk.Checked = false;
                                    if (chk.Tag.ToString() == posCode)
                                    {
                                        chk.Checked = true; ;
                                    }
                                }

                                //while (true)
                                //{
                                    //if (istask == false)
                                    //{

                                        TaskEx.Delay(100).ContinueWith(t =>
                                        {
                                            Verify(toVerifyTemplate, pos, level);
                                        });
                                        //buttonVerify.Text = "Stop Verify";
                                        //verify = true;
                                        //break;
                                    //}
                                //} 
                                
                            }
                            
                        }
                        //else
                        //{
                        //    buttonVerify.Text = "Start Verify";
                        //    verify = false;
                        //}
                    }
                    else
                    {
                        buttonVerify.Text = "Start Verify";
                        verify = false;
                        //numericUpDownVerify.Enabled = true;
                    }
                }

            }
            else
            {
                buttonVerify.Text = "Start Verify";
                isCapture = false;               
                verify = false;

                ShowMessage("Capture stopped");
                pictureBoxVeriftPass.Visible = false;
                pictureBoxVerifyFail.Visible = false;
                labelSimilarity.Text = $"";
                labelfingerpos.Text = "";
                textBoxVerify.Text = "";
                verticalProgressBarVerify.Value = 0;
                pictureBoxVerifyPreview.Image?.Dispose();
                pictureBoxVerifyPreview.Image = null;
                tableLayoutPanel14.Enabled = true;
                comboBoxSecurityLevel.Enabled = true;
                dataGridViewVerify.Enabled = true;

                dev.EndLiveCapture();
                TurnOffA600RedLight();
                TurnOffA600GreenLight();
            }
        }

        private void TurnOnA600RedLight()
        {
            if (checkBoxLED.Enabled == true && checkBoxLED.Checked == true)
            {
                try
                {
                    dev.SetLedStatus(1, LedStatus.On);
                }
                catch(TrustFingerException e)
                {
                    ShowErrorMessage("SetLedStatus fail,Error code:" + e.ErrorCode);
                    return;
                    //ignore 
                }
            }
        }

        private void TurnOnA600GreenAuto()
        {
            if (checkBoxLED.Enabled == true && checkBoxLED.Checked == true)
            {
                TaskEx.Run(() =>
                {
                    TurnOnA600GreenLight();
                    Thread.Sleep(1 * 1000);
                    TurnOffA600GreenLight();
                });
               
            }
        }
        private void TurnOnA600GreenLight()
        {
            if (checkBoxLED.Enabled == true && checkBoxLED.Checked == true)
            {
                try
                {
                    dev.SetLedStatus(0, LedStatus.On);
                }
                catch (TrustFingerException e)
                {
                    ShowErrorMessage("SetLedStatus fail,Error code:" + e.ErrorCode);
                    return;
                    //ignore 
                }
            }
        }

        private void TurnOffA600GreenLight()
        {
            if (checkBoxLED.Enabled == true && checkBoxLED.Checked == true)
            {
                try
                {
                    dev.SetLedStatus(0, LedStatus.Off);
                }
                catch(TrustFingerException e)
                {
                    ShowErrorMessage("SetLedStatus fail,Error code:" + e.ErrorCode);
                    return;
                    //ignore 
                }
            }

        }

        private void dataGridViewVerify_SelectionChanged(object sender, EventArgs e)
        {
            if(dataGridViewVerify.SelectedRows.Count>0)
            {
                DataGridViewRow selecteItem = dataGridViewVerify.SelectedRows[0];
                //int pos = int.Parse(selecteItem.Cells[5].Value?.ToString());
                //FingerPosition fingerpos = (FingerPosition)pos;
                string pos = selecteItem.Cells[5].Value?.ToString();
                var chkBts = panelVerify.Controls.OfType<CheckBox>();
                foreach(CheckBox chk in chkBts)
                {
                    chk.Checked =false;
                    if(chk.Tag.ToString()== pos)
                    {
                        chk.Checked = true; ;
                    }
                }
            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {

        }

        private void radioButtonFile_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonFile.Checked)
            {
                dataGridViewVerify.Visible = false;
                labelFileVerify.Visible = true;
                labelFileVerify.Text = $"Please click Start Verify button to select a fingerprint feature file for verification.";

                pictureBoxVerifyPreview.Image?.Dispose();
                pictureBoxVerifyPreview.Image = null;

                textBoxVerify.Text = "";
                labelSimilarity.Text = "";
                labelfingerpos.Text = "";

                verticalProgressBarVerify.Value = 0;

                pictureBoxVeriftPass.Visible = false;
                pictureBoxVerifyFail.Visible = false;

                var chkBts = panelVerify.Controls.OfType<CheckBox>();
                foreach (CheckBox chk in chkBts)
                {
                    chk.Checked = false;
                }
            }
            else
            {
                labelFileVerify.Visible = false;
                dataGridViewVerify.Visible = true;

                pictureBoxVerifyPreview.Image?.Dispose();
                pictureBoxVerifyPreview.Image = null;

                textBoxVerify.Text = "";
                labelSimilarity.Text = "";
                labelfingerpos.Text = "";

                verticalProgressBarVerify.Value = 0;

                pictureBoxVeriftPass.Visible = false;
                pictureBoxVerifyFail.Visible = false;

                if (dataGridViewVerify.SelectedRows.Count > 0)
                {
                    DataGridViewRow selecteItem = dataGridViewVerify.SelectedRows[0];
                    //int pos = int.Parse(selecteItem.Cells[5].Value?.ToString());
                    //FingerPosition fingerpos = (FingerPosition)pos;
                    string pos = selecteItem.Cells[5].Value?.ToString();
                    var chkBts = panelVerify.Controls.OfType<CheckBox>();
                    foreach (CheckBox chk in chkBts)
                    {
                        chk.Checked = false;
                        if (chk.Tag.ToString() == pos)
                        {
                            chk.Checked = true; ;
                        }
                    }
                }
            }
        }

        private void tabControlMain_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (tabControlMain.SelectedIndex)
            {
                case 0:
                    ResetCaptureTab(true,true);
                    ShowMessage("Confirm the settings and select a finger for capture.");
                    break;
                case 1:
                    ResetEnrollTab();
                    //dataGridViewEnroll.Columns[0].Visible = false;
                    ShowMessage("Fill your info and select a finger for enrollment.");
                    break;
                case 2:
                    ResetVerify();
                    //dataGridViewVerify.Columns[0].Visible = false;
                    ShowMessage("Select a user or file for verification.");
                    break;
                case 3:
                    ResetIdentifyTab();
                    ShowMessage("Confirm the settings and click Start Identify button.");
                    break;
                case 4:
                    ShowMessage("Device opened.");
                    break;
            }
        }

        private void checkBoxLED_CheckedChanged(object sender, EventArgs e)
        {
            
        }

        private void checkBoxLED_Click(object sender, EventArgs e)
        {
            if (checkBoxLED.Checked == false)
            {
                try
                {
                    dev.SetLedStatus(1, LedStatus.Off);
                }
                catch (TrustFingerException ex)
                {
                    ShowErrorMessage("SetLedStatus fail,Error code:" + ex.ErrorCode);
                    return;
                    //ignore 
                }

                try
                {
                    dev.SetLedStatus(0, LedStatus.Off);
                }
                catch (TrustFingerException ex)
                {
                    ShowErrorMessage("SetLedStatus fail,Error code:" + ex.ErrorCode);
                    return;
                    //ignore 
                }
            }
        }

        private void comboBoxLFDLevel_SelectedIndexChanged(object sender, EventArgs e)
        {
            
        }

        private void comboBoxLFDLevel_SelectionChangeCommitted(object sender, EventArgs e)
        {
            //bool eximg = checkBoxExportIMG.Checked;
            try
            {
                switch (comboBoxLFDLevel.SelectedIndex)
                {
                    case 0:
                        dev.EnableLFD(false, 3);//, false);
                        break;
                    case 1:
                        dev.EnableLFD(true, 1);//, eximg);
                        break;
                    case 2:
                        dev.EnableLFD(true, 2);//, eximg);
                        break;
                    case 3:
                        dev.EnableLFD(true, 3);//, eximg);
                        break;
                    case 4:
                        dev.EnableLFD(true, 4);//, eximg);
                        break;
                    case 5:
                        dev.EnableLFD(true, 5);//, eximg);
                        break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                ShowErrorMessage(ex.Message);

                comboBoxLFDLevel.SelectedIndex = 0;

                return;
            }
        }

        private void numericUpDownQulity_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(e.KeyChar >= '0' && e.KeyChar <= '9' ) && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
        }

        private void numericUpDownImg_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(e.KeyChar >= '0' && e.KeyChar <= '9') && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
        }

        private void numericUpDownVerify_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(e.KeyChar >= '0' && e.KeyChar <= '9') && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
        }

        private void numericUpDownIdentifyQu_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(e.KeyChar >= '0' && e.KeyChar <= '9') && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
        }

        //private void checkBoxExportIMG_CheckedChanged(object sender, EventArgs e)
        //{
        //    int i = comboBoxLFDLevel.SelectedIndex;
        //    bool ei = checkBoxExportIMG.Checked;
        //    try
        //    {
        //        if(i!=0)
        //        {
        //            dev.EnableLFD(true, i, ei);
        //        }             
        //    }catch(Exception ex)
        //    {
        //        MessageBox.Show(ex.Message);
        //        ShowErrorMessage(ex.Message);

        //        checkBoxExportIMG.Checked = !checkBoxExportIMG.Checked;
        //        return;
        //    }
        //}
    }
}
