using CCDCount.DLL;
using CCDCount.DLL.Tools;
using CCDCount.MODEL.CameraClass;
using CCDCount.MODEL.ConfigModel;
using LogClass;
using MvCameraControl;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;

namespace CCDCountWpf
{
    public static class MessageBus
    {
        public static List<MainThreadClass> MainThreadS = new List<MainThreadClass>();

        public static MainThreadClass NowSettingLoadMainThread = null;

        public static ShowBindingClass ShowBinding = new ShowBindingClass();

        public static CameraClass CameraClass = new CameraClass();

        public static string NowLoadCammeraSN = string.Empty;
        public static int SeetingNowLoadInMaThreadsIndex = -1;
        public static int NowLoadCameraIndex = -1;
    }
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        #region 变量与实例
        Uri ShowUri = null;
        public ModbusTcpClient modbusTcpClient = new ModbusTcpClient();
        List<SaveConfigModel> Configs = null;
        bool IsShow = false;
        SystemMonitor monitor = new SystemMonitor();
        #endregion

        #region 窗体事件
        /// <summary>
        /// 主窗体构造函数
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
            DataContext = MessageBus.ShowBinding;
            //modbusTcpClient.Connect("192.168.1.88");
            modbusTcpClient.Connect("127.0.0.1");
            if (File.Exists(".\\Config\\CCDCountConfig.xml"))
            {
                Configs = XmlStorage.DeserializeFromXml<List<SaveConfigModel>>(".\\Config\\CCDCountConfig.xml");
            }
            SDKSystem.Initialize();
            InitCameraIdentify();
            MainPageBtn_Click(null, null);
            StartUpdataShowDataThread();
            InitCamComboboxValue();
        }

        
        /// <summary>
        /// 退出按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ExitBtn_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 主界面按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainPageBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowUri = new Uri("WpfPage\\MainPage.xaml", UriKind.Relative);
            ShowFrame.Navigate(ShowUri);
        }

        /// <summary>
        /// 开始运行按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RnIdentifyBtn_Click(object sender, RoutedEventArgs e)
        {
            if(RnIdentifyBtn_Text.Text == "开始运行")
            {
                RunCameraIdentify();
                RnIdentifyBtn_Image.Source = new BitmapImage(new Uri("/FromImage/暂停.png", UriKind.Relative));
                RnIdentifyBtn_Text.Text = "停止运行";
            }
            else if(RnIdentifyBtn_Text.Text == "停止运行")
            {
                StopCameraIdentify();
                RnIdentifyBtn_Image.Source = new BitmapImage(new Uri("/FromImage/运行.png", UriKind.Relative));
                RnIdentifyBtn_Text.Text = "开始运行";
            }
        }

        /// <summary>
        /// 窗体关闭事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            SDKSystem.Finalize();
            if (MessageBus.MainThreadS.Count != 0)
            {
                foreach (var item in MessageBus.MainThreadS)
                {
                    item.DisposeCamera();
                }
            }
            Environment.Exit(0);
        }
        #endregion

        #region 私有方法
        private void InitCameraIdentify()
        {
            if (Configs.Count == 0)
            {
                MessageBox.Show("尚未添加相机，请前往配置页面配置相机");
                return;
            }
            if (MessageBus.MainThreadS.Count != 0)
            {
                foreach (var item in MessageBus.MainThreadS)
                {
                    item.StopMianThread();
                }
            }
            MessageBus.MainThreadS = new List<MainThreadClass>();
            for (int i = 0; i < Configs.Count; i++)
            {
                MessageBus.MainThreadS.Add(new MainThreadClass(Configs[i].ShuLiConfigClass, Configs[i].CameraConfig));

                MessageBus.MainThreadS[i].SetModbusClient(modbusTcpClient);
                MessageBus.MainThreadS[i].loadCamera();
            }
        }

        /// <summary>
        /// 启动相机识别
        /// </summary>
        private void RunCameraIdentify()
        {
            for (int i = 0; i < MessageBus.MainThreadS.Count; i++)
            {
                //启动单相机实例的全部线程
                if (!MessageBus.MainThreadS[i].StartMianThread())
                {
                    LOG.error(MessageBus.MainThreadS[i].cameraConfig.DeviceName + "_" + MessageBus.MainThreadS[i].cameraConfig.CameraSNNum + "启动失败");
                    MessageBox.Show(MessageBus.MainThreadS[i].cameraConfig.DeviceName + "_" + MessageBus.MainThreadS[i].cameraConfig.CameraSNNum + "启动失败");
                    continue;
                }
            }
            MessageBus.NowLoadCammeraSN = MessageBus.MainThreadS[0].cameraConfig.CameraSNNum;
            MessageBus.SeetingNowLoadInMaThreadsIndex = 0;
            MessageBus.NowLoadCameraIndex = 0;
        }

        /// <summary>
        /// 启动相机识别
        /// </summary>
        private void StopCameraIdentify()
        {
            for (int i = 0; i < MessageBus.MainThreadS.Count; i++)
            {
                //启动单相机实例的全部线程
                if (!MessageBus.MainThreadS[i].StopMianThread())
                {
                    LOG.error(MessageBus.MainThreadS[i].cameraConfig.DeviceName + "_" + MessageBus.MainThreadS[i].cameraConfig.CameraSNNum + "启动失败");
                    MessageBox.Show(MessageBus.MainThreadS[i].cameraConfig.DeviceName + "_" + MessageBus.MainThreadS[i].cameraConfig.CameraSNNum + "启动失败");
                    continue;
                }
            }
        }
        /// <summary>
        ///  启动更新显示数据线程
        /// </summary>
        private void StartUpdataShowDataThread()
        {
            IsShow = true;
            Bitmap image1 = null;
            Bitmap image2 = null;
            Bitmap image3 = null;
            Bitmap image4 = null;
            const int targetMsPerFrame = 100; // 20FPS=50ms
            Stopwatch renderSW = new Stopwatch();
            Task.Run(() =>
            {
                while (IsShow)
                {
                    renderSW.Restart();
                    UpdataShuLiShowData();
                    UpdateMonitorMessage();
                    if (MessageBus.MainThreadS.Count == 0)
                    {
                        LOG.log(string.Format("{0}：当前未加载识别流程", "IdentifyCameraForm-StartShowImageThread"));
                        Thread.Sleep(100);
                        continue;
                    }
                    if(MessageBus.MainThreadS.Count>=1)
                    {
                        if (MessageBus.MainThreadS[0].HistoryActiveNum > 0)
                        {
                            MessageBus.MainThreadS[0].GetShowImage(2000, out image1);
                        }
                        else
                        {
                            MessageBus.MainThreadS[0].GetNullShowImage(4096, 2000, out image1);
                        }
                        if (image1 == null)
                        {
                            LOG.log(string.Format("{0}：相机一获取图片为空", "IdentifyCameraForm-StartShowImageThread"));
                            continue;
                        }
                    }

                    if (MessageBus.MainThreadS.Count >= 2)
                    {
                        if (MessageBus.MainThreadS[1].HistoryActiveNum > 0)
                        {
                            MessageBus.MainThreadS[1].GetShowImage(2000, out image2);
                        }
                        else
                        {
                            MessageBus.MainThreadS[1].GetNullShowImage(4096, 2000, out image2);
                        }
                        if (image2 == null)
                        {
                            LOG.log(string.Format("{0}：相机二获取图片为空", "IdentifyCameraForm-StartShowImageThread"));
                            continue;
                        }
                    }

                    if (MessageBus.MainThreadS.Count >= 3)
                    {
                        if (MessageBus.MainThreadS[2].HistoryActiveNum > 0)
                        {
                            MessageBus.MainThreadS[2].GetShowImage(2000, out image3);
                        }
                        else
                        {
                            MessageBus.MainThreadS[2].GetNullShowImage(4096, 2000, out image3);
                        }
                        if (image3 == null)
                        {
                            LOG.log(string.Format("{0}：相机三获取图片为空", "IdentifyCameraForm-StartShowImageThread"));
                            continue;
                        }
                    }

                    if (MessageBus.MainThreadS.Count >= 4)
                    {
                        if (MessageBus.MainThreadS[3].HistoryActiveNum > 0)
                        {
                            MessageBus.MainThreadS[3].GetShowImage(2000, out image4);
                        }
                        else
                        {
                            MessageBus.MainThreadS[3].GetNullShowImage(4096, 2000, out image4);
                        }
                        if (image4 == null)
                        {
                            LOG.log(string.Format("{0}：相机三获取图片为空", "IdentifyCameraForm-StartShowImageThread"));
                            continue;
                        }
                    }

                    Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        BitmapImage thumbnailImage1 = null;
                        BitmapImage thumbnailImage2 = null;
                        BitmapImage thumbnailImage3 = null;
                        BitmapImage thumbnailImage4 = null;
                        if (image1 != null)
                        {
                            thumbnailImage1 = ConvertToBitmapImage(image1);
                            MessageBus.ShowBinding.ThumbnailImage1 = thumbnailImage1;
                        }
                        if (image2 != null)
                        {
                            thumbnailImage2 = ConvertToBitmapImage(image2);
                            MessageBus.ShowBinding.ThumbnailImage2 = thumbnailImage2;
                        }
                        if (image3 != null)
                        {
                            thumbnailImage3 = ConvertToBitmapImage(image3);
                            MessageBus.ShowBinding.ThumbnailImage3 = thumbnailImage3;
                        }
                        if (image4 != null)
                        {
                            thumbnailImage4 = ConvertToBitmapImage(image4);
                            MessageBus.ShowBinding.ThumbnailImage4 = thumbnailImage4;
                        }
                        if (MessageBus.NowLoadCameraIndex == 0)
                        {
                            MessageBus.ShowBinding.BitmapImage = thumbnailImage1;
                        }
                        else if (MessageBus.NowLoadCameraIndex == 2)
                        {
                            MessageBus.ShowBinding.BitmapImage = thumbnailImage2;
                        }
                        else if (MessageBus.NowLoadCameraIndex == 3)
                        {
                            MessageBus.ShowBinding.BitmapImage = thumbnailImage3;
                        }
                        else if (MessageBus.NowLoadCameraIndex == 4)
                        {
                            MessageBus.ShowBinding.BitmapImage = thumbnailImage4;
                        }
                    }));
                    //进行精准20帧控制
                    int elapsed = (int)renderSW.ElapsedMilliseconds;
                    //Console.WriteLine(elapsed);
                    if (elapsed < targetMsPerFrame)
                    {
                        Thread.Sleep(targetMsPerFrame - elapsed);
                    }
                    //Thread.Sleep(50);
                }
            });
        }

        /// <summary>
        ///  停止更新显示数据线程
        /// </summary>
        private void StopUpdataShowDataThread()
        {
            IsShow = false;
        }


        /// <summary>
        /// 更新数粒显示数据
        /// </summary>
        private void UpdataShuLiShowData()
        {
            if (MessageBus.MainThreadS.Count == 0) return;
            if(MessageBus.NowLoadCameraIndex ==  -1) return;
            if (MessageBus.MainThreadS[MessageBus.NowLoadCameraIndex].ShuLiState)
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    MessageBus.ShowBinding.CameraStaticColor = MessageBus.MainThreadS[MessageBus.NowLoadCameraIndex].CameraRunStatic == true
                        ? System.Windows.Media.Brushes.Green : System.Windows.Media.Brushes.Red;
                    MessageBus.ShowBinding.CamRunStatic = MessageBus.MainThreadS[MessageBus.NowLoadCameraIndex].CameraRunStatic == true 
                        ? "运行中" : "未运行";
                });
            }
            else
            {
                Application.Current.Dispatcher.Invoke(() =>
                {

                    MessageBus.ShowBinding.CameraStaticColor = System.Windows.Media.Brushes.Yellow;
                    MessageBus.ShowBinding.CamRunStatic = "视野遮挡";
                });
            }
            MessageBus.ShowBinding.AllActiveNum = MessageBus.MainThreadS[MessageBus.NowLoadCameraIndex].HistoryActiveNum.ToString();
            MessageBus.ShowBinding.AllOkNum = MessageBus.MainThreadS[MessageBus.NowLoadCameraIndex].OkHistoryNum.ToString();
            MessageBus.ShowBinding.AllNgNum = MessageBus.MainThreadS[MessageBus.NowLoadCameraIndex].NgHistoryNum.ToString();
            MessageBus.ShowBinding.ShuLiSpeed = MessageBus.MainThreadS[MessageBus.NowLoadCameraIndex].GetOneSecondActiveNum().ToString();
        }

        /// <summary>
        /// 更新监控信息
        /// </summary>
        private void UpdateMonitorMessage()
        {
            MessageBus.ShowBinding.RamMonitor = monitor.GetAvailableMemory() > 1024 ? $"可用内存: {(monitor.GetAvailableMemory() / 1024).ToString("0.00")}GB" : $"可用内存: {monitor.GetAvailableMemory()}MB";
            MessageBus.ShowBinding.CPUMonitor = $"CPU: {monitor.GetCpuUsage().ToString("0.00")}%";
        }

        // Bitmap 转 BitmapImage 的辅助方法
        private BitmapImage ConvertToBitmapImage(Bitmap bitmap)
        {
            using (MemoryStream memory = new MemoryStream())
            {
                bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
                memory.Position = 0;
                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.StreamSource = memory;
                bitmapImage.EndInit();
                return bitmapImage;
            }
        }

        private void InitCamComboboxValue()
        {
            List<CameraInfoClass> CameraInfoList = new List<CameraInfoClass>();
            MessageBus.CameraClass.GetCameraList(out CameraInfoList);
            if (CameraInfoList.Count > 0)
            {
                MessageBus.ShowBinding.CameraItems.Clear();
                MessageBus.ShowBinding.CameraItems.Add(new CameraCoboxItem() { Name = "请选择相机", SNValue = "" });
                foreach (var item in CameraInfoList)
                {
                    MessageBus.ShowBinding.CameraItems.Add(new CameraCoboxItem()
                    {
                        Name = item.DeviceName + "_" + item.DeviceSN,
                        SNValue = item.DeviceSN
                    });
                }
            }
        }
        #endregion

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ShowUri = new Uri("WpfPage\\SettingPage.xaml", UriKind.Relative);
            ShowFrame.Navigate(ShowUri);
        }
    }
}
