using com.hnshituo.core.webapp.vo;
using Common;
using Infragistics.Win.UltraWinGrid;
using JC_MeasuringSystem;
using MeterModuleLibrary.uc;
using MeterPlugInLibrary;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CarMonitor
{
    public partial class frmMonitor : Form
    {
        public frmMonitor()
        {
            InitializeComponent();
        }

        Log lg = Log.GetInstance();
        BaseDbCls bd = new BaseDbCls();

        private string sVoice = "";
        private Thread thVoice = null;
        VoicePlay vp = new VoicePlay();
        private frmMsgInfo fm = null;

        string userId = "", userName = "";
        DbHelper db = new DbHelper();
        MeterWorkMonitorService monitorService = new MeterWorkMonitorService();
        private void frmMonitor_Load(object sender, EventArgs e)
        {
            PbCacheMonitor.frmMsgClosingTime = DateTime.Now;

            timer2.Start();
            userId = ((ST_MainForm)(this.MdiParent)).UserID;
            userName = ((ST_MainForm)(this.MdiParent)).UserName;

            #region 载入计量点的信息
            bd.setBaseDb();
            bd.getDb();
            setGridData();

            foreach (UltraGridRow ugr in ultraGridPW.Rows) 
            {
                if (ugr.Cells["monitorUserNo"].Text.Trim() != "" && ugr.Cells["monitorUserNo"].Text.Trim() == userName)
                {
                    ugr.Cells["UNCK"].Value = true;
                    ucCarMonitoring uc = new ucCarMonitoring();
                    uc.strCollectNo = ugr.Cells["collectionCode"].Text.Trim();
                    uc.Name = "uc" + ugr.Cells["pointNo"].Text;
                    uc.sUserId = userId;
                    uc.sName = userName;
                    uc.sPoint= ugr.Cells["pointNo"].Text;
                    uc.sPointName= ugr.Cells["pointName"].Text;
                    uc.ucMonitoringEvent += new EventHandler(ucEvent);
                    uc.evoice += new EventVoice(setsVoice);
                    //****************************************注意下面这个**********************
                    // uc.moxaip = dtPointInfo.Rows[k]["MOXAIP"].ToString().Trim(); 
                    uc.openMsg += new EventOpenMsg(OpenMsg);
                    uc.rowPointInfo = null;
                    uc.BorderStyle = BorderStyle.FixedSingle;
                    uc.db = db;
                    
                    flPanel.Controls.Add(uc);
                    
                }
                else 
                {
                    ugr.Cells["UNCK"].Value = false;
                }
            }

            ClsControlPack.RefreshAndAutoSize(this.ultraGridPW);

            #endregion
            thVoice = new Thread(ThVoice);
            thVoice.Start();
        }

        public void setGridData() 
        {
            DataTable dt = dtJGPointInfo.Clone();
            if (PbCacheMonitor.ltWorkMonitor != null && PbCacheMonitor.ltWorkMonitor.Count > 0) 
            {
                foreach (MeterWorkMonitor mwm in PbCacheMonitor.ltWorkMonitor) 
                {
                    DataRow dr = dt.NewRow();
                    dr["pointNo"] = mwm.pointNo;
                    dr["pointName"] = mwm.pointName;
                    dr["monitorUserNo"] = mwm.monitorUserNo;
                    dr["collectionCode"] = mwm.collectionCode;
                    dt.Rows.Add(dr);
                }
            }

            ClsControlPack.CopyDataToDatatable(ref dt, ref this.dtJGPointInfo, true);
            ClsControlPack.RefreshAndAutoSize(this.ultraGridPW);
        }

        /// <summary>
        /// 对应用户控件的ucMonitoringEvent；将用户控件回调到主界面执行，用于打开语音对讲或打开新的界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void ucEvent(object sender, EventArgs e)
        {
            Control control = (Control)sender;
            ucCarMonitoring um = control.Parent.Parent.Parent.Parent as ucCarMonitoring;
            bool bMainUm = true;
            if (control.Name == "btnSee")
            {
                um = control.Parent.Parent.Parent as ucCarMonitoring;
            }
            if (um == null)
            {
                frmProductVoice fv = control.Parent.Parent.Parent.Parent.Parent as frmProductVoice;
                um = fv._uc;
                bMainUm = false;
            }

            PbCacheMonitor.sportInfo = PbCacheMonitor.sportInfos.Where(s => s.baseSpotNo == um.sPoint).FirstOrDefault();

            //ucProductMonitoring um = control as ucProductMonitoring;
            try
            {
                switch (control.Name)
                {
                    case "btnIpVoice":
                        {
                            //表示曾经打开了一个语音，且不是当前点击的这个语音
                            if (um.sPoint != openPointNo && !string.IsNullOrEmpty(openPointNo))
                                MessageBox.Show("一次只能打开一个语音对讲!");
                            else
                                VoiceOption(um, bMainUm);
                        };
                        break;
                    case "btnSee":
                        {
                            frmProductVoice fpv = new frmProductVoice();
                            fpv.ucMonitoringEvent += new EventHandler(ucEvent);
                            fpv.Text = um.sPointName;
                            fpv._uc = um;
                            fpv.db = db;
                            fpv.ShowDialog();
                        };
                        break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("操作异常：" + ex.Message);
            }
        }

        /// <summary>
        /// 现场求助信息为：1呼叫待接听，从用户控件中回调主界面方法
        /// </summary>
        /// <param name="pointName"></param>
        private void OpenMsg(string pointName)
        {
            try
            {
                if (string.IsNullOrEmpty(openPointNo) && !bMsgOpen)
                {
                    if (PbCacheMonitor.frmMsgClosingTime == null)
                    {
                        bMsgOpen = true;
                        fm = frmMsgInfo.CreateInstrance(this);
                        fm.TopMost = true;
                        fm.setLbTxt(pointName);
                        fm.Show();
                    }
                    else 
                    {
                        TimeSpan secondSpan = new TimeSpan(DateTime.Now.Ticks - PbCacheMonitor.frmMsgClosingTime.Value.Ticks);
                        if (secondSpan.TotalSeconds > 10) 
                        {
                            bMsgOpen = true;
                            fm = frmMsgInfo.CreateInstrance(this);
                            fm.TopMost = true;
                            fm.setLbTxt(pointName);
                            fm.Show();
                        }
                    }
                }

                if (!string.IsNullOrEmpty(openPointNo) && fm != null) 
                {
                    fm.CloseFrm();
                }
            }
            catch { }
        }


        public bool bMsgOpen = false;

        /// <summary>
        /// 用户控件中调用语音提示操作；具体操作在下面的线程ThVoice中处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void setsVoice(object sender, string e)
        {
            sVoice += e + "|";
        }

        /// <summary>
        /// fm为frmMsgInfo
        /// </summary>
        private void ThVoice()
        {
            while (true)
            {
                if (string.IsNullOrEmpty(openPointNo))
                {
                    //挂断操作
                    sVoice = "";
                    if (fm != null && bMsgOpen && PbCacheMonitor.ltWorkMonitor != null)
                    {
                        int icount = PbCacheMonitor.ltWorkMonitor.Where(s => s.isHelp != null && s.isHelp == "1").Count();
                        if (icount == 0)
                        {
                            fm.setFrmNull();
                            fm = null;
                        }
                    }
                }
                else if (bMsgOpen)
                {
                    //弹出了语音呼叫界面
                    sVoice = "";
                }
                else if (sVoice != "")
                {
                    /* //注销下面播放提示语音的代码
                    //string[] sVoiceFirst = sVoice.Split("|");
                    int i = sVoice.IndexOf("|");
                    if (i > 0)
                    {
                        string voiceOpen = sVoice.Substring(0, i);
                        sVoice = sVoice.Substring(i + 1);

                        vp.GetVoicePlay(voiceOpen, "");
                        //Thread.Sleep();
                    }
                    else
                    {
                        Thread.Sleep(2000);
                    }
                    //*/
                }
                else
                {
                    Thread.Sleep(2000);
                }
            }
        }

        #region 语音对讲
        /// <summary>
        /// 硬盘录像机登录
        /// </summary>
        DhCameraShot cameraShotMain = new DhCameraShot();

        /// <summary>
        /// 必须先打开连接
        /// </summary>
        private bool GetIPVideo(MeterBaseVideoinfo video)
        {
            try
            {
                cameraShotMain.ip = video.videoip;
                cameraShotMain.port = video.vdoPort;
                cameraShotMain.uid = video.vdoUser;
                cameraShotMain.pwd = video.vdoPwd;

                cameraShotMain.Connection();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
            return true;
        }

        /// <summary>
        ///  必须先打开视频，然后再打开语音
        /// </summary>
        private void VoiceOpen()
        {
            try
            {
                cameraShotMain.StartTalk();
            }
            catch (Exception exp)
            {
                MessageBox.Show("打开语音失败：" + exp.Message);
            }
        }

        /// <summary>
        /// 关闭语音对讲
        /// </summary>
        private void VoiceClose()
        {
            try
            {
                cameraShotMain.StopTalk();
            }
            catch (Exception exp)
            {
                MessageBox.Show("关闭失败" + exp.Message);
            }

        }

        /// <summary>
        /// 关闭视频
        /// </summary>
        private void IPVideoClose()
        {
            try
            {
                //退出视频及语音登录
                cameraShotMain.Close();
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message);
            }

        }
        #endregion

        private string openPointNo = "";
        private void VoiceOption(ucCarMonitoring um, bool bMainUm)
        {
            if (PbCacheMonitor.ltWorkMonitor == null || PbCacheMonitor.ltWorkMonitor.Count == 0) 
            {
                MessageBox.Show("获取计量点信息异常，请稍后再试");
                return;
            }

            MeterWorkMonitor monitor = PbCacheMonitor.ltWorkMonitor.Where(s => s.pointNo == um.sPoint).FirstOrDefault();
            if (monitor == null) 
            {
                MessageBox.Show("获取当前计量点信息异常，请稍后再试");
                return;
            }

            //当前计量点已开启语音对讲
            if (!um.isNcFlag)  //未开启
            {
                //进行开启操作，并修改监控表的标识位
                bd.getSpot();
                GetIPVideo(PbCacheMonitor.videoInfo);
                VoiceOpen();
                um.setBtnVoiceText("挂断");
                UpdateCarijeg(new MeterWorkMonitor { pointNo = monitor.pointNo, isHelp = "2" });
                um.isNcFlag = true;
                um.bOpenVoice = false;
                openPointNo = um.sPoint;
                //um.cameraShotMain = cameraShotMain;
                lg.WriteLog(4, "开启语音的计量点：" + um.sPointName + ",对应的IP地址为：" + PbCacheMonitor.videoInfo.videoip);
            }
            else
            {
                //进行挂断操作，并修改监控表的标识位
                bd.getSpot();
                VoiceClose();
                /*
                if (bMainUm) 
                {
                    IPVideoClose();
                }
                //*/
                IPVideoClose();
                um.setBtnVoiceText("对讲");
                UpdateCarijeg(new MeterWorkMonitor { pointNo = monitor.pointNo, isHelp = "0" });
                um.isNcFlag = false;
                um.bOpenVoice = true;
                openPointNo = "";
                //um.cameraShotMain = null;
                lg.WriteLog(4, "关闭语音的计量点：" + um.sPointName + ",对应的IP地址为：" + PbCacheMonitor.videoInfo.videoip);
            }
        }

        /// <summary>
        /// 修改数据到接管表
        /// </summary>
        private void UpdateCarijeg(MeterWorkMonitor monitor)
        {
            RESTfulResult<string> rms = monitorService.doUpdateWf(monitor);
            if (!rms.Succeed) 
            {
                lg.WriteLog(4, "写入数据失败");
            }
        }


        private void timer2_Tick(object sender, EventArgs e)
        {
            try
            {
                if (bd.getDb()) 
                {
                    foreach (MeterWorkMonitor mon in PbCacheMonitor.ltWorkMonitor) 
                    {
                        foreach (Control cn in flPanel.Controls) 
                        {
                            if (cn.Name.Contains("uc")) 
                            {
                                ucCarMonitoring ucCar = cn as ucCarMonitoring;
                                if (ucCar.sPoint == mon.pointNo) 
                                {
                                    ucCar.rowPointInfo = mon;
                                }
                            }
                        }
                    }
                }
                else
                {
                    lg.WriteLog(4, "未找到实时监控数据");
                }
                
                //*/
            }
            catch (Exception ex)
            {
                lg.WriteLog(4, "数据库连接异常");
            }
        }

        private void ultraGridPW_CellChange(object sender, CellEventArgs e)
        {
            ultraGridPW.UpdateData();
            UltraGridRow ugr = ultraGridPW.ActiveRow;
            if (ugr != null)
            {
                if (ugr.Cells["UNCK"].Value.ToString().ToLower() == "false")
                {
                    if (!string.IsNullOrEmpty(openPointNo) && openPointNo == ugr.Cells["pointNo"].Text.Trim())
                    {
                        ugr.Cells["UNCK"].Value = true;
                        MessageBox.Show("当前计量点开启了语音，请先关闭语音"); //若要自动关闭则看Form_Closing事件代码即可
                        return;
                    }

                    flPanel.Controls.RemoveByKey("uc" + ugr.Cells["pointNo"].Text);
                    RESTfulResult<string> rm = monitorService.doUpdateWf(new MeterWorkMonitor { pointNo = ugr.Cells["pointNo"].Text.Trim(), monitorUserNo = "" });
                    if (!rm.Succeed) 
                    {
                        lg.WriteLog(4, "写入取消接管信息失败");
                    }
                }
                else
                {
                    MeterWorkMonitor mwm = PbCacheMonitor.ltWorkMonitor.Where(s => s.pointNo == ugr.Cells["pointNo"].Text.Trim()).FirstOrDefault();
                    //先查一次是否接管了
                    if (mwm != null && !string.IsNullOrEmpty(mwm.monitorUserNo))
                    {
                        ugr.Cells["UNCK"].Value = false;
                        MessageBox.Show("当前计量点已被账号【" + mwm.monitorUserNo + "】接管");
                        return;
                    }
                    
                    ucCarMonitoring uc = new ucCarMonitoring();
                    uc.strCollectNo = ugr.Cells["collectionCode"].Text.Trim();
                    uc.Name = "uc" + ugr.Cells["pointNo"].Text;
                    uc.sUserId = userId;
                    uc.sPoint = ugr.Cells["pointNo"].Text;
                    uc.sPointName = ugr.Cells["pointName"].Text;
                    uc.ucMonitoringEvent += new EventHandler(ucEvent);
                    uc.evoice += new EventVoice(setsVoice);
                    //****************************************注意下面这个**********************
                    // uc.moxaip = dtPointInfo.Rows[k]["MOXAIP"].ToString().Trim(); 
                    uc.openMsg += new EventOpenMsg(OpenMsg);
                    uc.rowPointInfo = null;
                    uc.BorderStyle = BorderStyle.FixedSingle;
                    uc.db = db;
                    flPanel.Controls.Add(uc);

                    RESTfulResult<string> rm = monitorService.doUpdateWf(new MeterWorkMonitor { pointNo = ugr.Cells["pointNo"].Text.Trim(), monitorUserNo = userName });
                    if (!rm.Succeed)
                    {
                        lg.WriteLog(4, "写入接管信息失败");
                    }
                }
            }
        }

        private void frmMonitor_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(openPointNo))
                {
                    UpdateCarijeg(new MeterWorkMonitor { pointNo = openPointNo, isHelp = "0" });
                    VoiceClose();
                    IPVideoClose();//关闭视频
                }

                if (thVoice != null) thVoice.Abort();
            }
            catch (Exception ex)
            {
                lg.WriteLog(4, "关闭监控界面异常：" + ex.Message);
            }
            finally 
            {
                timer2.Stop();
            }
        }
    }
}
