using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

using System.Management;

using System.Collections.Concurrent;

using System.Windows.Forms.DataVisualization.Charting;

namespace SerialPort
{
    ///-----------------------------------------------------------------------------------
    ///FrmMain :KW01-A1工程的窗体                                                          
    ///目    的:
    ///日    期:                                             
    ///编 程 者:
    ///-----------------------------------------------------------------------------------
    public partial class FrmMain : Form
    {
        //帧信息
        enum eAppCmd
        {

            eAPPCMD_SYSPARAMREAD = 0x00,       //0x00. 读取目标节点的系统参数（127页）
            eAPPCMD_SYSPARAMWRITE = 0x01,       //0x01. 写入目标节点的系统参数（127页）
            //增加命令
            eAPPCMD_RFTEST = 0x02,              //0x02. 验证RF收发
            eAPPCMD_TEMP_START = 0x03,        //0x03读取温度信息
            eAPPCMD_TEMP_PAUSE = 0x04,        //0x04暂停读取温度信息
            eAPPCMD_TEMP = 0x05,               //0x05温度信息
            eAPPCMD_LIGHT_ON = 0x06,        //0x06开灯
            eAPPCMD_LIGHT_OFF = 0x07,       //0x07关灯
            eAPPCMD_MAX,
        };

        //1. 窗体类的临时变量区
        private System.IO.Ports.SerialPort UARTport; //声明系统工具-串口对象的变量声明
        private Uart uart1;                          //声明一个自定义的Uart类型（串口操作）的变量
        private PCNode pcNode1;                      //声明一个自定义的PCNode类型的变量

        private ConcurrentQueue<byte> cq = new ConcurrentQueue<byte>();          //生命一个线程安全队列，用以保存从串口接收的数据
                                                                                 //供其他函数处理数据用


        byte[] shakeframe = {(byte)'P',11,0,
                                 (byte)'W',(byte)'h',(byte)'o',(byte)'a',(byte)'r',(byte)'e',
                                 (byte)'y',(byte)'o',(byte)'u',(byte)'?', 
                                 (byte)'C' 
                                 };
        const int tempCount = 20;
        double[] tempArray = new double[tempCount];
        ChartArea chartAreas1;
        Series series1;

  
        //2. 构造函数（启动窗体最先执行程序）
        public FrmMain()
        {
            //系统生成的构造函数（初始化窗体的元素）
            InitializeComponent();        
            //禁止检测跨线程调用异常(
            CheckForIllegalCrossThreadCalls = false;  
            //初始化窗体类临时变量
            UARTport = null;          //初始化“系统工具-串口对象”
            uart1 = null;             //初始化“Uart类型（串口操作）对象”
            pcNode1 = new PCNode();   //
       }
        
        //3. 加载窗体事件程序（在构造函数之后执行的程序）
        private void FrmMain_Load(object sender, EventArgs e)
        {
            string s1;
            this.tb_statue.Text = "运行状态：FrmMain_Load开始,调用PCNode类内部函数，寻找PCNode...";
            this.tb_statue.Refresh();

            if (uart1 != null && uart1.IsOpen) uart1.close();
            //UARTport = null;

            s1 = pcNode1.findPCNode();           //调用PCNode类内部函数，寻找PCNode
            uart1 = pcNode1.PCNode_Uart1;

            this.tb_statue.Text = "运行状态：" + s1;
            this.tb_statue.Refresh();

            lbl_PC_Node_State.Text = s1;

            //设置绘图控件
            chart1.ChartAreas.Clear();
            chartAreas1 = new ChartArea();
            chartAreas1.AxisX.Interval = 1;
            chartAreas1.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
            chartAreas1.AxisY.Maximum = 50;
            chartAreas1.AxisY.Minimum = -20;
            chartAreas1.AxisY.Interval = 10;
            chart1.ChartAreas.Add(chartAreas1);
            
            series1= new Series("target节点芯片温度");
            series1.ChartType = SeriesChartType.Line;
            chart1.Series.Clear();
            chart1.Series.Add(series1);

            //保留编程参考：绑定DataReceived事件(即串口接收中断处理函数）
            if (uart1 != null)
            {
                UARTport = uart1.port;
                UARTport.DataReceived += new System.IO.Ports. //添加串口对象变量的接收事件的响应函数
                         SerialDataReceivedEventHandler(this.UARTport_recvData);
                uart1.setReceInt(5);           //设置触发DataRecieved事件的字节数（目的是打开该事件）
            }
            //uart1.setReceInt(5);           //设置触发DataRecieved事件的字节数（目的是打开该事件）
            //uart1.sendData(B1, B1.Length); //发送握手数据

          }

        //========================以下是本窗体的各个事件响应函数==========================
       
