using System;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.Maps;
using KGIS.Framework.Utils;
namespace Kingo.Plugin.EngineEditor.helper
{
    public class PointAnalysisHelperForGdb
    {
        public readonly string DltbName = "DLTB_ERR_Result";
        public readonly string XZQName = "XZQ_ERR_Result";
        public readonly string DltbALLName = "DLTB_All_Result";
        public readonly string XZQALLName = "XZQ_All_Result";
        public string Path = "\\DataCheckResult.gdb";
        public IFeatureClass ShpFeatureClass = null;
        public IFeatureClass ALLFeatureClass = null;
        IWorkspaceFactory pWorkspaceFactory = null;
        IWorkspace pWorkspace = null;
        IFeatureWorkspace pFeatureWorkspace = null;
        public PointAnalysisHelperForGdb()
        {
        }
        /// 
        /// 给图形加点保证平均距离小于一定距离
        /// 
        /// 有问题的线段集合
        /// 要加点的图层
        /// 平均距离
        /// 适合环型图斑
        public void AddConcurrentPoint(IPoint point, IIdentify identify)
        {
            int max = 0;
            int partIndexMax = 0;
            IPoint BeforePoint = null;
            if (identify == null || point == null)
            {
                return;
            }
            IArray pIDs = identify.Identify(point);
            if (pIDs == null || pIDs.Count == 0)
                return;
            for (int index = 0; index < pIDs.Count; index++)
            {
                IFeatureIdentifyObj pFeatIdObj = pIDs.get_Element(index) as IFeatureIdentifyObj;
                IRowIdentifyObject pRowObj = pFeatIdObj as IRowIdentifyObject;
                IFeature iF = pRowObj.Row as IFeature;
                IGeometry geometry = iF.Shape;
                IPolyline polyline1 = GetPolyline2(iF);
                if (PointUpLine(polyline1, point))
                {
                    continue;
                }
                IPoint iHitPt = new ESRI.ArcGIS.Geometry.Point();
                IHitTest iHitTest = geometry as IHitTest;
                double hitDist = 0;
                int partIndex = 0;
                int vertexIndex = 0;
                bool bRightSide = false;
                IPointCollection pc = (SpliteLineAtPoint(polyline1, point) as IPointCollection);
                if (pc == null)
                {
                    //MessageHelper.Show("在批量节点密度处理中,添加共点失败,请查看oid为" + iF.OID + "的图层在点" + point.X + ";" + point.Y + "处是否有拓扑问题,我们将继续处理...");
                    LogAPI.Debug("在批量节点密度处理中,添加共点失败,请查看oid为" + iF.OID + "的图层在点" + point.X + ";" + point.Y + "处是否有拓扑问题");
                    continue;
                }
                for (int j = 0; j < pc.PointCount; j++)
                {
                    if (j == 0)
                    {
                        continue;
                    }
                    if (pc.Point[j].X == point.X && pc.Point[j].Y == point.Y)
                    {
                        BeforePoint = pc.Point[j - 1];
                        break;
                    }
                }
                bool isTrue = iHitTest.HitTest(BeforePoint, 0.0001, esriGeometryHitPartType.esriGeometryPartVertex,
                   iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide);
                if (isTrue)
                {
                    max = vertexIndex;
                    partIndexMax = partIndex;
                    iF.Shape = this.AddPoint(iF.Shape, point, partIndexMax, max, false);
                    iF.Store();
                    break;
                }
            }
        }
        /// 
        /// 图形转点
        /// 
        /// 
        /// 
        /// 
        public IPointCollection GeoToPoints(IGeometry geometry, bool isCopy = true)
        {
            IGeometry CopyGeometry = null;
            IPointCollection collection = null;
            if (isCopy)
            {
                ESRI.ArcGIS.esriSystem.IClone colone = geometry as ESRI.ArcGIS.esriSystem.IClone;
                CopyGeometry = colone.Clone() as ESRI.ArcGIS.Geometry.IGeometry;
                if (CopyGeometry.SpatialReference == null)
                {
                    CopyGeometry.SpatialReference = MapsManager.Instance.MapService.getAxMapControl().ActiveView.FocusMap.SpatialReference;
                }
                collection = CopyGeometry as IPointCollection;
            }
            else
                collection = geometry as IPointCollection;
            return collection;
        }
     
