using KGIS.Framework.Commands;
using Kingo.Plugin.MapView.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using KGIS.Framework.Platform;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using Kingo.Plugin.MapView.Views.MeasurementUi;
using KGIS.Framework.Utils.Helper;
using ESRI.ArcGIS.esriSystem;
using KGIS.Framework.Utils.ExtensionMethod;
using KGIS.Framework.Utils;
using KGIS.Framework.Maps;
using KGIS.Framework.EngineEditor;
namespace Kingo.Plugin.MapView.Commands
{
    public class MeasurementToolClass : BaseToolCmd
    {
        private INewLineFeedback pNewLineFeedback;//追踪线对象
        private INewPolygonFeedback pNewPolygonFeedback;//追踪面对象
        private IPoint pPointPt = null;//鼠标点击点
        private IPoint pMovePt = null;//鼠标移动时的当前点
        private double dToltalLength = 0;//测量总长度
        private IPointCollection pAreaPointCol = new MultipointClass();//对面积测量时所画的点进行存储
        private string sMapUnits = "";//地图单位变量
        private double dSegmentLength = 0;//片段距离
        private double dSumLength = 0;//保存所有距离
        private IHookHelper m_hookHelper;//获取地图控件和主窗体
        private object missing = Type.Missing;
        private int pMouseOperate = 0;
        private double DsumLength = 0;
        private INewEnvelopeFeedback m_NewPolygonFeedback;
        MeasurementUi main;
        IArea pArea;
        IPolygon pPolygon;
        private bool bDoubleClickMark = false;//双击是否要起作用标记(true有效 false已无效)
        /// 
        /// 鼠标点击事件
        /// 
        /// 
        /// 
        /// 
        /// 
        private List iPoitns = new List();
        /// 
        /// 测量地图中距离与面积
        /// 
        public MeasurementToolClass()
        {
            base.m_caption = "测量";
            base.m_toolTip = "左键点击开始测量,双击结束测量";
            base.m_cursor = System.Windows.Forms.Cursors.Cross;
        }
        public override void OnClick()
        {
            try
            {
                if (m_hookHelper != null)
                {
                    this.m_NewPolygonFeedback = new NewEnvelopeFeedback() { Display = (m_hookHelper.FocusMap as IActiveView).ScreenDisplay };
                    if (main != null)
                        return;
                    main = new MeasurementUi();
                    main.Closed += Main_Closed;
                    main.Width = 300;
                    main.Height = 200;
                    main.WindowStartupLocation = System.Windows.WindowStartupLocation.Manual;
                    main.Left = 240;
                    main.Top = 110;
                    main.ActionsUpda = ActionUpdate;
                    main.ShowInMainWindow(false);
                }
                else
                {
                    MessageHelper.Show("hookHelper获取失败");
                    //return;
                }
            }
            catch (Exception ex)
            {
                //LogAPI.Debug("测量异常:" + ex);
                LogAPI.Debug("点击 测量工具 时异常,异常信息如下:");
                LogAPI.Debug(ex);
                LogAPI.Debug("点击 测量工具 时异常信息结束");
            }
        }
        public override void OnCreate(object Hook)
        {
            try
            {
                base.OnCreate(Hook);
                if (m_hookHelper == null)
                {
                    m_hookHelper = new HookHelper();
                    m_hookHelper.Hook = Hook;
                }
            }
            catch (Exception ex)
            {
                //LogAPI.Debug("测量异常!" + en.Message);
                LogAPI.Debug("初始化 测量工具 时异常,异常信息如下:");
                LogAPI.Debug(ex);
                LogAPI.Debug("初始化 测量工具 时异常信息结束");
            }
        }
        /// 
        /// 鼠标双击事件
        /// 
        public override void OnDblClick()
        {
            bDoubleClickMark = true;
            if (pMouseOperate == 0)
            {
                if (pNewLineFeedback == null)
                {
                    return;
                }
                DeletePoint();
            }
            else if (pMouseOperate == 1)
            {
                if (pNewPolygonFeedback == null)
                {
                    return;
                }
                DeletePolyg();
            }
            else if (pMouseOperate == 2)
            {
            }
        }
        /// 
        /// 释放控件
        /// 
        /// 
        public override bool Deactivate()
        {
            if (main != null)
            {
                main.Close();
            }
            base.Deactivate();
            this.m_deactivate = true;
            return this.m_deactivate;
        }
        private void Main_Closed(object sender, EventArgs e)
        {
            if (main != null)
            {
                main.Closed -= Main_Closed;
            }
            sMapUnits = "";
            dSegmentLength = 0;
            dToltalLength = 0;
            pPointPt = null;//鼠标点击点
            pMovePt = null;//鼠标移动时的当前点
            this.EndFeedback();
            this.EndArcFeedback();
            this.EndTraceFeedback();
        }
        /// 
        /// 测量线
        /// 
        /// 0:测量长度  1:测量面积 其他:关闭测量工具
        //[LogWrite(Description = "")]
        public void ActionUpdate(int ss)
        {
            try
            {
                pMouseOperate = ss;
                if (ss == 0)
                {
                    DeletePolyg();
                }
                else if (ss == 1)
                {
                    DeletePoint();
                }
                else if (ss == 2)
                {
                    DeletePoint();
                }
                else
                {
                    pMouseOperate = 0;
                    main = null;
                    DeletePolyg();
                    DeletePoint();
                }
            }
            catch (Exception ex)
            {
                //LogAPI.Debug(e.Message);
                LogAPI.Debug("使用测量工具期间 测量线 时异常,异常信息如下:");
                LogAPI.Debug(ex);
                LogAPI.Debug("使用测量工具期间 测量线 时异常信息结束");
            }
        }
        //[LogWrite(Description = "")]
        public override void OnMouseDown(int Button, int Shift, int X, int Y)
        {
            try
            {
                if (main == null || Button == 4) return;
                //通过鼠标点击的位置获取地图中XY轴坐标
                //以数据视图的坐标系为标准获取点
                #region 捕捉
                this.m_pPointCatched = (this.m_hookHelper.FocusMap as IActiveView).ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
                if (this.m_pSnappingEnv != null && this.m_pSnappingEnv.Enabled)
                {
                    ISnappingResult snappingResult = this.m_pPntSnapper.Snap(this.m_pPointCatched);
                    this.m_pSnappingFeedback.Update(snappingResult, 0);
                    if (snappingResult != null)
                    {
                        this.m_pPointCatched = snappingResult.Location;
                    }
                }
                #endregion
                pPointPt = this.m_pPointCatched;
                if (pMouseOperate == 0)
                {
                    //判断追踪线对象是否为空,若是则实例化并设置当前鼠标点为起始点
                    if (pNewLineFeedback == null)
                    {
                        //实例化追踪线对象
                        pNewLineFeedback = new NewLineFeedbackClass();
                        pNewLineFeedback.Display = (m_hookHelper.FocusMap as IActiveView).ScreenDisplay;
                        //设置起点,开始动态线绘制
                        pNewLineFeedback.Start(pPointPt);
                        dToltalLength = 0;
                    }
                    else //如果追踪线对象不为空,则添加当前鼠标点
                    {
                        pNewLineFeedback.AddPoint(pPointPt);
                    }
                    if (dSegmentLength != 0)
                    {
                        dToltalLength = dToltalLength + dSegmentLength;
                        dSumLength = dSumLength + dSegmentLength;
                    }
                }
                else if (pMouseOperate == 1)
                {
                    if (pNewPolygonFeedback == null)
                    {
                        //实例化追踪面对象
                        pNewPolygonFeedback = new NewPolygonFeedback();
                        pNewPolygonFeedback.Display = (m_hookHelper.FocusMap as IActiveView).ScreenDisplay;
                        //  pAreaPointCol.RemovePoints(0, pAreaPointCol.PointCount);
                        //开始绘制多边形
                        pNewPolygonFeedback.Start(pPointPt);
                        pAreaPointCol.AddPoint(pPointPt, ref missing, ref missing);
                    }
                    else
                    {
                        pNewPolygonFeedback.AddPoint(pPointPt);
                        pAreaPointCol.AddPoint(pPointPt, ref missing, ref missing);
                    }
                    iPoitns.Add(pPointPt);
                }
                else if (pMouseOperate == 2)
                {
                    pPointPt = (this.m_hookHelper.FocusMap as IActiveView).ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
                    if (m_NewPolygonFeedback != null)
                    {
                        m_NewPolygonFeedback.Start(pPointPt);
                    }
                }
                //KGIS.Common.Utility.CustomOperationLogAPICustomOperationLogAPI.InsertDatalogResLog("测量操作", "测量操作完成!");
            }
            catch (Exception ex)
            {
                //LogAPI.Debug("测量异常!" + en.Message);
                LogAPI.Debug("使用测量工具期间 鼠标点击 时异常,异常信息如下:");
                LogAPI.Debug(ex);
                LogAPI.Debug("使用测量工具期间 鼠标点击 时异常信息结束");
            }
        }
        /// 
        /// 清空线对象
        /// 
        private void DeletePoint()
        {
            try
            {
                if (pNewLineFeedback != null)
                {
                    pNewLineFeedback.Stop();
                    pNewLineFeedback = null;
                    //清空所画的线对象
                    (m_hookHelper.FocusMap as IActiveView).PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
                }
                if (main != null)
                {
                    sMapUnits = "";
                    dSegmentLength = 0;
                    dToltalLength = 0;
                    pPointPt = null;//鼠标点击点
                    pMovePt = null;//鼠标移动时的当前点
                }
                // main.Txt_Segment.Text = String.Format("{0}{1}", dSegmentLength, sMapUnits);
                //main.Txt_Length.Text = String.Format("{0}{1}", dToltalLength, sMapUnits);
            }
            catch (Exception ex)
            {
                //LogAPI.Debug("测量异常!" + en.Message);
                LogAPI.Debug("使用测量工具期间 清空 线对象 时异常,异常信息如下:");
                LogAPI.Debug(ex);
                LogAPI.Debug("使用测量工具期间 清空 线对象 时异常信息结束");
            }
        }
        /// 
        /// 清空面对象
        /// 
        //[LogWrite(Description = "")]
        private void DeletePolyg()
        {
            try
            {
                if (pNewPolygonFeedback != null)
                {
                    pNewPolygonFeedback.Stop();
                    pNewPolygonFeedback = null;
                    //清空所画的线对象
                    (m_hookHelper.FocusMap as IActiveView).PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
                }
                pPointPt = null;//鼠标点击点
                pMovePt = null;//鼠标移动时的当前点
                pAreaPointCol.RemovePoints(0, pAreaPointCol.PointCount);//清空点集中的所有点
                DsumLength = 0;
                pArea = null;
                pPolygon = null;
                sMapUnits = "";
                //    main.Txt_AreaSegment.Text = String.Format("{0}{1}", 0, sMapUnits);
                //main.Txt_SumArea.Text = String.Format("{0}{1}", 0, sMapUnits);
                //  main.Txt_AreaLength.Text = String.Format("{0}{1}", 0, sMapUnits);
            }
            catch (Exception ex)
            {
                //LogAPI.Debug("测量异常!" + en.Message);
                LogAPI.Debug("使用测量工具期间 清空 面对象 时异常,异常信息如下:");
                LogAPI.Debug(ex);
                LogAPI.Debug("使用测量工具期间 清空 面对象 时异常信息结束");
            }
        }
        /// 
        /// 鼠标移动事件
        /// 
        /// 
        /// 
        /// 
        /// 
        public override void OnMouseMove(int Button, int Shift, int X, int Y)
        {
            try
            {
                //鼠标移动的位置
                #region 捕捉
                this.m_pPointCatched = (this.m_hookHelper.FocusMap as IActiveView).ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
                if (this.m_pSnappingEnv != null && this.m_pSnappingEnv.Enabled)
                {
                    ISnappingResult snappingResult = this.m_pPntSnapper.Snap(this.m_pPointCatched);
                    this.m_pSnappingFeedback.Update(snappingResult, 0);
                    if (snappingResult != null)
                    {
                        this.m_pPointCatched = snappingResult.Location;
                    }
                }
                #endregion
                pMovePt = this.m_pPointCatched;
                //pMouseOperate=0则测量周长
                if (pMouseOperate == 0)
                {
                    if (pNewLineFeedback == null)
                    {
                        return;
                    }
                    if (pNewLineFeedback != null)
                    {
                        pNewLineFeedback.MoveTo(pMovePt);
                    }
                    //double deltaX = 0; //两点之间X差值
                    //double deltaY = 0; //两点之间Y差值
                    if ((pPointPt != null) && (pNewLineFeedback != null))
                    {
                        IPointCollection pNewLineFeedbackLike = new Polyline();
                        pNewLineFeedbackLike.AddPoint(pMovePt);
                        pNewLineFeedbackLike.AddPoint(pPointPt);
                        dSegmentLength = (pNewLineFeedbackLike as IPolyline).Length;
                        dToltalLength = dToltalLength + dSegmentLength;
                        if (main != null)
                        {
                            double dToLength = Math.Round(dToltalLength, 6, MidpointRounding.AwayFromZero);
                            //解决在地图上绘制草图功能错误
                            if (bDoubleClickMark == true)
                            {
                                dToLength = 0;
                                bDoubleClickMark = false;
                            }
                            sMapUnits = "米";
                            if (dToLength > 1000)
                            {
                                sMapUnits = "千米";
                                dToLength = Math.Round((dToLength / 1000).ToDouble(), 6);
                            }
                            main.Txt_Length.Text = String.Format("{0}{1}", dToLength, sMapUnits);
                            dToltalLength = dToltalLength - dSegmentLength; //鼠标移动到新点重新开始计算
                        }
                    }
                }
                else
                {
                    if (m_NewPolygonFeedback != null)
                    {
                        m_NewPolygonFeedback.MoveTo(pMovePt);
                    }
                    //pMouseOperate!=0则测量面积
                    if (pNewPolygonFeedback == null)
                    {
                        return;
                    }
                    if (pNewPolygonFeedback != null)
                    {
                        pNewPolygonFeedback.MoveTo(pMovePt);
                    }
                    IPointCollection pPointCol = new Polygon();    //对面积测量时所画的点进行存储
                    pPolygon = new PolygonClass();
                    IGeometry pGeo = null;//创建几何对象
                    ITopologicalOperator pTopo = null;//包含拓扑关系运算功能
                    for (int i = 0; i <= pAreaPointCol.PointCount - 1; i++)
                    {
                        pPointCol.AddPoint(pAreaPointCol.get_Point(i), ref missing, ref missing);
                    }
                    pPointCol.AddPoint(pMovePt, ref missing, ref missing);
                    if (pPointPt != null)
                    {
                        //向pNewLineFeedbackLike中添加两个点组成一条线
                        IPointCollection pNewLineFeedbackLike = new Polyline();
                        pNewLineFeedbackLike.AddPoint(pMovePt);
                        pNewLineFeedbackLike.AddPoint(pPointPt);
                        DsumLength = (pNewLineFeedbackLike as IPolyline).Length;
                    }
                    //     main.Txt_AreaSegment.Text = String.Format("{0}{1}", Math.Round(DsumLength, 3), sMapUnits);
                    if (pPointCol.PointCount < 3) return;
                    pPolygon = pPointCol as IPolygon;
                    if ((pPolygon != null))
                    {
                        pPolygon.Close();
                        pGeo = pPolygon as IGeometry;
                        pTopo = pGeo as ITopologicalOperator;
                        //使几何图形的拓扑正确
                        pTopo.Simplify();
                        //拓扑操作的空间引用设置为数据视图的空间引用
                        pGeo.Project(m_hookHelper.FocusMap.SpatialReference);
                        pArea = pGeo as IArea;//面积量算所画的面
                        Double dobuleArea = Math.Round((pArea.Area).ToDouble(), 3);
                        //解决在地图上绘制草图功能错误
                        if (bDoubleClickMark == true)
                        {
                            dobuleArea = 0;
                            bDoubleClickMark = false;
                        }
                        sMapUnits = "平方米";
                        if (dobuleArea > 10000)
                        {
                            dobuleArea = Math.Round((dobuleArea / 10000).ToDouble(), 6);
                            sMapUnits = "公顷";
                        }
                        if (dobuleArea > 1000000)
                        {
                            dobuleArea = Math.Round((dobuleArea / 1000000).ToDouble(), 6);
                            sMapUnits = "平方千米";
                        }
                        main.Txt_SumArea.Text = String.Format("{0}{1}", dobuleArea, sMapUnits);
                        //    main.Txt_AreaLength.Text = String.Format("{0}{1}", Math.Round(pPolygon.Length, 3), sMapUnits);
                        pPolygon = null;
                    }
                }
            }
            catch (Exception ex)
            {
                //LogAPI.Debug("测量异常!" + en.Message);
                
                LogAPI.Debug("使用测量工具期间 调用鼠标移动事件 时异常,异常信息如下:");
                LogAPI.Debug(ex);
                LogAPI.Debug("使用测量工具期间 调用鼠标移动事件 时异常信息结束");
            }
        }
        public override void OnMouseUp(int Button, int Shift, int X, int Y)
        {
            try
            {
                if (pMouseOperate != 2)
                {
                    return;
                }
                IGeometry pGeotry = m_NewPolygonFeedback.Stop();
                //IPoint currentPoint = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
                List layers = MapsManager.Instance.MapService.GetAllVisibleLayerInMap();
                List features = Identify(pGeotry, layers);
                if (features != null && features.Count >= 1)
                {
                    pArea = features[0].Shape as IArea;//面积量算所画的面
                    if (pArea != null)
                    {
                        Double dobuleArea = Math.Round((pArea.Area).ToDouble(), 3);
                        //解决在地图上绘制草图功能错误
                        if (bDoubleClickMark == true)
                        {
                            dobuleArea = 0;
                            bDoubleClickMark = false;
                        }
                        for (int i = 1; i < features.Count; i++)
                        {
                            dobuleArea += Math.Round(((features[i].Shape as IArea).Area).ToDouble(), 3);
                        }
                        sMapUnits = "平方米";
                        if (dobuleArea > 10000)
                        {
                            dobuleArea = Math.Round((dobuleArea / 10000).ToDouble(), 6);
                            sMapUnits = "公顷";
                        }
                        if (dobuleArea > 1000000)
                        {
                            dobuleArea = Math.Round((dobuleArea / 1000000).ToDouble(), 6);
                            sMapUnits = "平方千米";
                        }
                        this.main.Grid_Area.Visibility = System.Windows.Visibility.Visible;
                        this.main.Grid_Length.Visibility = System.Windows.Visibility.Collapsed;
                        main.Txt_SumArea.Text = String.Format("{0}{1}", dobuleArea, sMapUnits);
                    }
                    else if ((features[0].Shape as IPolyline) != null)
                    {
                        double dToLength = Math.Round((features[0].Shape as IPolyline).Length, 6);
                        //解决在地图上绘制草图功能错误
                        if (bDoubleClickMark == true)
                        {
                            dToLength = 0;
                            bDoubleClickMark = false;
                        }
                        for (int i = 1; i < features.Count; i++)
                        {
                            dToLength += (features[i].Shape as IPolyline).Length;
                        }
                        sMapUnits = "米";
                        if (dToLength > 1000)
                        {
                            sMapUnits = "千米";
                            dToLength = Math.Round((dToLength / 1000).ToDouble(), 6);
                        }
                        this.main.Grid_Area.Visibility = System.Windows.Visibility.Collapsed;
                        this.main.Grid_Length.Visibility = System.Windows.Visibility.Visible;
                        main.Txt_Length.Text = String.Format("{0}{1}", dToLength, sMapUnits);
                    }
                    else
                    {
                        main.Txt_SumArea.Text = "";
                        main.Txt_Length.Text = "";
                    }
                }
                else
                {
                    main.Txt_SumArea.Text = "";
                    main.Txt_Length.Text = "";
                }
            }
            catch (Exception ex)
            {
                //Common.Utility.LogAPI.Debug(ex);
                LogAPI.Debug("使用测量工具期间 鼠标抬起 时异常,异常信息如下:");
                LogAPI.Debug(ex);
                LogAPI.Debug("使用测量工具期间 鼠标抬起 时异常信息结束");
            }
            base.OnMouseUp(Button, Shift, X, Y);
        }
        public override bool Enabled
        {
            get
            {
                return true;
            }
        }
        /// 
        /// 根据图形捕捉要素
        /// 
        /// 
        /// 
        /// 
        public List Identify(IGeometry pGeo, List pLayers, int buffer = 5)
        {
            List result = new List();
            ESRI.ArcGIS.esriSystem.IArray arrayFlush = new ESRI.ArcGIS.esriSystem.ArrayClass();
            try
            {
                if (pGeo != null && !pGeo.IsEmpty && pLayers != null)
                {
                    foreach (IFeatureLayer item in pLayers)
                    {
                        IIdentify identify = item as IIdentify;
                        if (identify == null)
                            continue;
                        //ITopologicalOperator pTopo = pGeo as ITopologicalOperator;
                        //IGeometry pGeometry = pTopo.Buffer(buffer).Envelope as IGeometry;
                        ESRI.ArcGIS.esriSystem.IArray array = identify.Identify(pGeo);
                        if (array == null)
                            continue;
                        for (int i = 0; i < array.Count; i++)
                        {
                            IRowIdentifyObject row = (IRowIdentifyObject)array.get_Element(i);
                            if (row == null)
                                continue;
                            IFeature f = row.Row as IFeature;
                            result.Add(f);
                            arrayFlush.Add(f.ShapeCopy);
                        }
                        if (arrayFlush.Count > 0)
                        {
                            FlashShapeArray(m_hookHelper, arrayFlush);
                        }
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                LogAPI.Debug("使用测量工具期间 根据图形捕捉要素 时异常,异常信息如下:");
                LogAPI.Debug(ex);
                LogAPI.Debug("使用测量工具期间 根据图形捕捉要素 时异常信息结束");
                throw ex;
            }
            return result;
        }
        /// 
        /// 通过IHookActions闪烁要素集合 
        /// 
        /// 
        /// 
        public static void FlashShapeArray(IHookHelper m_hookHelper, IArray geoArray)
        {
            IHookActions hookActions = (IHookActions)m_hookHelper;
            //hookActions.DoActionOnMultiple(geoArray, esriHookActions.esriHookActionsPan);
            //hookActions.DoActionOnMultiple(geoArray, esriHookActions.esriHookActionsGraphic);
            //hookActions.DoActionOnMultiple(geoArray, esriHookActions.esriHookActionsZoom);
            System.Windows.Forms.Application.DoEvents();
            //m_hookHelper.ActiveView.ScreenDisplay.UpdateWindow();
            hookActions.DoActionOnMultiple(geoArray, esriHookActions.esriHookActionsFlash);
        }
    }
}