using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsCE.Forms;
using System.Runtime.InteropServices;
using Bt.ScanLib;
using Bt;

namespace SCAN.lib
{
    class BtScanLib : MessageWindow
    {
        private static LogWriter logger = LogWriter.getInstance();
        public bool Debug { get; set; }

        //--------------------------------------------------------------
        // DLLImport
        //--------------------------------------------------------------
        [DllImport("coredll.dll", EntryPoint = "DeleteObject")]
        private static extern bool DeleteObject(IntPtr hObject);

        public event ScanEventHandler OnScan;

        private static BtScanLib btScanLib = null;

        public static BtScanLib getInstance()
        {
            if (btScanLib == null)
            {
                btScanLib = new BtScanLib();
            }

            return btScanLib;
        }

        private BtScanLib()
        {
            // Initial BT scan library
            Bt.ScanLib.Utility.btScanSetServiceEnable(0);
        }

        public void Enable()
        {
            Bt.ScanLib.Control.btScanEnable();
        }

        public void Disable()
        {
            Bt.ScanLib.Control.btScanDisable();
        }

        protected override void WndProc(ref Microsoft.WindowsCE.Forms.Message msg)
        {
            switch (msg.Msg)
            {
                case (Int32)LibDef.WM_BT_SCAN:
                    // success scan
                    if (msg.WParam.ToInt32() == (Int32)LibDef.BTMSG_WPARAM.WP_SCN_SUCCESS)
                    {
                        // scan once
                        ScanData_once();
                    }
                    break;
            }
            base.WndProc(ref msg);
        }

        /********************************************************************************
         * Function ：Get the reading code individually
         * API  ：btScanGetResultCount, btScanGetDataSize, btScanGetData, btScanGetOCRData
        **/
        private void ScanData_once()
        {

            Int32 ret = 0;
            String disp = "";

            Int32 resultCount = 0;
            Byte[] codedataGet;
            Int32 codeLen = 0;
            LibDef.BT_SCAN_REPORT stReportGet = new LibDef.BT_SCAN_REPORT();
            LibDef.BT_SCAN_QR_REPORT stQrReportGet = new LibDef.BT_SCAN_QR_REPORT();

            try
            {
                resultCount = Bt.ScanLib.Control.btScanGetResultCount();
                if (resultCount <= 0)
                {
                    disp = "btScanGetResultCount error ret[" + resultCount + "]";
                    //MessageBox.Show(disp, "Error");
                    goto L_END;
                }

                // Code read event
                if (resultCount > 0)
                {
                    //-----------------------------------------------------------
                    // Read (individual)
                    //-----------------------------------------------------------
                    for (UInt32 i = 0; i < resultCount; i++)
                    {
                        codeLen = Bt.ScanLib.Control.btScanGetDataSize(i);
                        if (codeLen <= 0)
                        {
                            disp = "btScanGetDataSize error ret[" + codeLen + "]";
                            //MessageBox.Show(disp, "Error");
                            goto L_END;
                        }
                        codedataGet = new Byte[codeLen];

                        // btScanGetData
                        stReportGet = new LibDef.BT_SCAN_REPORT();
                        stQrReportGet = new LibDef.BT_SCAN_QR_REPORT();
                        ret = Bt.ScanLib.Control.btScanGetData(i, codedataGet, ref stReportGet, ref stQrReportGet);
                        if (ret != LibDef.BT_OK)
                        {
                            disp = "btScanGetData error ret[" + ret + "]";
                            //MessageBox.Show(disp, "Error");
                            goto L_END;
                        }
                        if (stReportGet.codetype == LibDef.BT_SCAN_CODE_OCR)
                        {
                            LibDef.BT_SCAN_OCR_REPORT objOcr = new LibDef.BT_SCAN_OCR_REPORT();
                            LibDef.BT_SCAN_OCR_REPORT_IMAGE objOcrImg = new LibDef.BT_SCAN_OCR_REPORT_IMAGE();
                            ret = Bt.ScanLib.Control.btScanGetOCRData(ref objOcr, ref objOcrImg);
                            if (ret != LibDef.BT_OK)
                            {
                                disp = "btScanGetOCRData error";
                                //MessageBox.Show(disp, "Error");
                                DeleteObject(objOcrImg.bitmap);
                                goto L_END;
                            }
                            string strAtt = "";
                            for (UInt32 j = 0; j < objOcr.SourceDataLen; j++)
                            {
                                strAtt = strAtt + objOcr.CharAttention[j];
                            }
                            string result = System.Text.Encoding.ASCII.GetString(codedataGet, 0, codedataGet.Length);
                            disp =
                                "OCR recognition pattern:" + objOcr.DataFormat + "\r\n" +
                                 "Misidentification alert information:" + objOcr.AlertType + "\r\n" +
                                 "Format registration number:" + objOcr.FormatNumber + "\r\n" +
                                 "Recognized string length:" + objOcr.SourceDataLen + "\r\n" +
                                 "Recognized string:" + System.Text.Encoding.ASCII.GetString (objOcr.SourceData, 0, (int) (objOcr.SourceDataLen)) + "\r\n" +
                                 "Character credit information:" + strAtt + "\r\n";
                            //MessageBox.Show(disp, "Read (individual)");
                            if (Debug) logger.Log(disp);
                            DeleteObject(objOcrImg.bitmap);

                            OnScan(result);
                            /*
                            if (Form_Login._Form_LoginInstance.ScanMode == 0 && Form_Login._Form_LoginInstance.ScanStep != 0)
                            {
                                setText(Form_Login._Form_LoginInstance.ScanMode, Form_Login._Form_LoginInstance.ScanStep, result);

                            }
                            else
                            {
                                
                            }
                             * */
                            


                        }
                        else
                        {//Successful barcode reading
                            string result = System.Text.Encoding.ASCII.GetString(codedataGet, 0, codedataGet.Length);
                            disp =
                                "Data size:" + codeLen + "\r\n" +
                                "[Report] \r\n" +
                                "Number of digits:" + stReportGet.keta + "\r\n" +
                                "result:" + result + "\r\n" +
                                "Code type:" + stReportGet.codetype + "\r\n" +
                                "Is it a composite:" + stReportGet.composite + "\r\n" +
                                "Quality:" + stReportGet.quality + "\r\n" +
                                "Details:" + stReportGet.extraType + "\r\n" +
                                "Code synthesis:" + stReportGet.codelink + "\r\n" +
                                "[QR] \r\n" +
                                "Read result position:" + stQrReportGet.pos + "\r\n" +
                                "Parity:" + stQrReportGet.parity + "\r\n" +
                                "Total number of concatenations:" + stQrReportGet.count + "\r\n";
                            //MessageBox.Show(disp, "Read (individual)");
                            if (Debug) logger.Log(disp);
                            //setText(Form_Login._Form_LoginInstance.ScanMode, Form_Login._Form_LoginInstance.ScanStep, result);

                            OnScan(result);

                        }
                    }
                }

            L_END:
                ret = Bt.ScanLib.Control.btScanDisable();
                if (ret != LibDef.BT_OK)
                {
                    disp = "btScanDisable error ret[" + ret + "]";
                    //MessageBox.Show(disp, "Error");
                    //MessageBox.Show("Please try again.", "Scan Error");
                }

                ret = Bt.ScanLib.Control.btScanEnable();
                if (ret != LibDef.BT_OK)
                {
                    disp = "btScanEnable error ret[" + ret + "]";
                    //MessageBox.Show(disp, "Error");
                    //MessageBox.Show("Please try again.", "Scan Error");
                }
            }
            catch (MissingMethodException)
            {
                //MessageBox.Show("Contains APIs that cannot be used with this terminal.");
                //MessageBox.Show("Please try again.", "Scan Error");
            }
            catch (Exception e)
            {
                //MessageBox.Show(e.Message + ", Please try again.", "Scan Error");
                //MessageBox.Show(ex.ToString());

                //Call ErrorForm.cs here.
                //ErrorForm err = new ErrorForm();
                //err.Show(); 

            }
        }

