using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KGIS.PlatformPlugin.Model
{
    /// 
    /// 线模型
    /// 
    public class TestLineModel
    {
        public List PointElements = new List();
        /// 
        /// 显示线元素
        /// 
        public IElement LineElement { get; set; }
        /// 
        /// 显示跟随线元素
        /// 
        public IElement FollowLineElement { get; set; }
        /// 
        /// 线对象
        /// 
        public IPointCollection Line { get; set; }
        /// 
        /// 跟随线对象
        /// 
        public ILineMovePointFeedback FollowLine { get; set; }
        private IActiveView ActiveView { get; set; }
        /// 
        /// 计算线上点的坐标所用到的宽度比例
        /// 
        //public double Scale { get; set; }
        /// 
        /// 线样式
        /// 
        public ILineSymbol LineSymbol { get; private set; }
        /// 
        /// 跟随线样式
        /// 
        public ILineSymbol FollowLineSymbol { get; private set; }
        public TestLineModel(IActiveView pActiveView, esriSimpleLineStyle pLineStyle, double pScale = 1)
        {
            this.ActiveView = pActiveView;
            //this.Scale = pScale;
            // 获取IRGBColor接口
            IRgbColor color = new RgbColor();
            // 设置颜色属性
            color.Red = 0;
            color.Green = 255;
            color.Blue = 255;
            // 获取ILine符号接口
            ILineSymbol outline = new SimpleLineSymbol();
            // 设置线符号属
            outline.Width = 1.5;
            outline.Color = color;
            (outline as SimpleLineSymbol).Style = pLineStyle;
            this.LineSymbol = outline;
            this.FollowLineSymbol = outline;
        }
        public void Init()
        {
            this.Line = new Polyline();
            ActiveView.ScreenDisplay.SetSymbol(FollowLineSymbol as ISymbol);
            this.FollowLine = new LineMovePointFeedbackClass()
            {
                Symbol = FollowLineSymbol as ESRI.ArcGIS.Display.ISymbol,
                Display = ActiveView.ScreenDisplay
            };
            this.FollowLine.Symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;
        }
        /// 
        /// 刷新线上的指定索引处的点
        /// 
        public void RefreshPoint(int pPointIndex)
        {
            if (this.Line.PointCount > pPointIndex)
            {
                this.DrawLine(pPointIndex);
                if (PointElements.Count > this.Line.PointCount)
                {
                    IPoint endPointForElement = (IPoint)PointElements[PointElements.Count - 1].Geometry;
                    IPoint endPointForLine = (this.Line as IPolyline).ToPoint;
                    if (endPointForElement.X != endPointForLine.X || endPointForElement.Y != endPointForLine.Y)
                    {
                        IElement e = PointElements[pPointIndex];
                        ActiveView.GraphicsContainer.DeleteElement(e);
                        PointElements.Remove(e);
                        e = null;
                    }
                }
                else if (PointElements.Count < this.Line.PointCount)
                {
                    IPoint endPointForLine = (this.Line as IPolyline).ToPoint;
                    IMarkerElement e = new MarkerElementClass();
                    // 获取IRGBColor接口
                    IRgbColor color = new RgbColor();
                    // 设置颜色属性
                    color.Red = 255;
                    color.Green = 255;
                    color.Blue = 0;
                    IMarkerSymbol symbol = new SimpleMarkerSymbolClass();
                    symbol.Color = color;
                    symbol.Size = 5;
                    e.Symbol = symbol;
                    (e as IElement).Geometry = endPointForLine;
                    ActiveView.GraphicsContainer.AddElement(e as IElement, 0);
                    PointElements.Insert(pPointIndex, e as IElement);
                }
                else if (pPointIndex > -1)
                {
                    IPoint endPointForLine = this.Line.get_Point(pPointIndex);
                    IElement e = PointElements[pPointIndex];
                    e.Geometry = endPointForLine;
                }
                IPointCollection newGeo = new Polyline();
                int i = pPointIndex - 1;
                if (i >= 0)
                {
                    newGeo.AddPoint(this.Line.get_Point(i));
                }
                i = pPointIndex;
                if (i >= 0)
                {
                    newGeo.AddPoint(this.Line.get_Point(i));
                }
                i = pPointIndex + 1;
                if (i < this.Line.PointCount)
                {
                    newGeo.AddPoint(this.Line.get_Point(i));
                }
                if (newGeo.PointCount > 1)
                {
                    ITopologicalOperator topo = newGeo as ITopologicalOperator;
                    if (topo != null)
                    {
                        IGeometry geo = topo.Buffer(10);
                        ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, geo.Envelope);
                    }
                }
            }
        }
        /// 
        /// 绘制线对象
        /// 
        public void DrawLine(int pIndex = -1)
        {
            if (this.Line == null || this.Line.PointCount == 0)
            {
                ActiveView.GraphicsContainer.DeleteAllElements();
                ActiveView.Refresh();
                this.PointElements.Clear();
                this.LineElement = null;
                this.FollowLineElement = null;
            }
            else
            {
                if (PointElements.Count > this.Line.PointCount)
                {
                    if (pIndex == -1)
                    {
                        pIndex = PointElements.Count - 1;
                    }
                    IPoint endPointForElement = (IPoint)PointElements[pIndex].Geometry;
                    IPoint endPointForLine = (this.Line as IPolyline).ToPoint;
                    if (endPointForElement.X != endPointForLine.X || endPointForElement.Y != endPointForLine.Y)
                    {
                        IElement e = PointElements[pIndex];
                        ActiveView.GraphicsContainer.DeleteElement(e);
                        PointElements.Remove(e);
                        e = null;
                    }
                }
                else if (PointElements.Count < this.Line.PointCount)
                {
                    if (pIndex == -1)
                    {
                        pIndex = PointElements.Count;
                    }
                    IPoint endPointForLine = (this.Line as IPolyline).ToPoint;
                    IMarkerElement e = new MarkerElementClass();
                    // 获取IRGBColor接口
                    IRgbColor color = new RgbColor();
                    bool IsAutoTrackPoint = true;//是否自动跟随点
                    if (IsAutoTrackPoint)
                    {
                        // 设置颜色属性
                        color.Red = 100;
                        color.Green = 0;
                        color.Blue = 255;
                    }
                    else
                    {
                        // 设置颜色属性
                        color.Red = 255;
                        color.Green = 255;
                        color.Blue = 0;
                    }
                    IMarkerSymbol symbol = new SimpleMarkerSymbolClass();
                    symbol.Color = color;
                    symbol.Size = 5;
                    e.Symbol = symbol;
                    (e as IElement).Geometry = endPointForLine;
                    ActiveView.GraphicsContainer.AddElement(e as IElement, 0);
                    PointElements.Insert(pIndex, e as IElement);
                }
                else
                {
                    if (pIndex == -1)
                    {
                        pIndex = PointElements.Count - 1;
                    }
                    IPoint endPointForLine = (this.Line as IPolyline).ToPoint;
                    IElement e = PointElements[pIndex];
                    e.Geometry = endPointForLine;
                }
                if (this.LineElement == null)
                {
                    if (this.Line.PointCount >= 2)
                    {
                        #region 构造新的元素
                        ILineElement pFillShapeElement = new LineElementClass();
                        pFillShapeElement.Symbol = this.LineSymbol;
                        this.LineElement = pFillShapeElement as IElement;
                        this.LineElement.Geometry = this.Line as IGeometry;
                        ActiveView.GraphicsContainer.AddElement(this.LineElement, 0);
                        #endregion
                    }
                }
                else
                {
                    if (this.Line.PointCount < 2)
                    {
                        #region 当点集合小于2的时候,删除对应的元素
                        ActiveView.GraphicsContainer.DeleteElement(this.LineElement);
                        this.LineElement = null;
                        #endregion
                    }
                    else
                    {
                        #region 更新现有元素
                        this.LineElement.Geometry = this.Line as IGeometry;
                        #endregion
                    }
                }
                //DrawFollowLine();
                IPointCollection newGeo = new Polyline();
                if (this.Line.PointCount > 1)
                {
                    newGeo.AddPoint(this.Line.get_Point(this.Line.PointCount - 2));
                }
                newGeo.AddPoint(this.Line.get_Point(this.Line.PointCount - 1));
                if (newGeo.PointCount > 1)
                {
                    if ((newGeo as IGeometry).IsEmpty)
                        return;
                    ITopologicalOperator topo = newGeo as ITopologicalOperator;
                    if (topo != null)
                    {
                        topo.Simplify();
                        //注释注释缓冲代码,解决在GIS10.2环境中绘制线物面卡顿问题
                        ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, (newGeo as IGeometry).Envelope);
                    }
                }
            }
        }
    }
}