using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Data;
using System.Net;
using System.IO;

using System.IO.Ports;

using System.Collections.Generic;
using System.Text;

using System.Threading;


namespace SyUpLoad
{
    partial class PartLoad
    {
        /// <summary>
        /// 从DataReceived扫描枪发送条码到处理程序
        /// BarCode(string barCode)
        /// </summary>
        /// <param name="barCode"></param>
        public delegate void BarCodeInvoke(string barCode);
        /// <summary>
        /// BarCode(string barCode)
        /// 从DataReceived扫描枪发送条码到处理程序
        /// </summary>
        BarCodeInvoke barCodeInvoke;


        /// <summary>
        /// 当前扫描枪类型
        /// 1:手持；2：固定
        /// </summary>
        string ScannerType_Current = "1";

        //手持扫描枪
        private System.IO.Ports.SerialPort serialPort1 = new SerialPort();
        /// <summary>
        /// 初始化COM通讯口
        /// </summary>
        public void SetCOM()
        {
            try
            {
                //首选扫描枪
                barCodeInvoke = new BarCodeInvoke(BarCode); 
                SetCOM1();
            }
            catch (Exception err)
            {
               // ApplicationLog.WriteLog(err, err.Message);
            }
        }
        /// <summary>
        /// 初始化COM通讯口
        /// </summary>
        public void SetCOM1()
        {
            try
            {
                //if (ApplicationConfig.PortName.Length < 3)
                //{
                //    return;
                //}
                serialPort1.PortName = PortName;  //端口号
                serialPort1.BaudRate = BaudRate; //比特率，默认为9600
                serialPort1.Parity = Parity.None;//奇偶校验
                serialPort1.StopBits = StopBits.One;//停止位
                serialPort1.ReadTimeout = ReadTimeout; //读超时，即在1000内未读到数据就引起超时异常
                serialPort1.DtrEnable = true;
                serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);

                OpenSerialPort();
            }
            catch (Exception err)
            {
                //ApplicationLog.WriteLog(err, err.Message);
            }
            finally
            {

            }
        }

        /// <summary>
        /// 关闭扫描枪
        /// </summary>
        private void OpenSerialPortAll()
        {
            SetCOM1();
        }
        /// <summary>
        /// 打开扫描枪
        /// </summary>
        private bool OpenSerialPort()
        {
            try
            {
                //if (ApplicationConfig.PortName.Length < 4)
                //{
                //    return true;
                //}
                if (serialPort1 == null) return true;
                if (!serialPort1.IsOpen)
                {
                    serialPort1.Open();
                    SerialPort_Closing = false;
                }
                return true;
            }
            catch (Exception err)
            {
                //ApplicationLog.WriteLog(err, err.Message);
                return false;
            }
        }
        /// <summary>
        /// 关闭扫描枪
        /// </summary>
        private bool CloseSerialPort()
        {
            try
            {
                //if (ApplicationConfig.PortName.Length < 4)
                //{
                //    return true;
                //}
                if (serialPort1 == null) return true;

                //根据当前串口对象，来判断操作
                if (serialPort1.IsOpen)
                {
                    SerialPort_Closing = true;
                    while (SerialPort_Listening) Application.DoEvents();
                    serialPort1.Close();
                }
                return true;
            }
            catch (Exception err)
            {
                //ApplicationLog.WriteLog(err, "CloseSerialPort");
                return false;
            }
        }
        /// <summary>
        /// 关闭扫描枪
        /// </summary>
        private void CloseSerialPortAll()
        {
            CloseSerialPort();
        }
        /// <summary>
        /// 是否没有执行完invoke相关操作
        /// </summary>
        private bool SerialPort_Listening = false;
        /// <summary>
        /// 是否正在关闭串口，执行Application.DoEvents，
        /// </summary>
        private bool SerialPort_Closing = false;
        /// <summary>
        /// 处理手持扫描枪
        /// 对于总线缸盖上线工位，扫描枪是固定扫描枪。（F102）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //byte[] readBuf;
            //int HowTime = ApplicationConfig.HowTime;
            //int ByteTime = ApplicationConfig.ByteTime;
            string barCode;
            //获取或设置一个值，该值在串行通信过程中启用数据终端就绪 (DTR) 信号。
            //如果为 true，则启用数据终端就绪 (DTR)；否则为 false。默认为 false。 
            bool DtrEnable = serialPort1.DtrEnable;
            //如果已将数据设置就绪信号发送到该端口，则为 true；否则为 false。
            bool DsrHolding = serialPort1.DsrHolding;
            //如果端口处于中断状态，则为 true；否则为 false。 
            bool BreakState = serialPort1.BreakState; ;