        /// 
        /// 点是否在线上
        /// 
        /// 
        private bool PointUpLine(IPolyline polyline, IPoint point, bool isDelete = false)
        {
            IPointCollection Allcollection = new PolylineClass() as IPointCollection;
            Allcollection = polyline as IPointCollection;
            double angle = 0;
            for (int i = 0; i < Allcollection.PointCount; i++)
            {
                if (Allcollection.Point[i].X == point.X && Allcollection.Point[i].Y == point.Y)
                {
                    if (isDelete)
                    {
                        if (i == 0 || i == Allcollection.PointCount - 1)
                        {
                            return false;
                        }
                        angle = GetAngle(point, Allcollection.Point[i - 1], Allcollection.Point[i + 1]);
                        angle = Math.Round(angle, 0);
                        if (angle == 180 || angle == 0)
                        {
                            return true;
                        }
                        else
                            return false;
                    }
                    return true;
                }
            }
            return false;
        }
        public double GetAngle(IPoint cenPoint, IPoint firstPoint, IPoint secondPoint)
        {
            double ma_x = firstPoint.X - cenPoint.X;
            double ma_y = firstPoint.Y - cenPoint.Y;
            double mb_x = secondPoint.X - cenPoint.X;
            double mb_y = secondPoint.Y - cenPoint.Y;
            double v1 = (ma_x * mb_x) + (ma_y * mb_y);
            double ma_val = Math.Sqrt(ma_x * ma_x + ma_y * ma_y);
            double mb_val = Math.Sqrt(mb_x * mb_x + mb_y * mb_y);
            if (ma_val * mb_val == 0)
            {
                return -1;
            }
            double cosM = v1 / (ma_val * mb_val);
            double angleAMB = Math.Acos(cosM) * 180 / Math.PI;
            return angleAMB;
        }
        /// 
        /// 在线的指定位置上打断点
        /// 
        /// 线
        /// 断点
        /// 
        public IPolyline SpliteLineAtPoint(IPolyline LineCurve, IPoint SplitePoint)
        {
            IPolyline Lines = null;
            bool isSplit;
            int splitIndex, segIndex;
            LineCurve.SplitAtPoint(SplitePoint, false, false, out isSplit, out splitIndex, out segIndex);
            if (isSplit)
            {
                Lines = LineCurve as IPolyline;
            }
            return Lines;
        }
     
        private IPolyline GetPolyline2(IFeature pFeature)
        {
            IPointCollection point = pFeature.Shape as IPointCollection;
            IPointCollection collection = new PolylineClass() as IPointCollection;
            collection.AddPointCollection(point);
            return collection as IPolyline;
        }
        /// 
        /// 给图形加点
        /// 
        /// 
        /// 要添加的点
        /// 片段顺序
        /// 点的索引
        /// true:Before;false:After
        /// 
        public IGeometry AddPoint(IGeometry geometry, IPoint point, int partIndex, int vertexIndex, bool beforeOrAfter = true)
        {
            IGeometryCollection collection = geometry as IGeometryCollection;
            IGeometry geo = collection.get_Geometry(partIndex);
            IPointCollection points = geo as IPointCollection;
            object index = vertexIndex;
            object mss = Type.Missing;
            if (beforeOrAfter)
            {
                points.AddPoint(point, ref index, ref mss);
            }
            else
                points.AddPoint(point, ref mss, ref index);
            //geo = points as IGeometry;
            return geometry;
        }
    }
}