using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using cn.edu.suda.sumcu.iot.data;
using cn.edu.suda.sumcu.iot.chart;

//Form类主要针对MainForm.应用开发，故放在cn.edu.suda.sumcu.MainForm.空间下的form子空间中
namespace cn.edu.suda.sumcu.iot.form
{
    public partial class FrmRealtimeSeries : Form
    {
        //声明要继承的窗体
        private FrmMain frmMain;
        //声明绘图区,在一个绘图区上绘制多条曲线
        private ChartArea chartArea = new ChartArea("chartArea");
        //声明图线，可实例化多条曲线  
        private List<Series> series = new List<Series>();
        //实例化DrawSeries类
        private DrawSeries draw;
        //获取选中的IMSI号
        private string selectedIMSI = "";
        //用于存储由终端发来的转化为c#格式的时间
        private DateTime curTime;

        public FrmRealtimeSeries()
        {
            InitializeComponent();
        }

        public FrmRealtimeSeries(FrmMain frm_Main)
            : this()
        {
            this.frmMain = frm_Main;
        }

        /// ===========================================================
        /// <summary>                                                       
        /// 函 数 名:FrmRealtimeSeries_Load                              
        /// 功    能:完成实时数据曲线页面的初始化工作                                                                  
        /// </summary>                                                      
        /// ===========================================================
        private void FrmRealtimeSeries_Load(object sender, EventArgs e)
        {
            //（1）添加“选择查询的IMSI号”列表的内容
            int count = 0;   //用于存储监听的IMSI个数
            //对于g_IMSI数组中的每个IMSI号
            foreach (string Imsi in frmMain.g_IMSI)
            {
                //清除字符串开始和结尾的空格、tab和换行
                string one_imsi = Imsi.Trim();
                //IMSI号长度为15时
                if (one_imsi.Length == 15)
                {
                    //添加到监听IMSI列表中
                    ComboBoxSearchIMSI.Items.Add(one_imsi);
                    count++; //IMSI号个数加1                
                }
            }
            //（2）默认首先显示第一个IMSI号的曲线
            ComboBoxSearchIMSI.SelectedIndex = 0;
        }

        /// ===========================================================
        /// <summary>                                                       
        /// 函 数 名:ComboBoxSearchIMSI_SelectedIndexChanged                              
        /// 功    能:点击下拉列表选取IMSI号获取对应的实时曲线                                                                  
        /// </summary>                                                      
        /// ===========================================================
        private void ComboBoxSearchIMSI_SelectedIndexChanged(object sender, EventArgs e)
        {
            //（1）获取选中的IMSI号
            selectedIMSI = ComboBoxSearchIMSI.SelectedItem.ToString();
            //（2）获取点击下拉列表的时间
            curTime = DateTime.Now;
            //（3）首先清空曲线
            foreach (var line in chart1.Series)
            {
                line.Points.Clear();
            }
            //（4）初始化chart控件并清空曲线中数据点的数据
            draw = new DrawSeries(chart1, chartArea);
            //（5）显示实时曲线
            draw.rtSeriesInit(chart1, chartArea, series, "blue", "red", "MCU温度");
            draw.rtSeriesInit(chart1, chartArea, series, "red", "blue", "信号强度");
            //（6）注册数据接收事件
            this.frmMain.frmRealtimeData.DeviceDataEvent += new FrmRealtimeData.DeviceData(recv);
        }

        /// ===========================================================
        /// <summary>                                                       
        /// 函数名称：recv                                       
        /// 输入参数：imsi：接收到的终端imsi号；data：接收到的数据；                       
        /// 功  能：读出数据并根据命令字解析出来显示，实时显示数据
        /// 返  回：无
        /// </summary>                                                                                       
        /// ===========================================================
        private void recv(string imsi, byte[] frameData)
        {
            string IMSI = "";       //用于存储由终端发来的IMSI号
            double mcuTemp = 0;    //用于存储由终端发来的MCU温度
            double signalPower = 0;//用于存储由终端发来的信号强度

            //判断是否为配置数据
            string command = Encoding.Default.GetString(frameData, 0, 2);
            FrameData tmpFrmStruct = null;
            if (this.frmMain.g_commandsFrame.ContainsKey(command))
            {
                tmpFrmStruct = this.frmMain.g_commandsFrame[command];
            }
            //把接收到的字节数组类型的数据转为结构体的成员变量
            tmpFrmStruct.byteToStruct(frameData);
            //解析tmpFrmStruct中的数据并显示在相应位置
            for (int i = 0; i < tmpFrmStruct.Parameter.Count; i++)
            {
                if (tmpFrmStruct.Parameter[i].name == "IMSI")
                {
                    IMSI = tmpFrmStruct.Parameter[i].value;
                }
                //将发送时间转化为标准时间
                else if (tmpFrmStruct.Parameter[i].name == "currentTime")
                {
                    System.DateTime startTime =
                        new DateTime(1970, 1, 1);       //获取时间基准
                    string sendTime =
                       tmpFrmStruct.Parameter[i].value; //记录发送时间
                    ulong u = Convert.ToUInt64   //将时间转为ulong格式
                        (sendTime);
                    double d =                   //将u转化为double类型
                        Convert.ToDouble(u);
                    TimeSpan delta = TimeSpan.FromSeconds(d);
                    curTime =
                        startTime.Add(delta);    //获得发送时间                   
                }
                else if (tmpFrmStruct.Parameter[i].name == "mcuTemp")
                {
                    string temp = tmpFrmStruct.Parameter[i].value;
                    mcuTemp = Convert.ToDouble(Convert.ToDouble(temp) / 10);
                }
                else if (tmpFrmStruct.Parameter[i].name == "signalPower")
                {
                    string signal = tmpFrmStruct.Parameter[i].value;
                    signalPower = Convert.ToDouble(Convert.ToInt32(signal));
                }
            }

            //判断选择要查询的IMSI号是否与实时接收的IMSI号相同，
            //相同则开始画曲线
            if (selectedIMSI == imsi)
            {
                //draw.rtSeries_addPoint(chart1, series, curTime, mcuTemp);
                draw.rtSeries_addPoint(chart1, series, curTime, mcuTemp, signalPower);
            }
        }

        /// ===========================================================
        /// <summary>                                                       
        /// 函数名称：chart1_GetToolTipText                                           
        /// 函数功能：chart控件中自带的方法：
        ///           判断鼠标是否移动到数据标记点，是则显示提示信息
        /// </summary>                                                                                          
        /// ===========================================================
        private void chart1_GetToolTipText(object sender, ToolTipEventArgs e)
        {
            ////判断鼠标是否移动到数据标记点，是则显示提示信息
            if (e.HitTestResult.ChartElementType == ChartElementType.DataPoint)
            {
                this.Cursor = Cursors.Cross;                 //移至数据点时显示十字光标
                int i = e.HitTestResult.PointIndex;          //获取命中数据点的索引
                DataPoint dp = e.HitTestResult.Series.Points[i];
                DateTime dt = DateTime.FromOADate(dp.XValue);//将double的xvalue转换为datetime形式  

                //分别显示x轴和y轴的数值，其中{1:F2},表示显示的是float类型，精确到小数点后2位。    
                e.Text = string.Format("{0}", dp.YValues[0]);
            }
            else
            {
                this.Cursor = Cursors.Default;
            }
        }
    }
}