        //------------------------单击“检测PC节点”按钮----------------------------------
        private void btnCheckPcNode_Click(object sender, EventArgs e)
        {

            //if (_port1.IsOpen) 
            this.tb_statue.Text = "运行状态：" + "单击“检测PC节点”按钮...";
            this.tb_statue.Refresh();

            FrmMain_Load(sender, e);

            this.tb_statue.Text = "运行状态：" + "单击“检测PC节点”按钮...退出";
        }

        
        //-------------------------------串口接收事件的响应函数---------------------------
        private void UARTport_recvData(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            byte b;
            byte[] recArray = new byte[1000];
            int frameLen;

            while (UARTport.BytesToRead > 0) {
                //textBox1.Text += "++++++++++++++++";
                b = (byte)UARTport.ReadByte();
                //textBox1.Text += b + " ";
                recArray[0] = b;//读取帧头

                b = (byte)UARTport.ReadByte();
                //textBox1.Text += b + " ";
                recArray[1] = b;//读取有效帧长

                frameLen=recArray[1];
                for (int i = 2; i < frameLen+3; i++)
                {
                    b = (byte)UARTport.ReadByte();
                    //textBox1.Text += b + " ";

                    recArray[i] = b;//读取帧内容                  
                }
               
                Console.WriteLine( frameLen+3);

                //对帧数据进行解析
                Console.WriteLine(recArray[3]);
                switch (recArray[3])
                {
                    case (byte)eAppCmd.eAPPCMD_TEMP_START:
                        {//已开灯，将按钮文字更改为开灯
                            btnTemperature.Text = "暂停读取温度";
                            break;
                        }
                    case (byte)eAppCmd.eAPPCMD_TEMP_PAUSE:
                        {//已关灯，将按钮文字更改为开灯
                            btnTemperature.Text = "开始读取温度";

                            break;
                        }
                    case (byte)eAppCmd.eAPPCMD_TEMP:
                        {//获取并返回了温度帧
                            uint  vtemp;
                            double temp;
                            vtemp = (uint)recArray[4] + (uint)recArray[5] * 256;
 
                            temp = vtemp* 3300 / 65536 ;
                            temp = 25 - (temp - 706) / 1.62;
                            textBox1.Text ="target节点芯片温度：" + System.Math.Round(temp,2)+"\n";
                            for (int i = 0; i < tempCount - 1; i++)
                            {
                                tempArray[i] = tempArray[i + 1];
                            }
                            tempArray[tempCount - 1] = temp;


                            chart1.Series.Clear();

                            series1 = new Series("target节点芯片温度");
                            series1.ChartType = SeriesChartType.Spline;

                            for (int i = 0; i < tempCount; i++)
                            {
                                series1.Points.AddY(tempArray[i]);
                            }
                            chart1.Series.Add(series1);
                            break;
                        }
                    case (byte)eAppCmd.eAPPCMD_LIGHT_ON:
                        {
                            //已开灯，将按钮文字更改为开灯

                            btnChangeLight.Text = "关灯";
                            break;
                        }
                    case (byte)eAppCmd.eAPPCMD_LIGHT_OFF:
                        {
                            //已关灯，将按钮文字更改为开灯
                            btnChangeLight.Text = "开灯";
                            break;
                        }

                    default:
                        break;
                }
            }
        }

        private void btnGetTemperature_Click(object sender, EventArgs e)
        {
           
            byte[] SendByteArray = new byte[5];//发送字节数组

            SendByteArray[0] = (byte)'P';      //帧头

            SendByteArray[1] = 2;             //帧长
            SendByteArray[2] = 0xFF;          //硬件地址
            if (btnTemperature.Text.Equals("开始读取温度"))
            {
                SendByteArray[3] = (byte)eAppCmd.eAPPCMD_TEMP_START;      //开始读取温度命令
            }
            else if (btnTemperature.Text.Equals("暂停读取温度"))
            {
                SendByteArray[3] = (byte)eAppCmd.eAPPCMD_TEMP_PAUSE;      //暂停读取温度命令
            }

            SendByteArray[4] = (byte)'C';     //帧尾
            pcNode1.PCNodeSend(SendByteArray, 1, 300);//数据发出后不管，由中断处理接收到的数据

        }

        private void btnChangeLight_Click(object sender, EventArgs e)
        {
            byte[] SendByteArray = new byte[5];//发送字节数组

            SendByteArray[0] = (byte)'P';      //帧头

            SendByteArray[1] = 2;             //帧长
            SendByteArray[2] = 0xFF;          //硬件地址
            if (btnChangeLight.Text.Equals("开灯")) {
                SendByteArray[3] = (byte)eAppCmd.eAPPCMD_LIGHT_ON;      //开灯命令
            }
            else if (btnChangeLight.Text.Equals("关灯")) {
                SendByteArray[3] = (byte)eAppCmd.eAPPCMD_LIGHT_OFF;      //关灯命令
            }

            SendByteArray[4] = (byte)'C';     //帧尾
            pcNode1.PCNodeSend(SendByteArray, 1, 300);//数据发出后不管，由中断处理接收到的数据
        }

     
        
    //------------------------------------------------------------------------------------
    }
}