            if (SerialPort_Closing) return;
            //如果正在关闭，忽略操作，直接返回， 尽快的完成串口监听线程的一次循环
            try
            {
                //设置标记，说明我已经开始处理数据，一会儿要使用系统UI的。
                SerialPort_Listening = true;
                //20110225 zhangji
                //获取扫描枪信息时加延时，否则可能无法完全读取扫描的信息
                Thread.Sleep(200);
                int n = serialPort1.BytesToRead;
                byte[] buf = new byte[n];
                //声明一个临时数组存储当前来的串口数据
                serialPort1.Read(buf, 0, n);
                n = n - ScannerTrim;
                barCode = Encoding.UTF8.GetString(buf, 0, n);
                BeginInvoke(barCodeInvoke, new Object[] { barCode });
            }
            catch (Exception err)
            {

                barCode = "";
                //ApplicationLog.WriteLog(err, err.Message);
            }
            finally
            {
                //清空扫描枪缓冲区
                serialPort1.DiscardInBuffer();
                SerialPort_Listening = false;//我用完了，ui可以关闭串口了。

                //最后用完了先关闭串口，然后再打开串口
                CloseSerialPort();
                OpenSerialPort();
            }
        }

        /// <summary>
        /// 字符数组转字符串16进制
        /// </summary>
        /// <param name="InBytes"> 二进制字节</param>
        /// <returns>类似"01 02 0F"</returns>
        public static string ByteToString(byte[] InBytes)
        {
            string StringOut = "";
            foreach (byte InByte in InBytes)
            {
                StringOut = StringOut + String.Format("{0:X2}", InByte) + " ";
            }

            return StringOut.Trim();
        }
        /// <summary>
        /// strhex 转字节数组
        /// </summary>
        /// <param name="InString">类似"01 02 0F" 用空格分开的 </param>
        /// <returns></returns>
        public static byte[] StringToByte_Int(string InString)
        {
            string[] ByteStrings;
            ByteStrings = InString.Split("|".ToCharArray());
            byte[] ByteOut;
            ByteOut = new byte[ByteStrings.Length];
            try
            {
                for (int i = 0; i <= ByteStrings.Length - 1; i++)
                {
                    ByteOut[i] = byte.Parse(ByteStrings[i]);
                }
            }
            catch (Exception err)
            {

                //ApplicationLog.WriteLog(err, err.Message);
            }
            return ByteOut;
        }
        /// <summary>
        /// strhex 转字节数组
        /// </summary>
        /// <param name="InString">类似"01 02 0F" 用空格分开的 </param>
        /// <returns></returns>
        public static byte[] StringToByte(string InString)
        {
            string[] ByteStrings;
            ByteStrings = InString.Split(" ".ToCharArray());
            byte[] ByteOut;
            ByteOut = new byte[ByteStrings.Length];
            for (int i = 0; i <= ByteStrings.Length - 1; i++)
            {
                ByteOut[i] = byte.Parse(ByteStrings[i], System.Globalization.NumberStyles.HexNumber);
            }
            return ByteOut;
        }

        /// <summary>
        /// strhex 转字节数组
        /// </summary>
        /// <param name="InString">类似"01 02 0F" 中间无空格</param>
        /// <returns></returns>
        public static byte[] StringToByte_2(string InString)
        {
            byte[] ByteOut;
            InString = InString.Replace(" ", "");
            try
            {
                string[] ByteStrings = new string[InString.Length / 2];
                int j = 0;
                for (int i = 0; i < ByteStrings.Length; i++)
                {

                    ByteStrings[i] = InString.Substring(j, 2);
                    j += 2;
                }

                ByteOut = new byte[ByteStrings.Length];
                for (int i = 0; i <= ByteStrings.Length - 1; i++)
                {
                    ByteOut[i] = byte.Parse(ByteStrings[i], System.Globalization.NumberStyles.HexNumber);
                }
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }

            return ByteOut;
        }
        /// <summary>
        /// 字符串 转16进制字符串
        /// </summary>
        /// <param name="InString">unico</param>
        /// <returns>类似“01 0f”</returns>
        public static string Str_To_0X(string InString)
        {
            return ByteToString(UnicodeEncoding.Default.GetBytes(InString));
        }
    }
}
