using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SIASUN.Autopilot.View.Helper
{
    /// <summary>
    /// DrawableObjectsCS 的摘要说明。
    /// </summary>

    //基类
    public abstract class DShape
    {
        public abstract void Draw(Graphics g);
        protected RectangleF bounding;
        public PointF[] pointlist;
        public abstract void pointchange(PointF[] p);
        public virtual GraphicsPath pathChange(GraphicsPath path, bool pick)
        {
            return null;
        }
        protected Color penColor;
        protected float penWidth;
    }

    //填充图形接口
    public interface IFillable
    {
        void Fill(Graphics g);
        Color FillBrushColor
        {
            get;
            set;
        }
    }

    //画线
    public class DLine : DShape
    {
        protected PointF p1;
        protected PointF p2;
        public DLine(PointF[] p, Color penColor, float penWidth)
        {
            this.pointchange(p);
            this.penColor = penColor;
            this.penWidth = penWidth;
        }

        public override void pointchange(PointF[] p)
        {
            pointlist = new PointF[p.Length];
            int i = 0;
            foreach (PointF tempPoint in p)
            {
                pointlist[i++] = tempPoint;
            }
            p1 = pointlist[0];
            p2 = pointlist[1];
        }

        public override void Draw(Graphics g)
        {
            using (Pen p = new Pen(penColor, penWidth))
            {
                g.DrawLine(p, p1, p2);
            }
        }
    }

    //画线--带样式
    public class DPLine : DShape
    {
        protected PointF p1;
        protected PointF p2;
        protected DashStyle style;
        protected System.Drawing.Drawing2D.LineCap scap;
        protected System.Drawing.Drawing2D.LineCap ecap;
        public DPLine(PointF start, PointF end, Color penColor, DashStyle style, System.Drawing.Drawing2D.LineCap scap, System.Drawing.Drawing2D.LineCap ecap)
        {
            p1 = start;
            p2 = end;
            this.penColor = penColor;
            this.style = style;
            this.scap = scap;
            this.ecap = ecap;
        }
        public override void pointchange(PointF[] p)
        {
        }
        public override void Draw(Graphics g)
        {
            using (Pen p = new Pen(penColor))
            {
                p.DashStyle = style;
                p.StartCap = scap;
                p.EndCap = ecap;
                p.Width = 8;
                g.DrawLine(p, p1, p2);
            }
        }
    }

    //画路径
    public class DPath : DShape
    {
        protected GraphicsPath Path;
        public DPath(GraphicsPath Path, Color penColor, float penWidth)
        {
            this.Path = Path;
            this.penColor = penColor;
            this.penWidth = penWidth;
        }
        public override void pointchange(PointF[] p)
        {
        }
        public override GraphicsPath pathChange(GraphicsPath path, bool pick)
        {
            if (pick == true)
                return this.Path;
            else
            {
                this.Path = path;
                return null;
            }
        }
        public override void Draw(Graphics g)
        {
            using (Pen p = new Pen(penColor, penWidth))
            {
                g.DrawPath(p, Path);
            }
        }
        public GraphicsPath mousePath
        {
            get
            {

                return Path;
            }
        }
    }
    //空心圆
    public class DHollowCircle : DShape
    {
        public DHollowCircle(PointF[] p, Color penColor, float penWidth)
        {
            this.pointchange(p);
            this.penColor = penColor;
            this.penWidth = penWidth;
        }

        public override void pointchange(PointF[] p)
        {
            //this.pointlist = new PointF[p.Length];
            //int i = 0;
            //foreach (PointF tempPoint in p)
            //{
            //    pointlist[i++] = tempPoint;
            //}
            //int Distance = (int)Math.Sqrt(Math.Pow((pointlist[0].X - pointlist[1].X), 2.0) + Math.Pow((pointlist[0].Y - pointlist[1].Y), 2.0));
            //pointlist[0].Offset(-Distance, -Distance);
            //int diameter = Distance * 2;
            //bounding = new Rectangle(pointlist[0], new Size(diameter, diameter));
        }

        public override void Draw(Graphics g)
        {
            using (Pen p = new Pen(penColor, penWidth))
            {
                g.DrawEllipse(p, bounding);
            }
        }
    }

    //实心圆
    public class DFilledCircle : DHollowCircle, IFillable
    {
        protected Color brushColor;
        public DFilledCircle(PointF[] p, Color penColor, float penWidth, Color brushColor) : base(p, penColor, penWidth)
        {
            this.brushColor = brushColor;
        }

        public void Fill(Graphics g)
        {
            using (Brush b = new SolidBrush(brushColor))
            {
                g.FillEllipse(b, bounding);
            }
        }
        public Color FillBrushColor
        {
            get
            {
                return brushColor;
            }
            set
            {
                brushColor = value;
            }
        }
        public override void Draw(Graphics g)
        {
            Fill(g);
            //base.Draw(g);
        }
    }
    //画弧
    public class DArc : DHollowCircle
    {
        protected float angle1;
        protected float angle2;
        public DArc(PointF[] p, Color penColor, float penWidth, float angle1, float angle2) : base(p, penColor, penWidth)
        {
            this.angle1 = angle1;
            this.angle2 = angle2;
        }
        public override void Draw(Graphics g)
        {
            using (Pen p = new Pen(penColor, penWidth))
            {
                g.DrawArc(p, bounding, angle1, angle2);
            }
        }
    }

    //画多边形
    public class DPolygon : DShape
    {
        public DPolygon(PointF[] p, Color penColor, float penWidth)
        {
            this.pointchange(p);
            this.penColor = penColor;
            this.penWidth = penWidth;
        }
        public override void pointchange(PointF[] p)
        {
            pointlist = new PointF[p.Length];
            int i = 0;
            foreach (PointF tempPoint in p)
            {
                pointlist[i++] = tempPoint;
            }
        }
        public override void Draw(Graphics g)
        {
            using (Pen p = new Pen(penColor, penWidth))
            {
                g.DrawPolygon(p, pointlist);
            }
        }
    }


    //Beziers
    public class DBeziers : DPolygon
    {
        public DBeziers(PointF[] p, Color penColor, float penWidth) : base(p, penColor, penWidth)
        {
        }
        public override void Draw(Graphics g)
        {
            using (Pen p = new Pen(penColor, penWidth))
            {
                g.DrawBeziers(p, pointlist);
            }
        }
    }

    //Curve
    public class DCurve : DPolygon
    {
        public DCurve(PointF[] p, Color penColor, float penWidth) : base(p, penColor, penWidth)
        {
        }
        public override void Draw(Graphics g)
        {
            using (Pen p = new Pen(penColor, penWidth))
            {
                g.DrawCurve(p, pointlist);
            }
        }
    }

    //图像
    public class DImage : DShape
    {
        protected Image image;
        public DImage(PointF p, Image image)
        {
            bounding = new RectangleF(p, new SizeF(image.Width, image.Height));
            this.image = image;
        }
        public override void pointchange(PointF[] p)
        {
        }
        public override void Draw(Graphics g)
        {
            g.DrawImage(image, bounding);
        }
    }

    //图形集合
    public class DShapeList : CollectionBase
    {
        DrawCollection wholeList = new DrawCollection();
        public new int Count
        {
            get
            {
                return wholeList.Count;
            }
        }

        public void Add(DShape d)
        {
            wholeList.Add(d);
        }

        public new void RemoveAt(int i)
        {
            wholeList.RemoveAt(i);
        }

        public new void Clear()
        {
            wholeList.Clear();
        }

        //索引器
        public DShape this[int newshapeIndex]
        {
            get
            {
                return (DShape)wholeList[newshapeIndex];
            }
            set
            {
                wholeList[newshapeIndex] = value;
            }
        }

        public void DrawList(Graphics g)
        {
            if (wholeList.Count != 0)
            {
                foreach (DShape d in wholeList)
                    d.Draw(g);
            }
        }
        //public IFillable[] GetFilledList() 
        //{
        //return (IFillable[])filledList.ToArray(typeof(IFillable));
        //}   
    }

    public class DrawCollection : CollectionBase
    {
        public void Add(DShape d)
        {
            List.Add(d);
        }

        public new void RemoveAt(int i)
        {
            List.RemoveAt(i);
        }

        public new void Clear()
        {
            List.Clear();
        }
        public DShape this[int shapeIndex]
        {
            get
            {
                return (DShape)List[shapeIndex];
            }
            set
            {
                List[shapeIndex] = value;
            }
        }
    }

    public class PointCollection : CollectionBase
    {
        public Point this[int pointIndex]
        {
            get
            {
                return (Point)List[pointIndex];
            }
            set
            {
                List[pointIndex] = value;
            }
        }
        public void Add(Point newPoint)
        {
            List.Add(newPoint);
        }
        public void RemoveRange(int x, int y)
        {
            for (int i = y - 1; i >= 0; i--)
            {
                List.RemoveAt(i);
            }
        }
        public void AddRange(Point[] point)
        {
            foreach (Point p in point)
            {
                List.Add(p);
            }
        }
        public PointCollection()
        {
        }
    }

    public class PointArrayCollection : CollectionBase
    {
        public Point[] this[int pointIndex]
        {
            get
            {
                return (Point[])List[pointIndex];
            }
            set
            {
                List[pointIndex] = value;
            }
        }
        public void Add(Point[] newPointArray)
        {
            List.Add(newPointArray);
        }
        public void RemoveRange(int x, int y)
        {
            for (int i = y - 1; i >= 0; i--)
            {
                List.RemoveAt(i);
            }
        }
        /*public void AddRange(Point[] point)
		{
			foreach(Point p in point)
			{
				List.Add(p);
			}
		} */
        public PointArrayCollection()
        {
        }
    }
}
