using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using KGIS.Framework.Commands;
using KGIS.Framework.Maps;
using KGIS.Framework.Platform.Helper;
using KGIS.Framework.Utils;
using KGIS.Framework.Utils.Dialog;
using KGIS.Framework.Utils.Helper;
using Kingo.PluginServiceInterface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Kingo.Plugin.DataLoad.Commands
{
    /// 
    /// 导出BG数据到SHP文件
    /// 
    public class CmdExportBGDataToSHP : BaseMenuCommand
    {
        IEngineEditor m_pEditor;
        public override void OnClick()
        {
            try
            {
                IFeatureLayer featureClassBG = MapsManager.Instance.MapService.GetFeatureLayerByName("DLTBBG");
                if (featureClassBG == null) return;
                IFeatureLayer pFeatureLayer = featureClassBG as IFeatureLayer;
                KGIS.Framework.Utils.Dialog.FolderBrowserDialog pBrowser = new KGIS.Framework.Utils.Dialog.FolderBrowserDialog
                {
                    ShowNewFolderButton = true
                };
                if (pBrowser.ShowDialog() == DialogResult.OK)
                {
                    string savepath = pBrowser.SelectedPath;
                    string fileName = pFeatureLayer.Name;
                    IQueryFilter queryfilter = new QueryFilterClass();
                    fileName = pFeatureLayer.FeatureClass.AliasName;
                    if (System.IO.File.Exists(System.IO.Path.Combine(savepath, fileName + ".shp")) || System.IO.File.Exists(System.IO.Path.Combine(savepath, fileName + ".SHP")))
                    {
                        if (MessageHelper.ShowYesNoAndTips("同名文件已存在是否替换?") != DialogResult.Yes)
                        {
                            return;
                        }
                        DeleteShp(pFeatureLayer.FeatureClass.AliasName, savepath);
                    }
                    ExportFeaturesToShp(pFeatureLayer.FeatureClass, queryfilter, savepath, fileName);
                    MessageHelper.ShowTips("导出成功!");
                }
            }
            catch (Exception ex)
            {
                MessageHelper.ShowTips("数据导出失败!");
                LogAPI.Debug("数据导出异常:" + ex);
            }
        }
        /// 
        /// 导出SHP数据
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void ExportFeaturesToShp(IFeatureClass pSourceFeatureClass, IQueryFilter pQueryFilter, string forlder, string fileName)
        {
            IWorkspaceFactory workFactory = null;
            IFeatureWorkspace pFeatureWorkspace = null;
            IFeatureCursor pFeatureCursor = null;
            IFeatureClass pFeatureClass = null;
            IFeatureCursor pInsertFeatureCursor = null;
            int count = 0;
            try
            {
                if (pSourceFeatureClass == null)
                {
                    MessageHelper.ShowTips("未获取到要素集!");
                    return;
                }
                if (!System.IO.Directory.Exists(forlder))
                {
                    System.IO.Directory.CreateDirectory(forlder);
                }
                count = pSourceFeatureClass.FeatureCount(pQueryFilter);
                pFeatureCursor = pSourceFeatureClass.Search(pQueryFilter, true);
                ProgressHelper.ShowProcessBar("正在导出,请稍候...");
                workFactory = new ESRI.ArcGIS.DataSourcesFile.ShapefileWorkspaceFactoryClass();
                pFeatureWorkspace = workFactory.OpenFromFile(forlder, 0) as IFeatureWorkspace;
                //创建字段信息
                IFields pFields = new FieldsClass();
                IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;
                List fieldNames = new List();
                for (int i = 0; i < pSourceFeatureClass.Fields.FieldCount; i++)
                {
                    IField field = pSourceFeatureClass.Fields.get_Field(i);
                    if ("XZQTZLX,BGZT,JCZT,TZ,BGDL,BGFW,WBGLX,SJLY,SFJCTB,NYJY,NYYPDL,SFJZ,ONLYZLBG".Contains(field.Name))
                        continue;
                    if ((field.Type == esriFieldType.esriFieldTypeBlob || field.Type == esriFieldType.esriFieldTypeRaster) && field.Type != esriFieldType.esriFieldTypeGeometry)
                        continue;
                    if (field.Type == esriFieldType.esriFieldTypeGeometry)
                    {
                        IField pField = new FieldClass();
                        IFieldEdit pFieldEdit = pField as IFieldEdit;
                        pFieldEdit.Name_2 = "Shape";
                        pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
                        IGeometryDef pGeometryDef = new GeometryDef();
                        IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit;
                        pGeometryDefEdit.GeometryType_2 = pSourceFeatureClass.ShapeType;//pFeature.Shape.GeometryType;
                        if ((pSourceFeatureClass as IGeoDataset) != null)
                        {
                            pGeometryDefEdit.SpatialReference_2 = (pSourceFeatureClass as IGeoDataset).SpatialReference;//pFeature.Shape.SpatialReference;
                        }
                        pFieldEdit.GeometryDef_2 = pGeometryDef;
                        pFieldsEdit.AddField(pField);
                    }
                    else
                    {
                        IField pField = new FieldClass();
                        IFieldEdit pFieldEdit = pField as IFieldEdit;
                        pFieldEdit.Length_2 = field.Length;
                        if (field.AliasName == "种植属性名称")
                        {
                            pFieldEdit.Length_2 = field.Length + 10;
                        }
                        if (field.Name.Length > 10)
                        {
                            string fname = field.Name.Substring(0, 10);
                            int n = 1;
                            while (fieldNames.Contains(fname))
                            {
                                string end = n.ToString();
                                fname = fname.Remove(10 - end.Length) + end;
                                n++;
                            }
                            pFieldEdit.Name_2 = fname;
                        }
                        else
                        {
                            pFieldEdit.Name_2 = field.Name;
                        }
                        fieldNames.Add(pFieldEdit.Name);
                        pFieldEdit.AliasName_2 = field.AliasName;
                        pFieldEdit.Type_2 = field.Type;
                        pFieldsEdit.AddField(pField);
                    }
                }
                pFeatureClass = pFeatureWorkspace.CreateFeatureClass(fileName, pFields, null, null, pSourceFeatureClass.FeatureType, "SHAPE", "");
                pInsertFeatureCursor = pFeatureClass.Insert(true);
                int num = 0;
                ProgressHelper.CountProgress = count;
                Dictionary dicMatchFields = new Dictionary();
                GetMatchFieldsDirectory(pSourceFeatureClass, pFeatureClass, ref dicMatchFields, true);
                IFeatureBuffer featureAdd = pFeatureClass.CreateFeatureBuffer();
                IFeature pFeature = null;
                while ((pFeature = pFeatureCursor.NextFeature()) != null)
                {
                    featureAdd.Shape = pFeature.Shape;
                    foreach (KeyValuePair kvpMatchField in dicMatchFields)
                    {
                        if (pFeature.Value[kvpMatchField.Value] != DBNull.Value)
                        {
                            featureAdd.set_Value(kvpMatchField.Key, pFeature.get_Value(kvpMatchField.Value));
                        }
                        else
                        {
                            featureAdd.set_Value(kvpMatchField.Key, null);
                        }
                    }
                    pInsertFeatureCursor.InsertFeature(featureAdd);
                    num++;
                    if (num % 100 == 0 || num == count)
                    {
                        ProgressHelper.CurrentProgress = num;
                    }
                }
                pInsertFeatureCursor.Flush();
                ProgressHelper.CloseProcessBar();
                //关闭lock
                IWorkspaceFactoryLockControl ipWsFactoryLock = (IWorkspaceFactoryLockControl)workFactory;
                if (ipWsFactoryLock.SchemaLockingEnabled)
                {
                    ipWsFactoryLock.DisableSchemaLocking();
                }
            }
            catch (Exception ex)
            {
                ProgressHelper.CloseProcessBar();
                MessageHelper.ShowError("导出SHAPE文件出错:" + ex.Message);
                LogAPI.Debug("导出SHAPE文件出错,可能的原因是:" + ex.Message);
            }
            finally
            {
                if (pFeatureCursor != null)
                {
                    Marshal.ReleaseComObject(pFeatureCursor);
                }
                if (pFeatureClass != null)
                {
                    Marshal.ReleaseComObject(pFeatureClass);
                }
                if (pInsertFeatureCursor != null)
                {
                    Marshal.ReleaseComObject(pInsertFeatureCursor);
                }
                if (pFeatureWorkspace != null)
                {
                    Marshal.ReleaseComObject(pFeatureWorkspace);
                }
                if (workFactory != null)
                {
                    Marshal.ReleaseComObject(workFactory);
                }
            }
        }
        /// 
        /// 删除同名SHP
        /// 
        /// 
        public static void DeleteShp(string fileName, string filePath)
        {
            IWorkspace pWorkspace = null;
            IWorkspaceFactory pWorkspaceFactory = null;
            IFeatureClass pFeatureClass = null;
            try
            {
                //打开shp工作空间
                pWorkspaceFactory = new ESRI.ArcGIS.DataSourcesFile.ShapefileWorkspaceFactory();
                pWorkspace = pWorkspaceFactory.OpenFromFile(filePath, 0);
                IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace;
                pFeatureClass = pFeatureWorkspace.OpenFeatureClass(fileName);
                IDataset pFeaDataset = pFeatureClass as IDataset;
                pFeaDataset.Delete();
            }
            catch (Exception ex)
            {
                LogAPI.Debug("删除shp失败,报错原因是:" + ex.Message);
            }
            finally
            {
                if (pWorkspaceFactory != null)
                {
                    Marshal.ReleaseComObject(pWorkspaceFactory);
                }
                if (pWorkspace != null)
                {
                    Marshal.ReleaseComObject(pWorkspace);
                }
                if (pFeatureClass != null)
                {
                    Marshal.ReleaseComObject(pFeatureClass);
                }
            }
        }
        /// 
        /// 获得匹配的字段索引集合
        /// 
        /// 源要素类
        /// 目标要素类
        /// 匹配字段集合-KEY为目标图层字段,VALUE为源图层字段
        /// 是否获取必须字段
        public static void GetMatchFieldsDirectory(IClass pSourceClass, IClass pTargetClass, ref Dictionary dicMatchFields, bool isGetRequired = false)
        {
            for (int i = 0; i < pTargetClass.Fields.FieldCount; i++)
            {
                IField pTargetField = pTargetClass.Fields.get_Field(i);
                //目标图层的字段必须为可编辑并且不是必须字段
                if (pTargetField.Required == false && pTargetField.Editable == true)
                {
                    int iSourceFeatureClassIndex = pSourceClass.Fields.FindField(pTargetField.Name);
                    if (pTargetField.Name == "SHAPE_Leng")
                    {
                        iSourceFeatureClassIndex = pSourceClass.Fields.FindField("SHAPE_Length");
                    }
                    //源要素类中该字段存在
                    if (iSourceFeatureClassIndex > -1)
                    {
                        IField pSourceField = pSourceClass.Fields.get_Field(iSourceFeatureClassIndex);
                        if ("XZQTZLX,BGZT,JCZT,TZ,BGDL,BGFW,WBGLX,SJLY,SFJCTB,NYJY,NYYPDL,SFJZ,ONLYZLBG".Contains(pSourceField.Name))
                            continue;
                        //目标图层的字段也必须为可编辑并且不是必须字段
                        if (pSourceField.Required == false && pSourceField.Editable == true)
                        {
                            //添加到字段匹配集合中
                            dicMatchFields.Add(i, iSourceFeatureClassIndex);
                        }
                        else if (isGetRequired)
                        {
                            dicMatchFields.Add(i, iSourceFeatureClassIndex);
                        }
                    }
                }
                //此处为了保留原有要素ObjectID字段值
                if (pTargetField.Name.Equals("OIDCOPY", StringComparison.CurrentCultureIgnoreCase))
                {
                    dicMatchFields.Add(i, pSourceClass.FindField(pSourceClass.OIDFieldName));
                }
            }
        }
        public override void OnCreate(object Hook)
        {
            //throw new NotImplementedException();
            m_pEditor = new EngineEditorClass();
        }
        public override bool Enabled => JudgeIsHaveTargetPath();
        private bool JudgeIsHaveTargetPath()
        {
            try
            {
                ProjectInfo prj = MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo;
                if (prj == null)
                {
                    return false;
                }
                return !string.IsNullOrWhiteSpace(prj.BGDatabase) && m_pEditor.EditState == esriEngineEditState.esriEngineStateNotEditing;
            }
            catch (Exception ex)
            {
                LogAPI.Debug("判定 检测数据加载 按钮是否有效时失败,异常原因: " + ex + " ; ");
                return false;
            }
        }
    }
}