using Nirvana.Common;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Timers;
using System.Windows.Forms;
using Timer = System.Timers.Timer;

namespace TianShengTool
{
    public partial class Form1 : Form
    {
        private ScanHook scanerHook = new ScanHook();
        private bool IsPrint = false; //是否正在打印,false-否,true-是
        private DateTime? PrintTime = null;

        public Form1()
        {
            InitializeComponent();
            //记在打印机
            LoadPrinters();
            //定时器，1秒更新一次
            var timer = new Timer
            {
                AutoReset = true,
                Enabled = true,
                Interval = 1000
            };

            timer.Elapsed += this.Timer_Elapsed;
        }

        /// <summary>
        /// 加载本地打印机列表
        /// </summary>
        /// <returns></returns>
        public void LoadPrinters()
        {
            var list = new List<string>();
            var defaultprinter = new PrintDocument().PrinterSettings.PrinterName;
            list.Add(defaultprinter);
            this.comboBox_printer.Items.Add(defaultprinter);
            this.comboBox_printer.SelectedIndex = 0;
            foreach (string fprintname in PrinterSettings.InstalledPrinters)
            {
                if (!list.Contains(fprintname))
                {
                    list.Add(fprintname);
                    this.comboBox_printer.Items.Add(fprintname);
                }
            }
        }

        /// <summary>
        /// 按比例缩放图片
        /// </summary>
        /// <param name="SourceImage"></param>
        /// <param name="M"></param>
        /// <param name="N"></param>
        /// <returns></returns>
        public Image ZoomPicture(Image SourceImage, float M, float N)
        {
            int IntWidth; //新的图片宽
            int IntHeight; //新的图片高
            int TargetWidth = (int)(M * SourceImage.Width); //取整，是因为下面的Bitmap的两个参数只能为整数
            int TargetHeight = (int)(N * SourceImage.Height);
            try
            {
                ImageFormat format = SourceImage.RawFormat;
                Bitmap SaveImage = new Bitmap(TargetWidth, TargetHeight);
                Graphics g = Graphics.FromImage(SaveImage);
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g.CompositingQuality = CompositingQuality.HighQuality;

                g.Clear(Color.White);

                //计算缩放图片的大小
                IntHeight = TargetHeight;
                IntWidth = TargetWidth;
                g.DrawImage(SourceImage, 0, 0, IntWidth, IntHeight); //在指定坐标处画指定大小的图片
                SourceImage.Dispose();

                return SaveImage;
            }
            catch (Exception ex)
            {
            }

            return null;
        }

        /// <summary>
        /// 定时器处理
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event args.</param>
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            this.BeginInvoke(
                (MethodInvoker)delegate
                {
                    this.button_start.Enabled = !ScanHook.IsStart;
                    this.button_stop.Enabled = ScanHook.IsStart;
                    this.textBox_num.Enabled = !ScanHook.IsStart;
                    this.textBox_PaperHeight.Enabled = !ScanHook.IsStart;
                    this.textBox_PaperWidth.Enabled = !ScanHook.IsStart;
                    this.button_printer.Enabled = this.listBox1.Items.Count > 0 && !IsPrint ? true : false;
                    this.button_printer.Text = this.IsPrint ? "正在打印" : "打印";
                    this.comboBox_printer.Enabled = !ScanHook.IsStart;
                    this.textBox_x.Enabled = !ScanHook.IsStart;
                    this.textBox_y.Enabled = !ScanHook.IsStart;
                    this.richTextBox1_logger.ReadOnly = ScanHook.IsStart;
                    this.textBox_marginw.Enabled = !ScanHook.IsStart;
                    this.textBox_str.Enabled = !ScanHook.IsStart;
                });
        }

        /// <summary>
        /// 开启钩子
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_start_Click(object sender, EventArgs e)
        {
            scanerHook.Start();
            scanerHook.ScanerEvent += new ScanHook.ScanerDelegate(ScanerHook_BarCodeEventAsync);
        }

        /// <summary>
        /// 关闭钩子
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_stop_Click(object sender, EventArgs e)
        {
            scanerHook.Stop();
            scanerHook = new ScanHook();
        }

        /// <summary>
        /// 扫码结果
        /// </summary>
        /// <param name="scanerCodes"></param>
        private void ScanerHook_BarCodeEventAsync(ScanHook.ScanerCodes scanerCodes)
        {
            if (PrintTime.HasValue && (DateTime.Now - PrintTime.Value).TotalSeconds < 2)
            {
                return;
            }
            var text = scanerCodes.Result;
            string code = text;
            if (!string.IsNullOrEmpty(text))
            {
                if (text.ToLower().StartsWith("http"))
                {
                    var arr = text.Split('?');
                    if (arr.Length == 2)
                    {
                        arr = arr[1].Split('=');
                        if (arr.Length == 2)
                        {
                            code = arr[1];
                        }
                    }
                }
            }
            if (code.Length < 5)
            {
                AddLogger($"二维码内容过短,最少为5个字");
                return;
            }
            //检测装箱台数
            int cnt = this.textBox_num.Text.ToInt();
            if (this.listBox1.Items.Count < cnt)
            {
                if (!this.listBox1.Items.Contains(code))
                {
                    this.listBox1.Items.Add(code);
                }
            }
            if (this.listBox1.Items.Count == cnt)
            {
                CreateImage();
                StartPrint();
            }
        }

