#define ENABLE_PACK


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ProtoBuf;
using Protobuf.Text;
using Media;
using NumMachine;
using tool;
using MessageBoxEE;
using System.Diagnostics;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace ct_terminal
{


    public partial class MainForm : Form
    {
        //自适应窗口大小
        AutoResizeForm m_auto_resize_form = new AutoResizeForm();
        //播放器
        MediaPlayer m_mediaPlayer = new MediaPlayer();
        //停车反馈接收器       
        consumer m_park_consumer = new consumer();
        //取车反馈接收器
        consumer m_pick_consumer = new consumer();
        //发送器
        producer m_producer = new producer();
        //号牌机数据
        private TimedData<string> m_timed_car_license = new TimedData<string>("");
        //终端号
        private int m_ternimalID;
        //单元号
        private int m_unitID;
        //rabbitmq连接参数  从配置文件读取
        private string m_rabbitmq_ip;
        private int m_rabbitmq_port;
        private string m_rabbitmq_user;
        private string m_rabbitmq_password;
        private string m_rabbitmq_ex_name;
        //获取号牌机线程
        private NumMachineLinker m_car_number;
        private bool m_car_number_condition;
        private Thread m_car_number_thread;
        //停车指令反馈
        private TimedData<string> m_park_command_response = new TimedData<string>("");
        //取车指令反馈

        private TimedData<string> m_pick_command_response = new TimedData<string>("");
        private Process m_process = null;
        private string m_image_path;
        private static readonly object Lock = new object();
        public MainForm()
        {
            InitializeComponent();
            //初始化json文件操作
            json_file_operation.Instance.json_file_operation_init();
            m_ternimalID = int.Parse(json_file_operation.Instance.read_json_string("ternimalNumber"));
            m_unitID = int.Parse(json_file_operation.Instance.read_json_string("unitNumber"));
            //读取rabbitmq相关配置
            m_rabbitmq_ip = json_file_operation.Instance.read_json_string("RabbitMQ_ip");
            m_rabbitmq_port = int.Parse(json_file_operation.Instance.read_json_string("RabbitMQ_port"));
            m_rabbitmq_user = json_file_operation.Instance.read_json_string("RabbitMQ_user");
            m_rabbitmq_password = json_file_operation.Instance.read_json_string("RabbitMQ_password");
            m_rabbitmq_ex_name = json_file_operation.Instance.read_json_string("RabbitMQ_ex_name");


            //初始化播放器
            m_mediaPlayer.MediaPlayerInit(this, ref this.ImagePictureBox, ref this.vlcControl1, ref this.time_label, ref this.date_label_1, ref this.date_label_2);
            //初始化发送指令
            m_producer.producer_init(m_rabbitmq_ip, m_rabbitmq_port, m_rabbitmq_user, m_rabbitmq_password);
            ////初始化消费指令
            string t_pick_queue_key = "pick_response_" + m_ternimalID.ToString() + "_queue";
            m_pick_consumer.consumer_init(m_rabbitmq_ip, m_rabbitmq_port, m_rabbitmq_user, m_rabbitmq_password, t_pick_queue_key, pick_response_thread);

            m_image_path = System.AppDomain.CurrentDomain.BaseDirectory + "./Resource/";

#if ENABLE_PACK
            //获取号牌线程
            m_car_number = new NumMachine.NumMachineLinker();
            m_car_number_condition = true;
            m_car_number_thread = new Thread(get_car_number_thread);

            //初始化打印机
            PrintManual.Instance.PrintManualInit();

            //初始化消费指令
            string t_park_queue_key = "park_response_" + m_ternimalID.ToString() + "_queue";
            m_park_consumer.consumer_init(m_rabbitmq_ip, m_rabbitmq_port, m_rabbitmq_user, m_rabbitmq_password, t_park_queue_key, park_response_thread);
#else
                this.parkingBtn.BackgroundImage = Image.FromFile(m_image_path + "parkingBtn_gray.BackgroundImage.png");
                this.parkingBtn.Enabled = false;
#endif
        }
        private void MainForm_Load(object sender, EventArgs e)
        {
            this.terminal_number_label.Text = "智象泊车终端" + json_file_operation.Instance.read_json_string("ternimalNumber").ToString() + "号机";
            this.terminal_number_english_label.Text = this.terminal_number_english_label.Text + json_file_operation.Instance.read_json_string("ternimalNumber");
            if (MessageBox.Show("是否最大化？", "tip", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == DialogResult.Yes)
            {
                //设置最大化
                this.WindowState = FormWindowState.Maximized;
            }
            m_auto_resize_form.controllInitializeSize(this);

            //启动播放器
            m_mediaPlayer.mediaplayer_run();

            //启动接受反馈
            m_pick_consumer.run();

#if ENABLE_PACK
            //启动号牌机
            m_car_number.Start();
            m_car_number_thread.Start();
            //启动打印机
            PrintManual.Instance.Start();

            m_park_consumer.run();
            //启动子程序
            Process[] myprocess = Process.GetProcessesByName("UnNomalized_node");
            if (myprocess.Count() == 0)
            {
                try
                {
                    m_process = new Process();//创建一个新的进程
                    m_process.StartInfo.FileName = @".\pyqt_ui\node.exe"; ;//要启动的应用程序
                    m_process.Start();
                }
                catch (Exception) { }
            }
#endif

        }
        public string randomNumer()
        {
            Random r = new Random();
            char E1 = (char)r.Next(65, 90);
            char E2 = (char)r.Next(65, 90);
            int N1 = r.Next(10, 99);
            string n1 = N1.ToString();
            int N2 = r.Next(9);
            string n2 = N2.ToString();
            int N3 = r.Next(9);
            string number = "鄂" + E1 + n1 + E2 + n2 + N3;
            return number;
        }

        private void parkingBtn_Click(object sender, EventArgs e)
        {
            //string car_license = randomNumer();
            string car_license = "";
            if (m_timed_car_license.IsTimeout() == false && m_timed_car_license.Value != "")
            {
                car_license = m_timed_car_license.Value;
            }
            else
            {
                MessageBoxEe messageBoxEe = new MessageBoxEe();
                messageBoxEe.Show("号牌机未拍摄到有效号牌，请尝试重新进入！");
                return;
            }
            //创建一个停车表单
            park_table park_Table = new park_table();
            park_Table.Statu = new table_statu();
            park_Table.Statu.ExecuteStatu = STATU.ENormal;
            park_Table.Statu.StatuDescription = "正常";
            park_Table.TerminalId = m_ternimalID;
            park_Table.UnitId = m_unitID;
            park_Table.CarNumber = car_license;
            m_park_command_response = "";

            if (m_producer.send(park_Table.ToText(), "command_ex", "user_command_port") == false)
            {
                MessageBoxEe messageBoxEe = new MessageBoxEe();
                messageBoxEe.Show("服务器连接失败！请联系管理员！");
                return;
            }
            this.parkingBtn.BackgroundImage = Image.FromFile(m_image_path + "parkingBtn_gray.BackgroundImage.png");
            this.parkingBtn.Enabled = false;
            while (!m_park_command_response.IsTimeout())
            {
                if (m_park_command_response.Value != "")
                    break;
            }
            if (m_park_command_response.IsTimeout() && m_park_command_response.Value == "")
            {
                MessageBoxEe messageBoxEe = new MessageBoxEe();
                messageBoxEe.Show("反馈超时，请重试或联系管理员！");
            }
            else
            {
                try
                {
                    park_table response_Table = park_table.Parser.ParseText(m_park_command_response.Value);
                    //response_Table.PrimaryKey = "ddddddddddd";
                    if (response_Table.Statu.ExecuteStatu == STATU.ENormal && response_Table.PrimaryKey != "")
                    {
                        PrintManual.Instance.PrintTicket(response_Table.PrimaryKey, response_Table.CarNumber);
                        MessageBoxEe messageBoxEe = new MessageBoxEe();
                        messageBoxEe.Show(response_Table.CarNumber + " 停车成功，请取走您的小票！");
                        Task.Factory.StartNew(() =>
                        {
                            Thread.Sleep(5000);
                            //停车成功需要清除车牌号
                            lock (Lock)
                            {
                                m_timed_car_license = "";
                            }
                        });
                    }
                    else
                    {
                        MessageBoxEe messageBoxEe = new MessageBoxEe();
                        messageBoxEe.Show(response_Table.Statu.StatuDescription);
                    }
                }
                catch (Exception ex)
                {
                    MessageBoxEe messageBoxEe = new MessageBoxEe();
                    messageBoxEe.Show("反馈解析失败！\n" + ex.StackTrace);
                }
            }
            m_park_command_response = "";
            this.parkingBtn.BackgroundImage = Image.FromFile(m_image_path + "parkingBtn.BackgroundImage.png");
            this.parkingBtn.Enabled = true;

        }
        private void pickupBtn_Click(object sender, EventArgs e)
        {
            FetchingFrom fetchingFrom = new FetchingFrom();
            fetchingFrom.StartPosition = FormStartPosition.CenterScreen;
            fetchingFrom.BringToFront();
            fetchingFrom.ShowDialog();
            if (fetchingFrom.m_is_return)
                return;

            //创建一个取车表单
            pick_table pick_Table = new pick_table();
            pick_Table.Statu = new table_statu();
            pick_Table.Statu.ExecuteStatu = STATU.ENormal;
            pick_Table.Statu.StatuDescription = "正常";
            pick_Table.PrimaryKey = fetchingFrom.m_key;
            pick_Table.TerminalId = m_ternimalID;


            m_pick_command_response = "";
            if (m_producer.send(pick_Table.ToText(), "command_ex", "user_command_port") == false)
            {
                MessageBoxEe messageBoxEe = new MessageBoxEe();
                messageBoxEe.Show("服务器连接失败！请联系管理员！");
                return;
            }
            this.pickupBtn.BackgroundImage = Image.FromFile(m_image_path + "fetchingBtn_gray.BackgroundImage.png");
            this.pickupBtn.Enabled = false;
            while (!m_pick_command_response.IsTimeout())
            {
                if (m_pick_command_response.Value != "")
                    break;
               
            }
            if (m_pick_command_response.IsTimeout() && m_pick_command_response.Value == "")
            {
                MessageBoxEe messageBoxEe = new MessageBoxEe();
                messageBoxEe.Show("反馈超时，请重试或联系管理员！");
            }
            else
            {
                try
                {
                    pick_table response_Table = new pick_table();
                    response_Table = pick_table.Parser.ParseText(m_pick_command_response.Value);
                    if (response_Table.Statu.ExecuteStatu == STATU.ENormal)
                    {
                        MessageBoxEe messageBoxEe = new MessageBoxEe();
                        messageBoxEe.Show(response_Table.CarNumber + " 取车成功，请观察LED屏幕提示取车！");
                    }
                    else
                    {
                        MessageBoxEe messageBoxEe = new MessageBoxEe();
                        messageBoxEe.Show(response_Table.Statu.StatuDescription);
                    }
                }
                catch (Exception ex)
                {
                    MessageBoxEe messageBoxEe = new MessageBoxEe();
                    messageBoxEe.Show("反馈解析失败！\n" + ex.StackTrace);
                }
            }
            m_pick_command_response = "";
            this.pickupBtn.BackgroundImage = Image.FromFile(m_image_path + "fetchingBtn.BackgroundImage.png");
            this.pickupBtn.Enabled = true;
        }
        //停车反馈线程
        void park_response_thread(string msg, ref IModel channel, ref BasicDeliverEventArgs args)
        {
            Console.WriteLine("停车反馈：" + msg);
            if (msg != null && msg != "")
            {
                m_park_command_response = msg;
                m_park_command_response.Set_timeout_ms(3000);
            }
            //返回消息确认
            channel.BasicAck(args.DeliveryTag, true);
        }
        //取车反馈线程
        void pick_response_thread(string msg, ref IModel channel, ref BasicDeliverEventArgs args)
        {
            Console.WriteLine("取车反馈：" + msg);
            if (msg != null && msg != "")
            {
                m_pick_command_response = msg;
                m_pick_command_response.Set_timeout_ms(3000);
            }
            //返回消息确认
            channel.BasicAck(args.DeliveryTag, true);

        }
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {

            Process[] proc = Process.GetProcessesByName("node");
            for (int i = 0; i < proc.Length; i++)
            {
                proc[i].Kill();  //逐个结束进程.
            }

            //关闭播放器
            m_mediaPlayer.mediaplayer_uninit();
#if ENABLE_PACK
            //关闭打印机
            PrintManual.Instance.Close();
            //关闭号牌机连接
            m_car_number.Stop();
            m_car_number_condition = false;
            if (m_car_number_thread.IsAlive)
            {
                m_car_number_thread.Abort();
            }
#endif
        }


        /// <summary>
        /// 获取号牌线程
        /// </summary>
        private void get_car_number_thread()
        {
            while (m_car_number_condition == true)
            {
                string number = m_car_number.GetLicensePlate(0);
                //   Console.WriteLine("号牌机接收到号牌："+number);
                if (number != null && number != "")
                {
                    lock (Lock)
                    {
                        m_timed_car_license = number;
                        m_timed_car_license.Set_timeout_ms(900000);
                    }

                    //   MessageBoxEe.Show(m_timed_car_license.Value);
                }
                if (!m_timed_car_license.IsTimeout() && m_timed_car_license.Value != "")
                {
                    terminal_node_statu terminal_Node_Statu = new terminal_node_statu();
                    terminal_Node_Statu.TerminalId = m_ternimalID;
                    terminal_Node_Statu.CarNumber = m_timed_car_license.Value;
                    m_producer.send(terminal_Node_Statu.ToText(), "statu_ex", "terminal_node_" + m_ternimalID.ToString() + "_statu_port");
                }

                Thread.Sleep(500);
            }
        }


        //设置天气
        public void set_weatherLab_text(string str)
        {
            this.weather_label.Text = str;
        }
        //设置气温
        public void set_temperatureLab_text(string str)
        {
            this.temperature_label.Text = str;
        }

        private void vlcControl1_VlcLibDirectoryNeeded(object sender, Vlc.DotNet.Forms.VlcLibDirectoryNeededEventArgs e)
        {
            var currentAssembly = Assembly.GetEntryAssembly();
            var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName;

            if (currentDirectory == null)
                return;
            if (IntPtr.Size == 4)
                e.VlcLibDirectory = new DirectoryInfo(Path.GetFullPath(@".\libvlc\win-x86\"));
            else
                e.VlcLibDirectory = new DirectoryInfo(Path.GetFullPath(@".\libvlc\win-x64\"));

            if (!e.VlcLibDirectory.Exists)
            {
                var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
                folderBrowserDialog.Description = "Select Vlc libraries folder.";
                folderBrowserDialog.RootFolder = Environment.SpecialFolder.Desktop;
                folderBrowserDialog.ShowNewFolderButton = true;
                if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
                {
                    e.VlcLibDirectory = new DirectoryInfo(folderBrowserDialog.SelectedPath);
                }
            }

        }

        private void MainForm_SizeChanged(object sender, EventArgs e)
        {
            m_auto_resize_form.controlAutoSize(this);
        }

        private void parkingBtn_KeyDown(object sender, KeyEventArgs e)
        {
            MessageBoxEe messageBoxEe = new MessageBoxEe();
            messageBoxEe.Show("取车请先点击取车按钮再扫码！");
        }

        private void pickupBtn_KeyPress(object sender, KeyPressEventArgs e)
        {
            MessageBoxEe messageBoxEe = new MessageBoxEe();
            messageBoxEe.Show("取车请先点击取车按钮再扫码！");
        }
    }
}
