using lib;
using Packing.lib.datasource;
using lib.model;
using Packing.lib;
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Threading.Tasks;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
using System.Linq;
using System.Drawing;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
using System.Security.Cryptography.X509Certificates;
using Packing.Properties;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using System.Drawing.Printing;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using System.Reflection.Emit;
using System.Drawing.Drawing2D;
using Patagames.Pdf.Net;
using Patagames.Pdf.Net.Controls.WinForms;
using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Pdf;
using PdfSharp.Pdf.Printing;
using TheArtOfDev.HtmlRenderer.PdfSharp;
using System.Diagnostics;
using System.Threading;
using Patagames.Pdf;

namespace Packing
{
    public partial class Form1 : Form
    {
        protected LogWriter logger = LogWriter.getInstance();
        const string INI = "Packing.ini";
        const string WORKING_JSON = "working.json";
        const string DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

        String log_dir = "";        
        public static Form _form;
        public static WorkerNoDs worker;
        public static WorkingState workingState;
        public static IniFile ini = new IniFile(INI);
        private static char delimiter = ini.Read("Delimiter", "Reader").ToCharArray()[0];

        private static bool isPreviousProcessCheck = ini.Read("OnOff", "PreviousProcessCheck") == "1" ? true : false;
        private static int MAXIMUM_SCAN = 0;
        private Dictionary<string, List<string>> previousProcessCheckList = new Dictionary<string, List<string>>();

        private System.Drawing.Printing.PrintDocument printDocument;
        private string printBuffer;
        private string printerName;
        private string qty;
        private string pdfPath;
        TextProcessing textProcessing;
        string selected_preset;
        private List<List<string>> Settings = new List<List<string>>();


        public Form1()
        {
            InitializeComponent();

            this.printDocument = new System.Drawing.Printing.PrintDocument();
            this.printDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.ThePrintDocument_PrintLabel);

            //Initialize text processing
            string input_format = ini.Read("input", selected_preset);
            //char delimiter = ini.Read("Delimiter", null).ToCharArray()[0];
            textProcessing = new TextProcessing(input_format, delimiter);

        }

        protected void ThePrintDocument_PrintLabel(object sender, System.Drawing.Printing.PrintPageEventArgs ev)
        {
            SolidBrush myBrush = new SolidBrush(Color.Black);

            string strwidth = ini.Read("width", selected_preset);
            string strheight = ini.Read("height", selected_preset);
            Int32 Intwidth = Convert.ToInt32(strwidth);
            Int32 Intheight = Convert.ToInt32(strheight);

            //HTML render
            Image image = TheArtOfDev.HtmlRenderer.WinForms.HtmlRender.RenderToImage(printBuffer);

            ev.Graphics.CompositingQuality = CompositingQuality.HighQuality;
            ev.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            ev.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

            Rectangle rect = new Rectangle(0, 0, Intwidth, Intheight); // (0, 0, Wide, High)

            ev.Graphics.DrawImage(image, rect);

            ev.HasMorePages = false;

            myBrush.Dispose();
        }