        /// <summary>
        /// 开始打印
        /// </summary>
        private void StartPrint()
        {
            if (IsPrint)
            {
                return;
            }
            int width = this.textBox_PaperWidth.Text.ToInt();
            int height = this.textBox_PaperHeight.Text.ToInt();
            if (width <= 0 || height <= 0)
            {
                MessageBox.Show("纸张宽度/高度不可小于0");
                return;
            }
            if (this.comboBox_printer.SelectedItem == null)
            {
                MessageBox.Show("请先选择打印机");
                return;
            }
            string printer = this.comboBox_printer.SelectedItem.ToString();//选择的打印机
            if (string.IsNullOrEmpty(printer))
            {
                MessageBox.Show("请先选择打印机");
                return;
            }
            var printerRes = new PrinterResolution();
            printerRes.Kind = PrinterResolutionKind.High;
            PrintDocument fPrintDocument = new PrintDocument();
            fPrintDocument.PrinterSettings.PrinterName = printer;
            fPrintDocument.PrinterSettings.Copies = 1;
            fPrintDocument.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
            fPrintDocument.DefaultPageSettings.PaperSize = new PaperSize("", width, height);
            var a = fPrintDocument.DefaultPageSettings.PrinterResolution;
            fPrintDocument.DefaultPageSettings.PrinterResolution = printerRes;
            fPrintDocument.BeginPrint += startprint;
            fPrintDocument.EndPrint += endprint;
            fPrintDocument.PrintPage += printboxpage;
            fPrintDocument.Print();
        }

        /// <summary>
        /// 开始打印
        /// </summary>
        /// <param name="sender"></param>
        /// 202
        /// <param name="e"></param>
        private void startprint(object sender, PrintEventArgs e)
        {
            AddLogger($"开始打印,台数{this.listBox1.Items.Count}台");
            this.IsPrint = true;
            this.listBox1.Items.Clear();
        }

        /// <summary>
        /// 打印结束
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void endprint(object sender, PrintEventArgs e)
        {
            AddLogger($"打印完成");
            this.listBox1.Items.Clear();
            this.IsPrint = false;
        }

        /// <summary>
        /// 画写打印页面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void printboxpage(object sender, PrintPageEventArgs e)
        {
            try
            {
                int width = this.textBox_PaperWidth.Text.ToInt();
                int height = this.textBox_PaperHeight.Text.ToInt();
                int mw = this.textBox_marginw.Text.ToInt();
                int x = this.textBox_x.Text.ToInt();
                int y = this.textBox_y.Text.ToInt();
                var img = this.pictureBox1.Image;

                e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
                e.Graphics.DrawImage(img, x, y, width - mw, height - mw);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 生成图片
        /// </summary>
        private int CreateImage()
        {
            #region 开始画图

            // 加载基础图
            var basepicpath = $"{Directory.GetCurrentDirectory()}/base.png";
            string fontfamily = "仿宋";//字体
            //开始画图
            int height = this.pictureBox1.Height;
            int width = this.pictureBox1.Width;
            var image = Image.FromFile(basepicpath);
            var n = height * 1.0f / image.Height * 1.0f;
            var m = width * 1.0f / image.Width * 1.0f;
            image = ZoomPicture(image, m, n);
            Bitmap bmp = (Bitmap)image;
            Graphics g = Graphics.FromImage(bmp);
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            Font textfont = new Font(fontfamily, 13, FontStyle.Bold);
            Brush textbrush = new SolidBrush(Color.Black);
            // 画台数
            int cnt = this.textBox_num.Text.ToInt();
            //g.DrawString("12122", textfont, textbrush, 0, 40);
            // 生成条形码
            int margintop = 140;
            int marginleft = 10;
            foreach (var item in this.listBox1.Items)
            {
                var val = item.ToString();
                // 遍历条码
                using (Bitmap map = BarcodeHelper.BarCode(val, 240, 30))
                {
                    g.DrawImage(map, marginleft, margintop, 240, 30);
                    g.DrawString($"{val}", textfont, textbrush, marginleft, margintop + 35);
                    margintop += 58;
                }
            }
            var bfont = new Font(fontfamily, 14, FontStyle.Bold);
            g.DrawString(this.textBox_str.Text, bfont, textbrush, marginleft, margintop + 20);
            g.Dispose();

            //bmp.Save($"{AppDomain.CurrentDomain.BaseDirectory}/reg/{DateTime.Now.ToString("yyyyMMdd")}/{DateTime.Now.ToString("yyyyMMddHHmmss")}.png", ImageFormat.Png);
            this.pictureBox1.Image = bmp;

            #endregion 开始画图

            return 0;
        }

        /// <summary>
        /// 打印日志
        /// </summary>
        /// <param name="text"></param>
        private void AddLogger(string text)
        {
            var PrintTime = DateTime.Now;
            this.richTextBox1_logger.Text += $"{PrintTime}:{text}\r\n";
        }

        /// <summary>
        /// 开始打印
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_printer_Click(object sender, EventArgs e)
        {
            CreateImage();
            StartPrint();
        }
    }
}