        /********************************************************************************
         * Function: Get the reading code at once.
         * API  ：btScanGetStringSize, btScanGetString
        **/
        private void ScanData_bulk()
        {

            Int32 ret = 0;
            String disp = "";

            Byte[] codedataGet;
            String strCodedata = "";
            Int32 codeLen = 0;
            UInt16 symbolGet = 0;

            try
            {
                //-----------------------------------------------------------
                // 読み取り(一括)
                //-----------------------------------------------------------
                codeLen = Bt.ScanLib.Control.btScanGetStringSize();
                if (codeLen <= 0)
                {
                    disp = "btScanGetStringSize error ret[" + codeLen + "]";
                   // MessageBox.Show(disp, "Error");
                    goto L_END;
                }
                codedataGet = new Byte[codeLen];

                ret = Bt.ScanLib.Control.btScanGetString(codedataGet, ref symbolGet);
                if (ret != LibDef.BT_OK)
                {
                    disp = "btScanGetString error ret[" + ret + "]";
                   // MessageBox.Show(disp, "Error");
                    goto L_END;
                }
                strCodedata = System.Text.Encoding.GetEncoding(932).GetString(codedataGet, 0, codeLen);
                disp =
                    "Code length    :" + codeLen + "\r\n" +
                    "Symbol     :" + symbolGet + "\r\n" +
                    "Code data :" + strCodedata + "\r\n";
              //  MessageBox.Show(disp, "Read (Batch)");

            L_END:
                ret = Bt.ScanLib.Control.btScanDisable();
                if (ret != LibDef.BT_OK)
                {
                    disp = "btScanDisable error ret[" + ret + "]";
                 //   MessageBox.Show(disp, "Error");
                }
            }
            catch (Exception e)
            {
               // MessageBox.Show(e.ToString());
            }
        }
    }

    public delegate void ScanEventHandler(string result);
}
