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

//Form类主要针对MainForm.应用开发，故放在cn.edu.suda.sumcu.MainForm.空间下的form子空间中
namespace cn.edu.suda.sumcu.iot.form
{
    public partial class FrmHistoryData : Form
    {
        //（1）定义类的成员变量
        private FrmMain frmMain;
        private int rowCount = 0;     //显示表单的当前位置
        private int rowCountSum = 0;  //显示表单的总记录数
        private DataTable dt;         //最新查询到的表单
        private TextBox[] dLibTextbox;  //文本框
        private Label[] dLibLabel;      //标签
        private Panel[] dLibPanel;      //放置一组文本框和标签
        private string currentCmd = ""; //记录当前的命令
        private string newCmd = "";     //记录新的命令
        public FrmHistoryData()
        {
            InitializeComponent();
        }
        public FrmHistoryData(FrmMain frmMain):this()
        {
            this.frmMain = frmMain;
        } 
        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 函 数 名:HistoryPage_Load:历史数据页面加载函数                              
        /// 功    能:完成历史数据页面的初始化工作                                                                  
        /// </summary>                                                      
        ///-----------------------------------------------------------------
        private void FrmHistoryData_Load(object sender, EventArgs e)
        {
            //（1）设置允许跨线程文本框赋值
            Control.CheckForIllegalCrossThreadCalls = false;
            //（2）初始化成员变量
            dt = frmMain.sQLUp.select();   //获得历史数据表
            rowCountSum = frmMain.sQLUp.count();     //获得历史数据表的记录数
            rowCount = rowCountSum;
            //frmMain.strip_runstatus.Text = "";
            //（3）创建历史数据的显示控件并显示rowCount行的帧数据
            updateDLibText();
            //（4）添加“选择查询的IMSI号”列表的内容
            ComboBoxSearchIMSI.Items.Add("ALL");
            ComboBoxSearchIMSI.SelectedIndex = 0;   //默认选中全部
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (!ComboBoxSearchIMSI.Items.Contains(dt.Rows[i]["IMSI"].ToString().Trim()))
                {
                    ComboBoxSearchIMSI.Items.Add(dt.Rows[i]["IMSI"].ToString().Trim());
                }
            }

        }
        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 对    象:BtnNewFrm（“最新一帧”按钮）                       
        /// 事    件:Click（单击）                                                  
        /// 功    能:显示数据库最新入库帧数据                         
        /// </summary>                                                      
        /// <param name="sender"></param>                                   
        /// <param name="e"></param>                                        
        ///-----------------------------------------------------------------
        private void BtnNewFrm_Click(object sender, EventArgs e)
        {
            //（1）获得选中的imsi
            string imsi = ComboBoxSearchIMSI.SelectedItem.ToString();
            //（2）更新当前的数据表
            if (imsi == "ALL")
                dt = frmMain.sQLUp.select();   //获得历史数据表
            else
                dt = frmMain.sQLUp.selectNeed("IMSI",imsi);
            //（3）更新当前显示的记录为最新一帧，并更新总记录帧数
            rowCount = dt.Rows.Count;
            rowCountSum = rowCount;
            //（4）更新文本框显示
            updateDLibText();
        }

        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 对    象:BtnPre("最早一帧"按钮)                                     
        /// 事    件:Click（单击）                                                  
        /// 功    能:显示上一帧数据                         
        /// </summary>                                                      
        /// <param name="sender"></param>                                   
        /// <param name="e"></param>                                        
        ///-----------------------------------------------------------------
        private void BtnPre_Click(object sender, EventArgs e)
        {
            rowCount = rowCount - 1;  //获得上一帧的行号
            updateDLibText();         //更新文本框显示
        }

        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 对    象:BtnNext （“下一帧”按钮）                                    
        /// 事    件:Click（单击）                                                  
        /// 功    能:显示下一帧数据                         
        /// </summary>                                                      
        /// <param name="sender"></param>                                   
        /// <param name="e"></param>                                        
        ///-----------------------------------------------------------------
        private void BtnNext_Click(object sender, EventArgs e)
        {
            rowCount++;         //获得下一帧的行号
            updateDLibText();   //更新文本框显示
        }
        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 对    象:BtnLastFrm（“最早一帧”按钮）                                     
        /// 事    件:Click（单击）                                                  
        /// 功    能:显示终端发送的最早一帧数据                        
        /// </summary>                                                      
        /// <param name="sender"></param>                                   
        /// <param name="e"></param>                                        
        ///-----------------------------------------------------------------
        private void BtnLastFrm_Click(object sender, EventArgs e)
        {
            rowCount = 1;       //获得第一帧的行号
            updateDLibText();   //更新文本框显示
        }
        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 对    象:BtnWriteDown（“写入下行表”按钮）                                     
        /// 事    件:Click（单击）                                                  
        /// 功    能:将修改后的数据写入下行表                      
        /// </summary>                                                      
        /// <param name="sender"></param>                                   
        /// <param name="e"></param>                                        
        ///-----------------------------------------------------------------
        private void BtnWriteDown_Click(object sender, EventArgs e)
        {
            int i;
            string write_imsi = "";
            //（1）获得当前显示的帧格式
            FrameData frame = this.frmMain.g_commandsFrame[dLibTextbox[0].Text.ToString()];
            //（2）将文本框中内容更新到结构体frame中
            try
            {
                for (i = 0; i < frame.Parameter.Count; i++)
                {
                    //若为IMSI，则将IMSI号保存到write_imsi变量中
                    if (frame.Parameter[i].name.ToString() == "IMSI")
                    {
                        write_imsi = dLibTextbox[i].Text.ToString();  //读出imsi号
                    }
                    //需要特殊处理的字段
                    if (frame.Parameter[i].name.ToString() == "currentTime")   //若为时间
                    {
                        System.DateTime startTime =           //获取时间基准
                        TimeZone.CurrentTimeZone.ToLocalTime
                        (new System.DateTime(1970, 1, 1));
                        ulong temp = (ulong)
                            (System.DateTime.Now.AddHours(8) - startTime).TotalSeconds;
                        frame.Parameter[i].value =
                            temp.ToString();   //更新当前时间与基准时间的差值                            
                    }
                    else if (frame.Parameter[i].name == "mcuTemp")             //若为芯片温度
                    {
                        string temp = dLibTextbox[i].Text.ToString();
                        temp = temp.Remove(temp.Length - 2, 1);
                        frame.Parameter[i].value = temp;//读出文本框中的数据               
                    }
                    else
                    {
                        if (frame.Parameter[i].type.ToString() == "byte[]")
                        {
                            frame.Parameter[i].value = "";      //清空该字节数组
                            frame.Parameter[i].value =
                                dLibTextbox[i].Text.ToString(); //读出文本框中的数据
                        }
                        else
                        {
                            frame.Parameter[i].value =
                                dLibTextbox[i].Text.ToString(); //读出文本框中的数据
                        }
                    }
                }
            }
            catch
            {
                frmMain.SetToolStripUserOperText("写入失败，文本框中的数据有误");
                return;
            }
        }

        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 对    象:btn_deleteOne_Click（“删除本帧”按钮）                                     
        /// 事    件:Click（单击）                                                  
        /// 功    能:删除当前显示的帧                       
        /// </summary>                                                      
        /// <param name="sender"></param>                                   
        /// <param name="e"></param>                                        
        ///-----------------------------------------------------------------
        private void BtnDeleteOne_Click(object sender, EventArgs e)
        {
            if (rowCount == 0)         //若当前数据库为空
            {
                frmMain.SetToolStripUserOperText("无可供删除的记录");                  //将接收文本框内容清空
            }
            else
            {
                //获得要删除的记录的IMSI号
                string imsi = dt.Rows[rowCount - 1]["IMSI"].ToString().Trim();
                //从数据库中删除该记录
                frmMain.sQLUp.deleteRow(Convert.ToInt32(dt.Rows[rowCount - 1]["ID"]));
                //更新数据表dt
                if (ComboBoxSearchIMSI.SelectedItem != null && ComboBoxSearchIMSI.SelectedItem.ToString()=="ALL")
                    dt = frmMain.sQLUp.select();
                else
                    dt = frmMain.sQLUp.selectNeed("IMSI", imsi);
                //保证rowCount不会大于数据表总行数
                if (rowCount > dt.Rows.Count)
                {
                    rowCount--;
                }
                //判断上行表中是否有该IMSI的记录
                DataTable d = frmMain.sQLUp.selectNeed("IMSI", imsi);
                if (d.Rows.Count == 0)
                    ComboBoxSearchIMSI.Items.Remove(imsi);
                //更新总记录数并更新文本框
                rowCountSum = frmMain.sQLUp.count();
                updateDLibText();
            }
        }
        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 对    象:BtnDeleteAll（“清空数据库”按钮）                                     
        /// 事    件:Click（单击）                                                  
        /// 功    能:清空数据库                      
        /// </summary>                                                      
        /// <param name="sender"></param>                                   
        /// <param name="e"></param>                                        
        ///-----------------------------------------------------------------
        private void BtnDeleteAll_Click(object sender, EventArgs e)
        {
            int i;
            //弹出对话框提示是否清空数据库
            DialogResult dr = MessageBox.Show
                ("此操作将清空数据库中所有数据，请问是否执行该操作？",
                "提示", MessageBoxButtons.YesNo);
            if (dr == DialogResult.Yes)     //若点击了确定
            {
                rowCount = 0;               //清零当前记录数
                rowCountSum = rowCount;     //清零总记录数
                frmMain.sQLUp.deleteAll();  //清零当前记录数
                if(dLibTextbox !=null)
                    for (i = 0; i < dLibTextbox.Count(); i++)   //清空所有自动创建的文本框
                    {
                        dLibTextbox[i].Text = "";
                    }
                dt = frmMain.sQLUp.select(); //更新数据表
                ComboBoxSearchIMSI.Items.Clear();
                ComboBoxSearchIMSI.Items.Add("ALL");
                frmMain.SetToolStripUserOperText( "数据库已空！"); //将接收文本框内容清空
            }
            else if (dr == DialogResult.No)
            {
                frmMain.SetToolStripUserOperText("已取消清空数据库操作！");
            }
        }

        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 对    象:ComboBoxSearchIMSI（“查询”按钮）                                     
        /// 事    件:Click（单击）                                                  
        /// 功    能:根据条件查询需要的记录                       
        /// </summary>                                                      
        /// <param name="sender"></param>                                   
        /// <param name="e"></param>                                        
        ///-----------------------------------------------------------------
        private void ComboBoxSearchIMSISelectedIndexChanged(object sender, EventArgs e)
        {
            //更新数据表
            string imsi = ComboBoxSearchIMSI.SelectedItem.ToString();
            if (imsi == "ALL")
            {
                dt = frmMain.sQLUp.select();
            }
            else
            {
                dt = frmMain.sQLUp.selectNeed("IMSI", imsi);
            }
            //更新当前的文本框显示
            rowCount = dt.Rows.Count;
            rowCountSum = rowCount;
            updateDLibText();
        }
        ///以下为内部函数
        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 函数名称：createLabel                                     
        /// 传入参数：无                                                 
        /// 函数返回：无      
        /// 函数功能：根据MainForm.g_frmStruct动态创建实时数据文本框和历史数据文本框
        /// </summary>                                                                                          
        ///-----------------------------------------------------------------
        private void createLabel(object frame1)
        {
            int i;
            FrameData frame = (FrameData)frame1;
            if (frame.Parameter.Count > 0)
            {
                //重新定义标签与文本框
                dLibTextbox = new TextBox[frame.Parameter.Count];
                dLibLabel = new Label[frame.Parameter.Count];
                dLibPanel = new Panel[frame.Parameter.Count];

                //tabControl1.TabPages[0].BackColor = Color.AliceBlue;
                //设置底色
                FlowPanelHistory.BackColor = Color.AliceBlue;
                //创建标签和文本框，并设置属性和内容
                for (i = 0; i < frame.Parameter.Count; i++)
                {
                    try
                    {
                        dLibPanel[i] = new Panel();
                        dLibPanel[i].Width = 300;
                        dLibPanel[i].Height = 25;
                        dLibLabel[i] = new Label();
                        dLibLabel[i].Width = 120;
                        dLibLabel[i].Height = 25;
                        dLibLabel[i].Font =
                            new System.Drawing.Font
                                ("宋体", 10.8F, FontStyle.Bold);
                        dLibLabel[i].TextAlign =
                            ContentAlignment.MiddleRight;
                        dLibLabel[i].Text =
                            frame.Parameter[i].otherName;
                        dLibTextbox[i] = new TextBox();
                        dLibTextbox[i].Width = 180;
                        dLibTextbox[i].Height = 25;
                        dLibTextbox[i].Font = new System.Drawing.Font
                            ("宋体", 10.8F, FontStyle.Bold);
                        dLibTextbox[i].Left = dLibPanel[i].Left + 120;
                        dLibTextbox[i].ForeColor = Color.White;
                        //设置不同数据类型的文本框颜色不同
                        switch (frame.Parameter[i].type)
                        {
                            case "uint_8":
                            case "int_8":
                            case "byte":
                            case "sbyte":
                                dLibTextbox[i].BackColor = Color.Red; break;
                            case "uint_16":
                            case "int_16":
                            case "short":
                            case "ushort":
                                dLibTextbox[i].BackColor = Color.Orange; break;
                            case "uint_32":
                            case "int_32":
                            case "int":
                            case "uint":
                                dLibTextbox[i].BackColor = Color.Yellow;
                                dLibTextbox[i].ForeColor = Color.Black; break;
                            case "uint_64":
                            case "int_64":
                            case "long":
                            case "ulong":
                                dLibTextbox[i].BackColor = Color.Green; break;
                            case "float":
                                dLibTextbox[i].BackColor = Color.Cyan; break;
                            case "double":
                                dLibTextbox[i].BackColor = Color.DarkBlue; break;
                            case "uint_8[]":
                            case "byte[]":
                                dLibTextbox[i].BackColor = Color.Purple; break;
                            default:
                                if (frame.Parameter[i].type.Contains("byte[")
                                    || frame.Parameter[i].type.Contains("uint_8["))
                                {
                                    dLibTextbox[i].BackColor = Color.Purple; break;
                                }
                                else
                                {
                                    break;
                                }
                        }
                        if (frame.Parameter[i].wr == "read")
                        {
                            dLibTextbox[i].BackColor = Color.LightGray;
                            dLibTextbox[i].Enabled = false;
                        }
                        //设置文本框和标签框等依附的控件
                        dLibTextbox[i].Parent = dLibPanel[i];
                        dLibLabel[i].Parent = dLibPanel[i];
                        dLibPanel[i].Parent = FlowPanelHistory;
                    }
                    catch
                    {
                        MessageBox.Show("自动生成文本框和标签框失败！");
                    }
                }
                frmMain.SetToolStripUserOperText("当前显示数据库最新一帧数据,您可点击下方按钮进行帧数据浏览。");
            }
        }
        ///-----------------------------------------------------------------
        /// <summary>                                                       
        /// 函数名称：updateDLibText                                     
        /// 传入参数：无                                                 
        /// 函数返回：无      
        /// 函数功能：根据rowCount更新指定记录的历史数据文本框
        /// </summary>                                                                                          
        ///-----------------------------------------------------------------
        private void updateDLibText()
        {
            if (rowCount < 1)
                rowCount = 1;
            else if (rowCount > rowCountSum)
                rowCount = rowCountSum;
            if (dt==null || dt.Rows.Count <= 0) return;
            newCmd = dt.Rows[rowCount-1]["cmd"].ToString();
            FrameData tmpFrmStruct = null;
            if (this.frmMain.g_commandsFrame.ContainsKey(newCmd))
            {
                tmpFrmStruct = this.frmMain.g_commandsFrame[newCmd];
            }
            else
                return;
            if(currentCmd != newCmd)
            {
                currentCmd = newCmd;
                createLabel(tmpFrmStruct);
            }
            DataRow dr = dt.Rows[rowCount - 1];
            tmpFrmStruct.dataRowToStruct(dr);
            for (int i = 0; i < dLibTextbox.Count(); i++)
            {
                if (tmpFrmStruct.Parameter[i].name == "mcuTemp")
                {
                    string temp = tmpFrmStruct.Parameter[i].value;
                    temp = temp.Insert(temp.Length - 1, ".");
                    dLibTextbox[i].Text = temp;//读出文本框中的数据    
                }
                //将发送时间转化为标准时间
                else if (tmpFrmStruct.Parameter[i].name == "currentTime")
                {
                    System.DateTime startTime = new DateTime(1970, 1, 1);//获取时间基准
                    ulong u = Convert.ToUInt64(tmpFrmStruct.Parameter[i].value);
                    double d = Convert.ToDouble(u);      //将value1转化为double类型
                    TimeSpan delta = TimeSpan.FromSeconds(d);
                    DateTime curTime = startTime.Add(delta); //获得发送时间
                    dLibTextbox[i].Text = curTime.ToString();   //显示发送时间
                }
                ////【2018-03-14】增   lbs基站定位解析
                //else if (tmpFrmStruct.Parameter[i].name == "lbs_location")
                //{
                //    try
                //    {
                //        dLibTextbox[i].Text = tmpFrmStruct.Parameter[i].value;
                //        DataTable dtTmp = frmMain.sQLCommunityLocation.selectNeed("community", tmpFrmStruct.Parameter[i].value.Replace(",", "-"));
                //        if (dtTmp != null && dtTmp.Rows.Count > 0)
                //            this.text_lbsLocation.Text = "纬度为：" + dtTmp.Rows[0][1] + "  经度为：" + dtTmp.Rows[0][2]
                //                                        + "\r\n地址为：" + dtTmp.Rows[0][3];
                //    }
                //    catch { }

                //}
                else
                {
                    dLibTextbox[i].Text = tmpFrmStruct.Parameter[i].value;
                }
            }

            ////入口参数检查
            //if (dt.Rows.Count == 0)
            //{
            //    rowCount = 0;
            //    frmMain.setToolStripUserOperText("无符合条件的数据");
            //    for (int i = 0; i < frmMain.g_FieldCnt; i++)   //清空历史数据文本框
            //    {
            //        dLibTextbox[i].Text = "";
            //    }
            //    return;
            //}
            //if (rowCount < 1)
            //    rowCount = 1;
            //else if (rowCount > dt.Rows.Count)
            //    rowCount = dt.Rows.Count;
            //for (int i = 0; i < frmMain.g_FieldCnt; i++)
            //{
            //    for (int j = 0; j < dt.Columns.Count; j++)
            //    {
            //        if (dt.Columns[j].ColumnName == frame.Parameter[i].name)
            //        {
            //            if (frame.Parameter[i].name == "mcuTemp")
            //            {
            //                string temp = dt.Rows[rowCount - 1][j].ToString();
            //                temp = temp.Insert(temp.Length - 1, ".");
            //                dLibTextbox[i].Text = temp;//读出文本框中的数据    
            //            }
            //            //将发送时间转化为标准时间
            //            else if (frame.Parameter[i].name == "currentTime")
            //            {
            //                System.DateTime startTime = new DateTime(1970, 1, 1);//获取时间基准
            //                ulong u = Convert.ToUInt64(dt.Rows[rowCount - 1][j].ToString());
            //                double d = Convert.ToDouble(u);      //将value1转化为double类型
            //                TimeSpan delta = TimeSpan.FromSeconds(d);
            //                DateTime curTime = startTime.Add(delta); //获得发送时间
            //                dLibTextbox[i].Text = curTime.ToString();   //显示发送时间
            //            }
            //            //【2018-03-14】增   lbs基站定位解析
            //            else if (frame.Parameter[i].name == "lbs_location")
            //            {
            //                dLibTextbox[i].Text = dt.Rows[rowCount - 1][j].ToString();
            //                DataTable dtTmp = frmMain.sQLCommunityLocation.selectNeed("community", dt.Rows[rowCount - 1][j].ToString().Replace(",", "-"));
            //                if (dtTmp != null && dtTmp.Rows.Count > 0)
            //                    this.text_lbsLocation.Text = "纬度为：" + dtTmp.Rows[0][1] + "  经度为：" + dtTmp.Rows[0][2]
            //                                                + "\r\n地址为：" + dtTmp.Rows[0][3];
            //            }
            //            else
            //            {
            //                dLibTextbox[i].Text = dt.Rows[rowCount - 1][j].ToString();
            //            }
            //        }
            //    }
            //}
            if (rowCount % 10 == 1)
            {
                frmMain.SetToolStripUserOperText("This is the" + rowCount.ToString() + "st frame."
                    + rowCountSum.ToString() + " frames in all.");
            }
            else if (rowCount % 10 == 2)
            {
                frmMain.SetToolStripUserOperText("This is the " + rowCount.ToString() + "nd frame."
                    + rowCountSum.ToString() + " frames in all.");
            }
            else if (rowCount % 10 == 3)
            {
                frmMain.SetToolStripUserOperText("This is the " + rowCount.ToString() + "rd frame."
                    + rowCountSum.ToString() + " frames in all.");
            }
            else
            {
                frmMain.SetToolStripUserOperText("This is the " + rowCount.ToString() + "th frame."
                    + rowCountSum.ToString() + " frames in all.");
            }
            if(ComboBoxSearchIMSI.SelectedItem!=null)
                LabelFrmNum.Text = ComboBoxSearchIMSI.SelectedItem.ToString()
                    + "：" + rowCountSum.ToString() +" frames in all.";
        }
    }
}