using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;

namespace Common.system
{
    internal enum ZPenType : byte
    {
        Pen = 1,
        Erase = 2
    };
    /// <summary>
    /// 画板线模型
    /// </summary>
    internal class ZBBPage
    {
        /// <summary>
        /// 线
        /// </summary>
        public List<ZBBPageStep> lines { get; set; }
        /// <summary>
        /// 历史记录
        /// </summary>
        public List<ZBBPageStep> lines_histoty { get; set; }
        /// <summary>
        /// 画板模型
        /// </summary>
        public ZBBPage()
        {
            lines = new List<ZBBPageStep>();
            lines_histoty = new List<ZBBPageStep>();
        }
    }

    internal class ZBBPageStep
    {
        public StrokeCollection lines_curr { get; set; }
        public StrokeCollection lines_add { get; set; }
        public StrokeCollection lines_remove { get; set; }

        public ZBBPageStep()
        {
            lines_curr = new StrokeCollection();
            lines_add = new StrokeCollection();
            lines_remove = new StrokeCollection();
        }
    }
    public class BlackboardNew
    {
        private InkCanvas m_canvas;

        //private ZPenType type = ZPenType.Pen;
        /// <summary>
        /// 当前页索引
        /// </summary>
        private int pagenum = 0;
        /// <summary>
        /// 橡皮大小
        /// </summary>
        private readonly int erasesize = 64;
        /// <summary>
        /// 笔粗细
        /// </summary>
        private readonly int pensize = 3;
        /// <summary>
        /// 是否在进行撤销恢复操作
        /// </summary>
        private int undoOrRedo = 0;
        /// <summary>
        /// 笔颜色
        /// </summary>
        private Color pencolor;
        /// <summary>
        /// 所有画板线
        /// </summary>
        private readonly List<ZBBPage> strokes_page_all = new List<ZBBPage>();

        // 添加这个变量是因为在用橡皮擦时 一次操作会触发多次StrokesChanged回掉 这里是把多次回掉合并在一起
        private ZBBPageStep step = null;

        public BlackboardNew(InkCanvas canvas)
        {
            init(canvas, Colors.White);
        }

        public BlackboardNew(InkCanvas canvas, Color _pencolor)
        {
            init(canvas, _pencolor);
        }

        private DrawingAttributes drawingAttributes;
        private void init(InkCanvas canvas, Color _pencolor)
        {
            m_canvas = canvas;
            pencolor = _pencolor;
            ZBBPage page = new ZBBPage();
            page.lines.Add(new ZBBPageStep());
            strokes_page_all.Add(page);
            if (canvas != null)
            {
                canvas.EditingMode = InkCanvasEditingMode.Ink;
                drawingAttributes = new DrawingAttributes();
                canvas.DefaultDrawingAttributes = drawingAttributes;
                drawingAttributes.Width = pensize;
                drawingAttributes.Height = pensize;
                drawingAttributes.Color = pencolor;
                drawingAttributes.FitToCurve = true;
                drawingAttributes.IgnorePressure = false;
                canvas.Strokes.StrokesChanged += Strokes_StrokesChanged;
                canvas.StrokeCollected += Canvas_StrokeCollected;
                canvas.StrokeErasing += Canvas_StrokeErasing;
                canvas.StrokeErased += Canvas_StrokeErased;
                canvas.MouseUp += Canvas_MouseUp;
            }
        }

        private void Canvas_StrokeErasing(object sender, InkCanvasStrokeErasingEventArgs e)
        {
            undoOrRedo = 0;
        }

        private void Canvas_StrokeErased(object sender, RoutedEventArgs e)
        {
        }

        private void Canvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
        {
        }

        private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (step != null)
            {
                if (pagenum + 1 > strokes_page_all.Count)
                {
                    ZBBPage pagetemp = new ZBBPage();
                    pagetemp.lines.Add(new ZBBPageStep());
                    strokes_page_all.Add(pagetemp);
                }

                try
                {
                    ZBBPage page = strokes_page_all[pagenum];
                    if (page != null)
                    {
                        step.lines_curr.Add(m_canvas.Strokes);
                        page.lines.Add(step);
                        step = null;
                    }
                }
                catch (Exception ex)
                {
                    if (strokes_page_all != null)
                    {
                        if (strokes_page_all.Count == 0)
                        {
                            ZBBPage pagetemp = new ZBBPage();
                            pagetemp.lines.Add(new ZBBPageStep());
                            strokes_page_all.Add(pagetemp);
                        }
                    }
                    LogHelper.WriteErrLog("【画板】（Canvas_MouseUp）添加失败，strokes_page_all为0，" + ex.Message, ex);
                }
            }
        }