        private void printToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                printDocument.PrinterSettings.PrinterName = printerName;
                printDocument.Print();
            }
            catch (Exception exp)
            {
                System.Console.WriteLine(exp.Message.ToString());
            }
        }

        public void init(object sender, EventArgs e)
        {
            showLog("DB connecting...");
            this.Refresh();

            // Log in
            btnChangeWorker_Click_1(sender, e);
            txtLeakTestCode.Text = "";
            new Action(
                    async () => MAXIMUM_SCAN = await GetMaximumScan(lblReaderNo.Text)
                )();

            // Load previous process check
            if (isPreviousProcessCheck)
            {
                string[] part_no_ = ini.Read("part_no", "PreviousProcessCheck").ToString().Split(',');
                foreach (string part in part_no_)
                {
                    previousProcessCheckList.Add(part, new List<string>(
                        ini.Read(part, "PreviousProcessCheck").ToString().Split(',')
                        )
                    );
                }
            }

            // Load & setup screen the current working
            workingState = WorkingState.Load(WORKING_JSON);

            btnPackingStart_Click_1(sender, e);

            updateView();

            showLog("DB connection established.");
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _form = this;
           
            qty = "1";
            pdfPath = "C:\\Program Files\\Adobe\\Acrobat DC\\Acrobat\\Acrobat.exe";

            // Initialize
            lblReaderNo.Text = ini.Read("ReaderNo", "Reader").ToString();
            log_dir = ini.Read("Log", "Folder").ToString();
            pdfPath = ini.Read("PDF", "Packing").ToString();

            if (log_dir.Length > 0)
            {
                logger.setLogDir(log_dir);
                logger.setAppendDate(true);
            }

            logger.Log("Application start.");

            //btnPackingStart_Click_1(sender,e);

        }

        private async Task<int> GetMaximumScan(string reader_no)
        {
            string sql = @"SELECT Packing_Pcs FROM tblReaderMst WHERE Reader_No=" + reader_no;
            List<object[]> rows = await (new DbTable()).executeQueryAsync(sql);
            int ret = 0;
            if (rows.Count > 0)
            {
                ret = (int)rows[0][0];
            }

            lblMaximumScan.Text = ret.ToString();
           
            return ret;
        }

        private void btnChangeWorker_Click_1(object sender, EventArgs e)
        {
            setWorkerName();

            
        }

        public void setWorkerName()
        {
            WorkerSelectFrm workerSelectFrm = new WorkerSelectFrm(worker != null);
            workerSelectFrm.ShowDialog(this);

            if (worker != null)
            {
                lblWorkerName.Text = worker.Name;
                showLog("Worker selected => " + worker.Name);
            }
        }

        private void updateView()
        {
            lblPalletNo.Text = workingState.pallet_no;
            lblPackingCount.Text = workingState.scan_count;
            lblPartNo.Text = workingState.part_code;
            lblPartName.Text = workingState.part_name;
            lblAbbreviation.Text = workingState.abbreviation;
            lblPartNoCheck.Text = workingState.part_no;
            leakTestCodeBindingSource.Clear();

            int scan_count = Convert.ToInt32(workingState.scan_count);
            int step = Convert.ToInt32(workingState.step);

            if (step == 1)
            {
                if (!btnPackingEnd.Enabled)
                {
                    txtInformation.Text = "Push [Packing Start].";
                }
                else
                {
                    txtInformation.Text = "Read Pallet code.";
                }
                dataGridLeakTestNoList.DataSource = null; // Clear an old one
                dataGridLeakTestNoList.DataSource = new List<LeakTestCodeDs>();
            }
            else
            {
                if (!btnPackingEnd.Enabled)
                {
                    txtInformation.Text = "Push [Packing Start].";
                }
                else
                {
                    if (scan_count < MAXIMUM_SCAN)
                    {
                        txtInformation.Text = "Read Code (or Push [Packing End]).";
                    }
                    else
                    {
                        txtInformation.Text = "Push [Packing End].";
                    }
                }

                LeakTestCodeDs.list = new List<LeakTestCodeDs>();
                string[] leaktest_code_ = workingState.leaktest_code.Split(delimiter);
                string[] packing_time_ = workingState.packing_time.Split(delimiter);
                string[] serial_no_ = workingState.serial_no.Split(delimiter);

                for (int i = 0; i < scan_count; i++)
                {
                    LeakTestCodeDs leakTestCodeDs = new LeakTestCodeDs(
                            (i + 1).ToString()
                            , leaktest_code_[i]
                            , packing_time_[i]
                            , serial_no_[i]
                            , false // Manual check traceability data
                            );
                    leakTestCodeDs.OnFinishedGetRelatedTraceabilityData += LeakTestCodeDs_OnFinishedQueryLeakTestCode;

                    LeakTestCodeDs.list.Add(leakTestCodeDs);
                }

                dataGridLeakTestNoList.DataSource = null; // Clear an old one
                dataGridLeakTestNoList.DataSource = LeakTestCodeDs.list;

            }

        }

        private void LeakTestCodeDs_OnFinishedQueryLeakTestCode(LeakTestCodeDs leakTestCodeDs)
        {
            // Update to Ini
            WorkingState.Save(workingState, WORKING_JSON);

            LeakTestCodeDs.list.Add(leakTestCodeDs);
            dataGridLeakTestNoList.DataSource = null; // Clear an old one
            dataGridLeakTestNoList.DataSource = LeakTestCodeDs.list;
        }

        private void LeakTestCodeDs_OnFinishedQueryLeakTestCode_PreviousProcessCheck(LeakTestCodeDs leakTestCodeDs)
        {
            List<object[]> rows = leakTestCodeDs.RelatedTraceabilityDataList;

            // Update to Ini
            WorkingState.Save(workingState, WORKING_JSON);

            LeakTestCodeDs.list.Add(leakTestCodeDs);
            dataGridLeakTestNoList.DataSource = null; // Clear an old one
            dataGridLeakTestNoList.DataSource = LeakTestCodeDs.list;
        }

        private void resetState()
        {
            workingState.pallet_no = "";
            workingState.scan_count = "0";
            workingState.step = "1";
            string tmp = "";
            for (int i = 0; i < MAXIMUM_SCAN - 1; i++)
            {
                tmp += delimiter.ToString();
            }
            workingState.leaktest_code = tmp;
            workingState.packing_time = tmp;
            workingState.serial_no = tmp;

            workingState.part_name = "";
            workingState.part_code = "";
            workingState.abbreviation = "";
            workingState.part_no = "";

        }

        private void txtLeakTestCode_KeyDown_1(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                logger.Info("Scan input : " + txtLeakTestCode.Text.ToString());

                /**
                 * "There are 3 conditions to check below.
                    1. First step for pallet no scan. It is 9 digits.
                    2. Scan item 19 digits for leaktest code on step 2.
                    3. Check the previous process for each part_no. It has been config in INI file.

                */
                try
                {
                    switch (workingState.step)
                    {
                        case "1":
                            if (txtLeakTestCode.Text.ToString().Length != 9)
                            {
                                Form ngFrm = new NgFrm("Not 9 digits for Pallet No.", txtLeakTestCode.Text.ToString());
                                ngFrm.ShowDialog();
                                return;
                            }
                            else
                            {
                                string tmp = "";
                                //for (int i = 0; i < MAXIMUM_SCAN - 1; i++)
                                //{
                                //    tmp += delimiter.ToString();
                                //}

                                for (int i = 0; i < 47; i++)
                                {
                                    tmp += delimiter.ToString();
                                }

                                workingState.pallet_no = txtLeakTestCode.Text.ToString();
                                workingState.step = "2";
                                workingState.scan_count = "0";
                                workingState.leaktest_code = tmp;
                                workingState.packing_time = tmp;
                                workingState.serial_no = tmp;

                                workingState.part_name = "";
                                workingState.part_code = "";
                                workingState.abbreviation = "";
                                workingState.part_no = "";

                                WorkingState.Save(workingState, WORKING_JSON);
                                updateView();

                                showLog("Pallet number set => " + txtLeakTestCode.Text.ToString());
                            }
                            break;

                        case "2":
                            
                            if (txtLeakTestCode.Text.ToString().Length != 19)
                            {
                                Form ngFrm = new NgFrm("Not 19 digits for QR Code.", txtLeakTestCode.Text.ToString());
                                ngFrm.ShowDialog();
                                return;
                            }
                            else
                            {
                                int scan_count = Convert.ToInt32(workingState.scan_count);
                                if (scan_count >= MAXIMUM_SCAN)
                                {
                                    Form ngFrm = new NgFrm("Reached the maximum scan.", "");
                                    ngFrm.ShowDialog();
                                    return;
                                }

                                // Change upper case letters
                                txtLeakTestCode.Text = txtLeakTestCode.Text.ToUpper();

                                LeakTestCodeDs leakTestCodeDs = new LeakTestCodeDs(
                                    (scan_count + 1).ToString(), txtLeakTestCode.Text, null, null, false
                                    );


                                // Check duplicated insert
                                if (LeakTestCodeDs.list.Contains(leakTestCodeDs))
                                {
                                    Form ngFrm = new NgFrm("Duplicated NG.", txtLeakTestCode.Text);
                                    ngFrm.ShowDialog();
                                    return;
                                }


                                // Call foreground process
                                List<object[]> rows_tr_data = leakTestCodeDs.GetRelatedTraceabilityData();
                                if (leakTestCodeDs.SerialNo == null || leakTestCodeDs.SerialNo == string.Empty)
                                {
                                    Form ngFrm = new NgFrm("No traceability data NG!!", "Serial number not found.");
                                    ngFrm.ShowDialog();
                                    return;
                                }


                                //string part_no = txtLeakTestCode.Text.ToString().Substring(4, 2);

                                string part_no = "32";

                                if (lblPartNoCheck.Text != string.Empty)
                                {
                                    if (lblPartNoCheck.Text != part_no)
                                    {
                                        Form ngFrm = new NgFrm("Part No NG!!", "Part No not match.");
                                        ngFrm.ShowDialog();
                                        return;
                                    }
                                }

                                List<object[]> rows_Mst_data = leakTestCodeDs.GetRelatedMstData(part_no);

                                if (leakTestCodeDs.PartName == null || leakTestCodeDs.PartName == string.Empty)
                                {
                                    Form ngFrm = new NgFrm("No master data NG!!", "Part Name not found.");
                                    ngFrm.ShowDialog();
                                    return;
                                }
                                if (leakTestCodeDs.PartCode == null || leakTestCodeDs.PartCode == string.Empty)
                                {
                                    Form ngFrm = new NgFrm("No master data NG!!", "Part Code not found.");
                                    ngFrm.ShowDialog();
                                    return;
                                }
                                if (leakTestCodeDs.Abbreviation == null || leakTestCodeDs.Abbreviation == string.Empty)
                                {
                                    Form ngFrm = new NgFrm("No master data NG!!", "Abbreviation not found.");
                                    ngFrm.ShowDialog();
                                    return;
                                }

                                if (isPreviousProcessCheck)
                                {
                                    //part_no = txtLeakTestCode.Text.ToString().Substring(4, 2);

                                    part_no = "32";

                                    List<string> proceeds = new List<string>();
                                    // Convert rows to proceeds list
                                    foreach (object[] cols in rows_tr_data)
                                    {
                                        proceeds.Add(string.Format("{0}", (int)cols[1]));
                                    }

                                    bool isProcessCheckPass = true;
                                    List<string> need_to_check_process_no = new List<string>();
                                    previousProcessCheckList.TryGetValue(part_no, out need_to_check_process_no);
                                    foreach (string p_check in need_to_check_process_no)
                                    {
                                        if (!proceeds.Contains(p_check))
                                        {
                                            isProcessCheckPass = false;
                                            break;
                                        }
                                    }

                                    if (!isProcessCheckPass)
                                    {
                                        Form ngFrm = new NgFrm("Previous process check failed.", txtLeakTestCode.Text.ToString());
                                        ngFrm.ShowDialog();
                                        return;
                                    }
                                }

                                // update workingState and updateView
                                scan_count++;
                                workingState.scan_count = (scan_count).ToString();
                                string[] leaktest_code_ = workingState.leaktest_code.Split(delimiter);
                                string[] packing_time_ = workingState.packing_time.Split(delimiter);
                                string[] serial_no_ = workingState.serial_no.Split(delimiter);
                                packing_time_[scan_count - 1] = DateTime.Now.ToString(DATETIME_FORMAT);
                                leaktest_code_[scan_count - 1] = txtLeakTestCode.Text.ToString();
                                serial_no_[scan_count - 1] = leakTestCodeDs.SerialNo;
                                workingState.leaktest_code = string.Join(delimiter.ToString(), leaktest_code_);
                                workingState.packing_time = string.Join(delimiter.ToString(), packing_time_);
                                workingState.serial_no = string.Join(delimiter.ToString(), serial_no_);
                                workingState.part_name = leakTestCodeDs.PartName;
                                workingState.part_code = leakTestCodeDs.PartCode;
                                workingState.abbreviation = leakTestCodeDs.Abbreviation;
                                workingState.part_no = leakTestCodeDs.PartNo;

                                WorkingState.Save(workingState, WORKING_JSON);
                                updateView();

                                showLog("Leak test code read => " + txtLeakTestCode.Text.ToString());

                            }
                            break;
                    }
                }
                finally
                {
                    // reset text box for new data input
                    txtLeakTestCode.Text = string.Empty;
                }
            }
        }

        private void btnClearList_Click_1(object sender, EventArgs e)
        {
            var confirmResult = MessageBox.Show("Are you sure to clear the list ??",
                                     "Confirm Clear!!",
                                     MessageBoxButtons.YesNo);
            if (confirmResult == DialogResult.Yes)
            {
                resetState();

                btnPackingStart_Click_1(sender, e);

                WorkingState.Save(workingState, WORKING_JSON);
                updateView();

                showLog("Clear list.");
            }
        }

        private void btnCancel_Click_1(object sender, EventArgs e)
        {
            var confirmResult = MessageBox.Show("Are you sure to clear the last scan data??",
                                     "Confirm Clear!!",
                                     MessageBoxButtons.YesNo);
            if (confirmResult == DialogResult.Yes)
            {
                int scan_count = Convert.ToInt32(workingState.scan_count);
                int step = Convert.ToInt32(workingState.step);
                if (scan_count > 0 && step == 2)
                {
                    string[] leaktest_code_ = workingState.leaktest_code.Split(delimiter);
                    string[] packing_time_ = workingState.packing_time.Split(delimiter);
                    string[] serial_no_ = workingState.serial_no.Split(delimiter);
                    packing_time_[scan_count - 1] = "";
                    leaktest_code_[scan_count - 1] = "";
                    serial_no_[scan_count - 1] = "";
                    workingState.leaktest_code = string.Join(delimiter.ToString(), leaktest_code_);
                    workingState.packing_time = string.Join(delimiter.ToString(), packing_time_);
                    workingState.serial_no = string.Join(delimiter.ToString(), serial_no_);
                    workingState.scan_count = (--scan_count).ToString();
                    if (scan_count == 0)
                    {
                        workingState.step = "1";
                    }
                }
                else
                {
                    workingState.pallet_no = "";
                    workingState.step = "1";
                    lblPalletNo.Text = "";

                    workingState.part_name = "";
                    workingState.part_code = "";
                    workingState.abbreviation = "";
                    workingState.part_no = "";

                }

                WorkingState.Save(workingState, WORKING_JSON);
                updateView();

                showLog("Removed last scan.");


            }
        }

        private void btnClose_Click_1(object sender, EventArgs e)
        {
            this.Close();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {

            if (CloseCancel() == false)
            {
                e.Cancel = true;
            };
        }

        public static bool CloseCancel()
        {
            const string message = "Are you sure that you would like to close the application?";
            const string caption = "Close application";
            var result = MessageBox.Show(message, caption,
                                         MessageBoxButtons.YesNo,
                                         MessageBoxIcon.Question);

            if (result == DialogResult.Yes)
                return true;
            else
                return false;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {

            logger.Log("Application end.");
        }

        private void btnPackingStart_Click(object sender, EventArgs e)
        {

        }

        private void btnPackingEnd_Click_1(object sender, EventArgs e)
        {
            string strTableShow = string.Empty;
            Double dblPage = 0;
            int intRowCount = 0;
            int intRowStart = 0;
            int scan_count = Convert.ToInt32(workingState.scan_count);
            int step = Convert.ToInt32(workingState.step);
            if (scan_count == 0 || step == 1)
            {
                NgFrm ngFrm = new NgFrm("Register Packing Data NG", "");
                ngFrm.ShowDialog();

                return;
            }


            // Insert packed item to DB server
            List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
            TblPackingData tblPackingData = new TblPackingData();



            var confirmResult = MessageBox.Show("Are you sure to ending the packing item??",
                                     "Confirm Ending!!",
                                     MessageBoxButtons.YesNo);
            if (confirmResult == DialogResult.Yes)
            {
                Cursor = Cursors.WaitCursor;
                showLog("Packing end.");
                Dictionary<string, object> cols = new Dictionary<string, object>();

                LeakTestCodeDs.PrintPalletSerialNo = lblReaderNo.Text + lblPartNoCheck.Text + DateTime.Now.ToString("ddMMyy")
                    + DateTime.Now.ToString("HHmm");

                lblPalletNo.Text = LeakTestCodeDs.PrintPalletSerialNo;

                cols["Reader_No"] = Convert.ToInt32(lblReaderNo.Text.ToString());
                cols["Pallet_No"] = lblPalletNo.Text.ToString();
                foreach (LeakTestCodeDs item in LeakTestCodeDs.list)
                {
                    if (item.LeakTestCode.ToString().Trim() != string.Empty)
                    {
                        cols["Packing_Time"] = item.PackingTime;
                        cols["Box_Index"] = Convert.ToInt32(item.Box_Id);
                        cols["Serial_No"] = item.SerialNo.ToString().Trim();
                        cols["LeakTest_Code"] = item.LeakTestCode.ToString();
                        cols["Packing_Worker_No"] = Convert.ToInt32(worker.Id);

                        int ret = tblPackingData.add(cols);
                        if (ret > 0)
                        {
                            showLog(String.Format("Data inserted => {0}.", item.LeakTestCode.ToString()));
                        }
                        else
                        {
                            // try to update with new Read_Time
                            Dictionary<string, object> cols_update = new Dictionary<string, object>();
                            cols_update["Serial_No"] = item.SerialNo.ToString().Trim();
                            cols_update["LeakTest_Code"] = item.LeakTestCode.ToString();
                            cols_update["Packing_Worker_No"] = worker.Id;
                            ret = tblPackingData.set(cols_update,
                                string.Format("Reader_No={0} AND Pallet_No='{1}' AND Packing_Time='{2}' AND Box_Index={3}",
                                    lblReaderNo.Text.ToString(),
                                    lblPalletNo.Text.ToString(),
                                    item.PackingTime.ToString(DATETIME_FORMAT),
                                    item.Box_Id
                                    )
                                );
                            if (ret > 0)
                            {
                                showLog(String.Format("Data updated => {0}.", item.LeakTestCode.ToString()));
                            }
                            else
                            {
                                showLog(String.Format("Data insert failed => {0}.", item.LeakTestCode.ToString()));
                            }
                        }
                    }
                }

                //LeakTestCodeDs.PrintPalletSerialNo = lblReaderNo.Text + lblPartNoCheck.Text + DateTime.Now.ToString("ddMMyy")
                //    + DateTime.Now.ToString("HHmm");


                Dictionary<string, object> colsHistoryPrint = new Dictionary<string, object>();
                TblHistoryPrint tblHistoryPrint = new TblHistoryPrint();

                colsHistoryPrint["Pallet_Serial_No"] = LeakTestCodeDs.PrintPalletSerialNo;
                colsHistoryPrint["Print_Date"] = DateTime.Now;//.ToString("yyyy-MM-dd HH:mm:ss");
                colsHistoryPrint["Part_No"] = Convert.ToInt32(lblPartNoCheck.Text);
                colsHistoryPrint["Part_Code"] = lblPartNo.Text;
                colsHistoryPrint["Part_Name"] = lblPartName.Text;
                colsHistoryPrint["Abbreviation"] = lblAbbreviation.Text;
                colsHistoryPrint["Serial_No"] = workingState.serial_no;
                LeakTestCodeDs.PrintInspectionDate = DateTime.Now.ToString("yyyy-MM-dd");
                colsHistoryPrint["Inspection_Date"] = LeakTestCodeDs.PrintInspectionDate;
                LeakTestCodeDs.PrintQty = lblPackingCount.Text + " pcs";
                colsHistoryPrint["Qty"] = LeakTestCodeDs.PrintQty;
                colsHistoryPrint["User_Name"] = lblWorkerName.Text;

                int ret1 = tblHistoryPrint.add(colsHistoryPrint);

                LeakTestCodeDs.PrintInspectionDate = LeakTestCodeDs.PrintInspectionDate.Substring(8, 2) + "/" +
                    LeakTestCodeDs.PrintInspectionDate.Substring(5, 2) + "/" + LeakTestCodeDs.PrintInspectionDate.Substring(0, 4);
                

                    //-----------------------New----------------------------//
                    string[] arrayAbbreviation;
                    string strAbbreviation1 = string.Empty;
                    string strAbbreviation2 = string.Empty;
                    string strAbbreviation3 = string.Empty;
                    string[] arraySerial_no = new string[48];
                    string strSerial_no011 = string.Empty;
                    string strSerial_no012 = string.Empty;
                    string strSerial_no013 = string.Empty;
                    
                    arrayAbbreviation = lblAbbreviation.Text.Split('/');

                    if (arrayAbbreviation.Length == 3)
                    {
                        strAbbreviation1 = arrayAbbreviation[0];
                        strAbbreviation2 = arrayAbbreviation[1];
                        strAbbreviation3 = arrayAbbreviation[2];
                    }
                    else if (arrayAbbreviation.Length == 2)
                    {
                        strAbbreviation1 = arrayAbbreviation[0];
                        strAbbreviation2 = arrayAbbreviation[1];
                        strAbbreviation3 = string.Empty;
                    }
                    else if (arrayAbbreviation.Length == 1)
                    {
                        strAbbreviation1 = arrayAbbreviation[0];
                        strAbbreviation2 = string.Empty;
                        strAbbreviation3 = string.Empty;
                    }

                    arraySerial_no = workingState.serial_no.Split('|');

                    
                        strSerial_no011 = arraySerial_no[0];
                        strSerial_no012 = arraySerial_no[1];
                        strSerial_no013 = arraySerial_no[2];
                        

                    if (strSerial_no011.Trim().Length == 0)
                    {
                        strSerial_no011 = " color:White;\">_________________";
                    }
                    else
                    {
                        strSerial_no011 = " \">" + arraySerial_no[0];
                    }

                    if (strSerial_no012.Trim().Length == 0)
                    {
                        if (strSerial_no011.Trim().Length == 19)
                        {
                            strSerial_no012 = " color:White;\">_________________";
                        }
                        else
                        {
                            strSerial_no012 = " color:White;\">________________";
                        }
                            
                    }
                    else
                    {
                        strSerial_no012 = " \">" + arraySerial_no[1];
                    }

                    if (strSerial_no013.Trim().Length == 0)
                    {
                        if (strSerial_no011.Trim().Length == 19)
                        {
                            strSerial_no013 = " color:White;\">_________________";
                        }
                        else
                        {
                            strSerial_no013 = " color:White;\">________________";
                        }
                    }
                    else
                    {
                        strSerial_no013 = " \">" + arraySerial_no[2];
                    }


                    printLabel(sender, e, LeakTestCodeDs.PrintPalletSerialNo + "|" + lblPartNo.Text.ToString() + "|" + lblPartName.Text.ToString() + "|"
                        + LeakTestCodeDs.PrintInspectionDate + "|" + LeakTestCodeDs.PrintQty + "|" + strAbbreviation1 + "|"
                        + strAbbreviation2 + "|" + strAbbreviation3 + "|" + lblWorkerName.Text + "|"
                        + strSerial_no011 + "|" + strSerial_no012 + "|" + strSerial_no013 + "|"
                        + arraySerial_no[3] + "|" + arraySerial_no[4] + "|" + arraySerial_no[5] + "|"
                        + arraySerial_no[6] + "|" + arraySerial_no[7] + "|" + arraySerial_no[8] + "|"
                        + arraySerial_no[9] + "|" + arraySerial_no[10] + "|" + arraySerial_no[11] + "|"
                        + arraySerial_no[12] + "|" + arraySerial_no[13] + "|" + arraySerial_no[14] + "|"
                        + arraySerial_no[15] + "|" + arraySerial_no[16] + "|" + arraySerial_no[17] + "|"
                        + arraySerial_no[18] + "|" + arraySerial_no[19] + "|" + arraySerial_no[20] + "|"
                        + arraySerial_no[21] + "|" + arraySerial_no[22] + "|" + arraySerial_no[23] + "|"
                        + arraySerial_no[24] + "|" + arraySerial_no[25] + "|" + arraySerial_no[26] + "|"
                        + arraySerial_no[27] + "|" + arraySerial_no[28] + "|" + arraySerial_no[29] + "|"
                        + arraySerial_no[30] + "|" + arraySerial_no[31] + "|" + arraySerial_no[32] + "|"
                        + arraySerial_no[33] + "|" + arraySerial_no[34] + "|" + arraySerial_no[35] + "|"
                        + arraySerial_no[36] + "|" + arraySerial_no[37] + "|" + arraySerial_no[38] + "|"
                        + arraySerial_no[39] + "|" + arraySerial_no[40] + "|" + arraySerial_no[41] + "|"
                        + arraySerial_no[42] + "|" + arraySerial_no[43] + "|" + arraySerial_no[44] + "|"
                        + arraySerial_no[45] + "|" + arraySerial_no[46] + "|" + arraySerial_no[47]
                    );

                // Reset view
                resetState();
              
                WorkingState.Save(workingState, WORKING_JSON);
                updateView();


                btnPackingEnd.Enabled = false;
                txtLeakTestCode.Enabled = false;
                btnCancel.Enabled = false;
                btnClearList.Enabled = false;

                btnPackingStart.Enabled = true;

                Cursor = Cursors.Default;

                btnPackingStart_Click_1(sender, e);
            }

        }

        private void printLabel(object sender, EventArgs e, string strprintBuffer)
        {
            //ini.Write("printer", printerName, selected_preset);
            printerName = ini.Read("printer", selected_preset);
            qty = ini.Read("qty", selected_preset);
            //ini.Write("template", System.IO.Directory.GetCurrentDirectory() + "\\Template-Packing.html", selected_preset);
            //ini.Write("width", "800", selected_preset);
            //ini.Write("height", "2000", selected_preset);

            //Print Label
            if (setContentPrintBuffer(strprintBuffer))
            {
                var config = new PdfGenerateConfig();
                config.PageOrientation = PageOrientation.Landscape;
                config.PageSize = PageSize.A4;

                PdfSharp.Pdf.PdfDocument pdf = PdfGenerator.GeneratePdf(printBuffer, config);
                pdf.Save("document_new.pdf");

                PrintPdf();

                //printDocument.PrinterSettings.PrinterName = this.printerName;
                //printDocument.PrinterSettings.Copies = Convert.ToInt16(qty);
                //printDocument.DefaultPageSettings.Landscape = true;
                //printDocument.Print();
            }
        }

        public void PrintPdf()
        {
            //var doc = Patagames.Pdf.Net.PdfDocument.Load("document_new.pdf");
            //var printDoc = new PdfPrintDocument(doc);
            //PrintController printController = new StandardPrintController();
            //printDoc.PrintController = printController;
            //printDoc.PrinterSettings.PrinterName = this.printerName;
            //printDoc.PrinterSettings.Copies = Convert.ToInt16(qty);
            //printDoc.DefaultPageSettings.Landscape = true;
            //printDoc.Print(); // Print PDF document
            //doc.Dispose();

            PdfFilePrinter.AdobeReaderPath = pdfPath;
      //= @"C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe";
            //PdfFilePrinter.DefaultPrinterName = this.printerName;           
            PdfFilePrinter printer = new PdfFilePrinter("document_new.pdf");
            printer.PrinterName = this.printerName;

            for (int i = 0; i < Convert.ToInt16(qty); i++)
            {
                
                printer.Print(5000);


            }


            Thread.Sleep(6000);

            FindAndKillProcess("Acrobat");


        }

        public bool FindAndKillProcess(string name)
        {
            //here we're going to get a list of all running processes on
            //the computer
            foreach (Process clsProcess in Process.GetProcesses())
            {
                //now we're going to see if any of the running processes
                //match the currently running processes by using the StartsWith Method,
                //this prevents us from incluing the .EXE for the process we're looking for.
                //. Be sure to not
                //add the .exe to the name you provide, i.e: NOTEPAD,
                //not NOTEPAD.EXE or false is always returned even if
                //notepad is running
                //if (clsProcess.ProcessName.StartsWith(name))
                    if (clsProcess.ProcessName.Contains(name))
                    {
                    //since we found the proccess we now need to use the
                    //Kill Method to kill the process. Remember, if you have
                    //the process running more than once, say IE open 4
                    //times the loop thr way it is now will close all 4,
                    //if you want it to just close the first one it finds
                    //then add a return; after the Kill
                    clsProcess.Kill();
                    //process killed, return true
                    return true;
                }
            }
            //process not found, return false
            return false;
        }

        private void printPriviewLabel(object sender, EventArgs e, string strprintBuffer)
        {
            ini.Write("printer", printerName, selected_preset);
            ini.Write("template", System.IO.Directory.GetCurrentDirectory() + "\\Template-Packing.html", selected_preset);
            ini.Write("width", "800", selected_preset);
            ini.Write("height", "2000", selected_preset);

            //Print Label
            if (setContentPrintBuffer(strprintBuffer))
            {
                printPreviewToolStripMenuItem_Click(sender, e);
            }
        }

        private bool setContentPrintBuffer(string str)
        {
            bool ret = true;
            //Dictionary<string, VarObject> vars = textProcessing.ParseInput(str, '|');
            Dictionary<string, VarObject> vars = textProcessing.ParseInput(str, delimiter);


            foreach (string key in vars.Keys)
            {
                VarObject v;
                vars.TryGetValue(key, out v);
            }

            //Read template content
            try
            {
                string html = System.IO.File.ReadAllText(ini.Read("template", selected_preset));

                //Process html
                html = TextProcessing.ReplaceVariables(textProcessing, html, ini);

                printBuffer = html;
            }
            catch (Exception e)
            {
                //log("Error: " + e.Message);
                ret = false;

            }

            return ret;
        }

        private void printPreviewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                PrintPreviewDialog printPreviewDialog1 = new PrintPreviewDialog();
                printDocument.PrinterSettings.PrinterName = this.printerName;
                printPreviewDialog1.Document = this.printDocument;
                printPreviewDialog1.FormBorderStyle = FormBorderStyle.Fixed3D;
                printPreviewDialog1.ShowDialog();

                printPreviewDialog1.PrintPreviewControl.Zoom = 200 / 100f;
                (printPreviewDialog1 as Form).WindowState = FormWindowState.Maximized;
            }
            catch (Exception exp)
            {
                System.Console.WriteLine(exp.Message.ToString());
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            lblTime.Text = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt");
        }

        private void showLog(string msg)
        {
            String tmp = String.Format("[{0}] {1}", DateTime.Now.ToString(DATETIME_FORMAT), msg);
            lblStatus.Text = tmp;
            logger.Info(msg);
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            timer2.Enabled = false;
            init(sender, e);
        }

        private void txtLeakTestCode_TextChanged(object sender, EventArgs e)
        {

        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void btnReprint_Click_1(object sender, EventArgs e)
        {
            ReprintFrm reprintFrm = new ReprintFrm();
            reprintFrm.ShowDialog(this);
        }

        private void btnPackingStart_Click_1(object sender, EventArgs e)
        {
            showLog("Packing start.");

            btnPackingEnd.Enabled = true;
            txtLeakTestCode.Enabled = true;
            btnCancel.Enabled = true;
            btnClearList.Enabled = true;

            btnPackingStart.Enabled = false;

            txtLeakTestCode.Focus();

           
            if (workingState.step == "1")
            {
                string tmp = "";
                //for (int i = 0; i < MAXIMUM_SCAN - 1; i++)
                //{
                //    tmp += delimiter.ToString();
                //}

                for (int i = 0; i < 47; i++)
                {
                    tmp += delimiter.ToString();
                }

                workingState.pallet_no = "123456789"; //txtLeakTestCode.Text.ToString();
                workingState.step = "2";
                workingState.scan_count = "0";
                workingState.leaktest_code = tmp;
                workingState.packing_time = tmp;
                workingState.serial_no = tmp;

                workingState.part_name = "";
                workingState.part_code = "";
                workingState.abbreviation = "";
                workingState.part_no = "";

                WorkingState.Save(workingState, WORKING_JSON);
            }

            updateView();

        }

        private void txtLeakTestCode_TextChanged_1(object sender, EventArgs e)
        {

        }


    }
}
