using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Diagnostics;

namespace WindowsFormsApp
{
    public partial class PenDraw : UserControl
    {
        //GDI+
        Graphics DrawGraphic = null;
        //笔画坐标点
        private List<Point> Stroke=new List<Point>();
        //定义画布高792
        private const int IMG_HEIGHT = 792;
        //定义画布宽560
        private const int IMG_WIDHT = 560;
        //本示例适用于A4点阵纸书写，相关尺寸根据A4点阵纸进行了缩放
        //不同尺寸点阵纸点阵宽高尺寸计算方法为：纸张物理尺寸（毫米）/0.3 *8,详见 开发必读.pdf 文档
        //A4点阵纸点阵高度
        private const int A4_DOT_HEIGHT = 7920;
        //A4点阵纸点阵宽度

        private const int A4_DOT_WIDTH = 5600;
        //序列号
        private string PenSerial = string.Empty;
        public PenDraw(string penSerial)
        {
            PenSerial = penSerial;
            InitializeComponent();
            InitDraw();
            this.Width = 280;
            this.Height = 396;
        }
        private void InitDraw()
        {
            Bitmap bitmap = new Bitmap(IMG_WIDHT, IMG_HEIGHT);
            DrawGraphic = Graphics.FromImage(bitmap);
            double scale = IMG_HEIGHT * 1.0 / A4_DOT_HEIGHT;
            DrawGraphic.FillRectangle(Brushes.AliceBlue, 0, 0, IMG_WIDHT, IMG_HEIGHT);
            
            DrawGraphic.DrawString(PenSerial, new Font("宋体", 45), Brushes.Black, 0, 0);
            pictureBox.Image = bitmap;
            DrawGraphic.ScaleTransform((float)scale, (float)scale);
            DrawGraphic.SmoothingMode = SmoothingMode.AntiAlias;
        }
        public void OnPenDown(ulong time, string penSerial, int penType)
        {
            
        }
        //抬笔后将坐标一次性画出
        public void OnPenUp(ulong time, string penSerial, int penType)
        {
            if (this.InvokeRequired)
            {
                Action<ulong, string, int> action = new Action<ulong, string, int>(OnPenUp);
                this.Invoke(action, new object[] { time, penSerial, penType });
            }
            else
            {
               
                int leftPoints = Stroke.Count % 3;
                if (0 != leftPoints)
                {
                    int from = Stroke.Count - leftPoints - 1;
                    if (from < 0)
                        from = 0;
                    int to = Stroke.Count - 1;
                    DrawCoordinates(from, to);
                }
                Stroke.Clear();
            }
        }
        private void DrawCoordinates(int from, int to)
        {
            if (pictureBox.InvokeRequired)
            {
                Action<int, int> action = new Action<int, int>(DrawCoordinates);
                this.Invoke(action, new object[] { from, to });
            }
            else
            {
                Point[] points = new Point[to - from + 1];

                int l = Stroke[from].X, r = Stroke[from].X, t = Stroke[from].Y, b = Stroke[to].Y;
                for (int i = from; i <= to; i++)
                {
                    points[i - from] = Stroke[i];
                    l = Math.Min(l, Stroke[i].X);
                    r = Math.Max(r, Stroke[i].X);
                    t = Math.Min(t, Stroke[i].Y);
                    b = Math.Max(b, Stroke[i].Y);
                }

                Pen pen = new Pen(new SolidBrush(Color.Blue), 3);
                if (points.Length == 1)
                    DrawGraphic.DrawLine(pen, points[0], points[0]);
                else if (points.Length == 2)
                    DrawGraphic.DrawLine(pen, points[0], points[1]);
                else
                    DrawGraphic.DrawCurve(pen, points);
                pen.Dispose();
                l = (int)(1.0 * l / A4_DOT_WIDTH * pictureBox.Width) - 5;
                r = (int)(1.0 * r / A4_DOT_WIDTH * pictureBox.Width) + 5;
                t = (int)(1.0 * t / A4_DOT_HEIGHT * pictureBox.Height) - 5;
                b = (int)(1.0 * b / A4_DOT_HEIGHT * pictureBox.Height) + 5;
               
                Rectangle rec = new Rectangle(l, t, r - l, b - t);
                pictureBox.Invalidate(rec);
            }
        }
        public void OnPenCoordinate(ulong time, string penSerial, int penType, string pageSerial, int cx, int cy, ushort force)
        {
            Stroke.Add(new Point(cx, cy));
            if (Stroke.Count % 3 == 0)
            {
                int from = Stroke.Count - 3 - 1;
                if (from < 0)
                    from = 0;
                int to = Stroke.Count - 1;
                DrawCoordinates(from, to);
            }
        }
    }
}