        private void Strokes_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e)
        {
            if (undoOrRedo > 0)
            {
                undoOrRedo -= 1;
                return;
            }

            if (step == null)
            {
                step = new ZBBPageStep();
            }

            // 笔模式
            if (e.Added.Count > 0 && e.Removed.Count == 0)
            {
                step.lines_add.Add(e.Added);
            }
            // 橡皮模式 会多次进入回掉
            else if (e.Removed.Count > 0)
            {
                step.lines_add.Add(e.Added);
                for (int i = 0; i < e.Removed.Count; i++)
                {
                    Stroke removeItem = e.Removed[i];
                    if (step.lines_add.Contains(removeItem))
                    {
                        step.lines_add.Remove(removeItem);
                    }
                    else
                    {
                        step.lines_remove.Add(removeItem);
                    }
                }
            }
        }

        // public方法 笔
        public void change_pen(Color _color)
        {
            //this.type = ZPenType.Pen;
            DrawingAttributes drawingAttributes = new DrawingAttributes();
            m_canvas.DefaultDrawingAttributes = drawingAttributes;
            drawingAttributes.Color = _color;
            drawingAttributes.Width = pensize;
            drawingAttributes.Height = pensize;
            drawingAttributes.FitToCurve = true;
            drawingAttributes.IgnorePressure = false;
            m_canvas.EditingMode = InkCanvasEditingMode.Ink;
        }

        // 橡皮
        public void change_erase()
        {
            //this.type = ZPenType.Erase;
            m_canvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
            m_canvas.EraserShape = new EllipseStylusShape(erasesize, erasesize, 0);
        }

        // 撤销
        public void undo()
        {
            ZBBPage page = strokes_page_all[pagenum];

            if (page != null && m_canvas.Strokes.Count > 0 && page.lines.Count > 1)
            {
                ZBBPageStep last = page.lines.Last();
                page.lines.Remove(last);
                page.lines_histoty.Add(last);
                if (page.lines.Last().lines_curr.Count > 0)
                {
                    undoOrRedo = 2;
                }
                else
                {
                    undoOrRedo = 1;
                }

                m_canvas.Strokes.Clear();
                m_canvas.Strokes.Add(page.lines.Last().lines_curr);
            }
        }

        // 恢复
        public void redo()
        {
            ZBBPage page = strokes_page_all[pagenum];
            if (page != null && page.lines_histoty.Count > 0)
            {
                ZBBPageStep line = page.lines_histoty[page.lines_histoty.Count - 1];

                page.lines.Add(line);
                page.lines_histoty.Remove(line);
                if (page.lines.Last().lines_curr.Count > 0)
                {
                    undoOrRedo = 2;
                }
                else
                {
                    undoOrRedo = 1;
                }
                m_canvas.Strokes.Clear();
                m_canvas.Strokes.Add(page.lines.Last().lines_curr);
            }
        }

        // 清空
        public void clear()
        {

            //ZBBPage page = new ZBBPage();
            //page.lines.Add(new ZBBPageStep());
            //page.lines = new List<ZBBPageStep>();
            //page.lines_histoty = new List<ZBBPageStep>();
            //strokes_page_all.Add(page);

            strokes_page_all.Clear();
            m_canvas.Strokes.Clear();
            //for (int i=0;i< strokes_page_all.Count;i++)
            //{
            //    ZBBPage page = strokes_page_all[pagenum];
            //    if (page != null)
            //    {
            //        m_canvas.Strokes.Clear();
            //        page.lines_histoty.Clear();
            //        page.lines.Clear();
            //        page.lines.Add(new ZBBPageStep());
            //    }
            //}


        }
        /// <summary>
        /// 翻页
        /// </summary>
        /// <param name="mpagenum"></param>
        public void changepage(int mpagenum)
        {
            if (pagenum != mpagenum)
            {
                pagenum = mpagenum;
                //新增页
                if (pagenum >= strokes_page_all.Count)
                {
                    int numadd = pagenum - strokes_page_all.Count + 1;
                    for (int i = 0; i < numadd; i++)
                    {
                        ZBBPage pagetemp = new ZBBPage();
                        pagetemp.lines.Add(new ZBBPageStep());
                        strokes_page_all.Add(pagetemp);
                    }
                }

                ZBBPage page = strokes_page_all[pagenum];
                if (page != null && page.lines.Count > 0)
                {
                    if (page.lines.Last().lines_curr.Count > 0)
                    {
                        undoOrRedo += 1;
                    }
                    if (m_canvas.Strokes.Count > 0)
                    {
                        undoOrRedo += 1;
                        m_canvas.Strokes.Clear();
                    }
                    //StrokeCollection strokes = new StrokeCollection();
                    StylusPointCollection stylusPoints = new StylusPointCollection();
                    //System.Windows.Input.StylusPointDescription stylusPointDescription = new StylusPointDescription();
                    StylusPoint stylusPoint = new StylusPoint
                    {
                        X = 580,
                        Y = 212
                    };
                    stylusPoints.Add(stylusPoint);
                    Stroke stroke = new Stroke(stylusPoints);

                    stylusPoint.X = 581;
                    stylusPoint.Y = 213;
                    stylusPoints.Add(stylusPoint);
                    stroke = new Stroke(stylusPoints);
                    page.lines.Last().lines_curr.Add(stroke);
                    m_canvas.Strokes.Add(page.lines.Last().lines_curr);
                }
            }
        }

        private StylusPointCollection stylusPoints = new StylusPointCollection();
        private StylusPoint stylusPoint = new StylusPoint();
        private Stroke stroke;
        private bool isFirst = true;
        public void changepages(double _x, double _y, bool _new, Color _color, int _size, int i, float Pressure)
        {
            if (_new)
            {
                if (stroke != null && stroke.StylusPoints.Count > 1)
                {
                    isFirst = true;
                    try
                    {
                        if (strokes_page_all.Count <= i)
                        {
                            ZBBPage pagetemp = new ZBBPage();
                            pagetemp.lines.Add(new ZBBPageStep());
                            strokes_page_all.Add(pagetemp);
                        }
                        strokes_page_all[i].lines.Last().lines_curr.Add(stroke);
                    }
                    catch (Exception ex)
                    {
                        if (strokes_page_all != null)
                        {
                            if (strokes_page_all.Count == 0)
                            {
                                ZBBPage pagetemp = new ZBBPage();
                                pagetemp.lines.Add(new ZBBPageStep());
                                strokes_page_all.Add(pagetemp);
                            }
                        }
                        LogHelper.WriteErrLog("【画板】（changepages）添加失败，strokes_page_all为0，" + ex.Message, ex);
                    }
                }
                stylusPoints = new StylusPointCollection();
                stylusPoint = new StylusPoint();
                stroke = null;
            }
            else
            {
                if (isFirst)
                {
                    stylusPoint.X = _x;
                    stylusPoint.Y = _y;
                    //_color.A = (byte)(Pressure * 255f);
                    //stylusPoint.PressureFactor = Pressure;
                    stylusPoints.Add(stylusPoint);
                    if (stylusPoints.Count > 1)
                    {
                        stroke = new Stroke(stylusPoints);
                        drawingAttributes = new DrawingAttributes
                        {
                            Color = _color,
                            Width = _size * 4.5,
                            Height = _size * 4.5,
                            FitToCurve = true,
                            //IsHighlighter =true,
                            IgnorePressure = true
                        };
                        stroke.DrawingAttributes = drawingAttributes;
                        m_canvas.Strokes.Add(stroke);
                        isFirst = false;
                    }
                }
                else
                {
                    if (m_canvas.Strokes.Count > 0)
                    {
                        stylusPoint.X = _x;
                        stylusPoint.Y = _y;
                        stylusPoints.Add(stylusPoint);
                        stroke = new Stroke(stylusPoints);
                        drawingAttributes = new DrawingAttributes
                        {
                            Color = _color,
                            Width = _size * 4.5,
                            Height = _size * 4.5,
                            FitToCurve = true,
                            IgnorePressure = false
                        };
                        stroke.DrawingAttributes = drawingAttributes;
                        m_canvas.Strokes[m_canvas.Strokes.Count - 1] = stroke;
                    }
                }
            }
        }
















        //public void changepages(double _x, double _y, bool _new, Color _color, int _size, int i)
        //{
        //    try
        //    {
        //        if (_new)
        //        {
        //            if (stroke != null && stroke.StylusPoints.Count > 1)
        //            {
        //                drawingAttributes = new DrawingAttributes();
        //                //m_canvas.DefaultDrawingAttributes = drawingAttributes;
        //                drawingAttributes.Color = _color;
        //                drawingAttributes.Width = _size * 5;
        //                drawingAttributes.Height = _size * 5;
        //                drawingAttributes.FitToCurve = true;
        //                drawingAttributes.IgnorePressure = false;

        //                stroke.DrawingAttributes = drawingAttributes;
        //                //m_canvas.DefaultDrawingAttributes= drawingAttributes;

        //                m_canvas.Strokes.Add(stroke);
        //                strokes_page_all[i].lines.Last().lines_curr.Add(stroke);

        //                //int currCount= strokes_page_all[i].lines.Last().lines_curr.Count;
        //                //if (currCount > 0)
        //                //{
        //                //    strokes_page_all[i].lines.Last().lines_curr[currCount - 1] = stroke;
        //                //}
        //                stroke = null;
        //            }
        //            stylusPoints = new StylusPointCollection();
        //            stylusPoint = new StylusPoint();
        //            //stroke = new Stroke(stylusPoints);
        //            //stroke = null;
        //        }
        //        else
        //        {
        //            //stylusPoints = new StylusPointCollection();
        //            //stylusPoint = new StylusPoint();
        //            stylusPoint.X = _x;
        //            stylusPoint.Y = _y;
        //            stylusPoints.Add(stylusPoint);
        //            stroke = new Stroke(stylusPoints);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogHelper.WriteErrLog("【XHMicroLessonSystemWindow】（changepages）点阵比书写报错：" + ex.Message, ex);
        //    }
        //}
    }
}
