using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using FObjBase;
namespace FLY.ModbusModule
{
    
    /// <summary>
    /// 解决异步问题
    /// </summary>
    public class Serial
    {
        System.IO.Ports.SerialPort serial = new System.IO.Ports.SerialPort();
        List<byte> in_buf = new List<byte>();

        #region 锁
        Mutex m_bufMutex = new Mutex();
        void LockBuf() { m_bufMutex.WaitOne(); }
        void UnlockBuf() { m_bufMutex.ReleaseMutex(); }
        #endregion
        public Serial() 
        {

            serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serial_DataReceived);
            
        }

        void serial_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            int len = serial.BytesToRead;
            byte[] buf = new byte[len];
            serial.Read(buf, 0, len);
            LockBuf();
            in_buf.AddRange(buf);
            if (in_buf.Count > serial.ReadBufferSize) 
            {
                in_buf.RemoveRange(0, in_buf.Count - serial.ReadBufferSize);
            }
            UnlockBuf();
        }
        public string PortName
        {
            get{return serial.PortName;}
            set{serial.PortName=value;}
        }

        public int BaudRate
        {
            get{return serial.BaudRate;}
            set{serial.BaudRate=value;}
        }

        public int DataBits
        {
            get{return serial.DataBits;}
            set{serial.DataBits=value;}
        }

        public System.IO.Ports.Parity Parity
        {
            get{return serial.Parity;}
            set{serial.Parity=value;}
        }

        public System.IO.Ports.StopBits StopBits
        {
            get { return serial.StopBits; }
            set { serial.StopBits = value; }
        }
        public bool IsOpen 
        {
            get { return serial.IsOpen; }
        }
        public void Open()
        {
            LockBuf();
            in_buf.Clear();
            UnlockBuf();

            serial.Open();
        }

        public void Close()
        {
            try
            {
                serial.Close();
            }
            catch (Exception e)
            { 
            
            }
            LockBuf();
            in_buf.Clear();
            UnlockBuf();
        }

        public int Read(byte[] buffer, int offset, int len) 
        {
            LockBuf();
            if (len > in_buf.Count())
                len = in_buf.Count();
            if (len == 0)
            {
                UnlockBuf();
                return len;
            }
            in_buf.CopyTo(0, buffer, offset, len);
            in_buf.RemoveRange(0, len);
            UnlockBuf();
            return len;
            //serial.
        }
        public void Write(byte[] buffer, int offset, int count) 
        {
            if(serial.IsOpen)
                serial.Write(buffer, offset, count);
        }
    }
}
