using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using AutoCAD = Autodesk.AutoCAD.Interop;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Autodesk.AutoCAD.DatabaseServices;
using Newtonsoft.Json;
using TestCad;
using dbx = Autodesk.AutoCAD.Interop.Common;
namespace SmartSoft.ACAD
{
    ///
    /// 读取AutoCAD属性信息
    ///
    public class AutoCADConnector : IDisposable
    {
        private AutoCAD.AcadApplication _Application;
        private bool _Initialized;
        private bool _Disposed;
        private dbx.AxDbDocument doc_as;

        #region 类初始化及析构操作
        ///
        /// 类初始化，试图获取一个正在运行的AutoCAD实例，
        /// 如果没有则新起动一个实例。
        ///
        public AutoCADConnector()
        {
            try
            {
                //取得一个正在运行的AUTOCAD实例
                this._Application = (AutoCAD.AcadApplication)Marshal.GetActiveObject("AutoCAD.Application.22");
            }//end of try
            catch
            {
                try
                {
                    //建立一个新的AUTOCAD实例，并标识已经建立成功。
                    _Application = new AutoCAD.AcadApplication();
                    _Initialized = true;
                }
                catch
                {
                    throw new Exception("无法起动AutoCAD应用程序，确认已经安装");
                }
            }//end of catch
        }//end of AutoCADConnector

        ~AutoCADConnector()
        {
            Dispose(false);
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!this._Disposed && this._Initialized)
            {
                //如果建立了AUTOCAD的实列，调用QUIT方法以避免内存漏洞
                this._Application.ActiveDocument.Close(false, "");
                this._Application.Quit();
                this._Disposed = true;
            }
        }
        #endregion

        #region 公共用户接口属性
        ///
        /// 取得当前类所获得的AUTOCAD实例
        ///
        public AutoCAD.AcadApplication Application
        {
            get
            {
                return _Application;
            }
        }//end of Application
        #endregion

        #region 公共用户接口方法
        ///
        /// 根据给定的文件名以AxDbDocument类型返回该文档
        ///
        public dbx.AxDbDocument GetThisDrawing(string FileName, string PassWord)
        {
            //这是AutoCAD2004的Programe ID
            string programeID = "ObjectDBX.AxDbDocument.22";
            AutoCAD.AcadApplication AcadApp = this.Application;
            dbx.AxDbDocument dbxDoc;
            dbxDoc = (dbx.AxDbDocument)AcadApp.GetInterfaceObject(programeID);
            try
            {
                if (System.IO.File.Exists(FileName) == false) throw new Exception("文件不存在。");

                dbxDoc.Open(FileName, PassWord);
            }// end of try
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
                dbxDoc = null;
            }
            return dbxDoc;
        }//end of function GetThisDrawing

        ///
        /// 根据当前文档和块名取得当前块的引用
        ///
        public dbx.AcadBlockReference GetBlockReference(dbx.AxDbDocument thisDrawing, string blkName)
        {
            dbx.AcadBlockReference blkRef = null;
            bool found = false;
            string str = "";
            try
            {
                foreach (dbx.AcadEntity entity in thisDrawing.ModelSpace)
                {
                    str += entity.EntityName + ",";
                    if (entity.EntityName == "AcDbBlockReference")
                    {
                        blkRef = (dbx.AcadBlockReference)entity;
                        //System.Windows.Forms.MessageBox.Show(blkRef.Name);
                        if (blkRef.Name.ToLower() == blkName.ToLower())
                        {
                            found = true;
                            break;
                        }
                    }//end of entity.EntityName=="AcDbBlockReference"
                }// end of foreach thisDrawing.ModelSpace
            }//end of try
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show("图形中有未知的错误，格式不正确或图形数据库需要修愎。系统错误提示：" + e.Message, "信息", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                thisDrawing = null;
            }//end of catch
            if (!found) blkRef = null;

            return blkRef;
        }//end of function GetBlockReference
         ///
         /// 根据给定的块引用(dbx.AcadBlockReference)和属性名返回属性值
         ///
        public object GetValueByAttributeName(dbx.AcadBlockReference blkRef, string AttributeName)
        {
            object[] Atts = (object[])blkRef.GetAttributes();
            object attValue = null;
            for (int i = 0; i < Atts.Length; i++)
            {
                dbx.AcadAttributeReference attRef;
                attRef = (dbx.AcadAttributeReference)Atts[i];
                if (attRef.TagString == AttributeName)
                {
                    attValue = attRef.TextString;
                    break;
                }
            }//end of for i
            return attValue;
        }// end of function

        //===

        ///
        /// 根据当前文档和实体名取得当前块的引用
        ///
        public void GetEntityReference(dbx.AxDbDocument thisDrawing)
        {
            dbx.AcadEntity entRef = null;
            bool found = false;
            string str = "", str2 = "";
            try
            {
                var mbiDoc = TestCad.Model.Document.CreateDocument();

                foreach (dbx.AcadEntity entity in thisDrawing.ModelSpace)
                {
                    if (entity is dbx.AcadBlockReference blockReference)
                    {
                        var cadObject = new TestCad.Model.BlockReference();
                        cadObject.Handle = entity.Handle;
                        cadObject.Layer = entity.Layer;
                        cadObject.Rotation = blockReference.Rotation;
                        cadObject.Position = ExportUtils.Point2XYZ(blockReference.InsertionPoint);
                        mbiDoc.AddObject(cadObject);
                    }

                    else if (entity is dbx.AcadLine line)
                    {
                        var cadObject = new TestCad.Model.Line();
                        cadObject.Handle = entity.Handle;
                        cadObject.Layer = entity.Layer;
                        cadObject.Start = ExportUtils.Point2XYZ(line.StartPoint);
                        cadObject.End = ExportUtils.Point2XYZ(line.EndPoint);
                        mbiDoc.AddObject(cadObject);
                    }

                    else
                    {
                        if (entity is dbx.AcadLWPolyline polyline)
                        {
                            var tt = thisDrawing.Database.ObjectIdToObject(polyline.ObjectID);

                            var cadObject = ExportUtils.Coordinates2PloyLine(polyline.Coordinates);
                            cadObject.Handle = entity?.Handle;
                            cadObject.Layer = entity.Layer;
                            mbiDoc.AddObject(cadObject);

                        }
                        else if (entity is dbx.AcadCircle circle)
                        {
                            var cadObject = new TestCad.Model.Circle();
                            cadObject.Handle = entity.Handle;
                            cadObject.Layer = entity.Layer;
                            cadObject.Center = ExportUtils.Point2XYZ(circle.Center);
                            cadObject.Radius = circle.Radius;
                            mbiDoc.AddObject(cadObject);
                        }
                        else if (entity is dbx.AcadText text)
                        {
                            var cadObject = new TestCad.Model.DBText();
                            cadObject.Handle = entity.Handle;
                            cadObject.Layer = entity.Layer;
                            cadObject.Position = ExportUtils.Point2XYZ(text.InsertionPoint);
                            cadObject.TextString = text.TextString;
                            mbiDoc.AddObject(cadObject);
                        }
                        else if (entity is dbx.AcadHatch hatch)
                        {

                        }
                        else if (entity is dbx.AcadMText mtext)
                        {
                            var cadObject = new TestCad.Model.DBText();
                            cadObject.Handle = entity.Handle;
                            cadObject.Layer = entity.Layer;
                            cadObject.Position = ExportUtils.Point2XYZ(mtext.InsertionPoint);
                            cadObject.TextString = mtext.TextString;
                            mbiDoc.AddObject(cadObject);
                        }
                        else if (entity is dbx.AcadSolid solid)
                        {
                          
                        }
                        else if (entity is dbx.AcadPoint point)
                        {
                        
                        }
                        else if (entity is dbx.AcadArc arc)
                        {
                            var cadObject = new TestCad.Model.Arc();
                            cadObject.Handle = entity.Handle;
                            cadObject.Layer = entity.Layer;
                            cadObject.Center = ExportUtils.Point2XYZ(arc.Center);
                            cadObject.Radius = arc.Radius;
                            cadObject.StartPoint = ExportUtils.Point2XYZ(arc.StartPoint);
                            cadObject.EndPoint = ExportUtils.Point2XYZ(arc.EndPoint);
                            cadObject.Normal = ExportUtils.Point2XYZ(arc.Normal);
                            mbiDoc.AddObject(cadObject);
                        }
                        else if (entity is dbx.AcadAttribute attribute)
                        {
                           
                        }
                        else
                        {
                            var layer = entity.Layer;
                            if (layer == "PUB_DIM")
                            { }
                            else
                            {
                                var tt = entity;
                            }

                        }
                    }

                }// end of foreach thisDrawing.ModelSpace
                mbiDoc.GroupElements();
                string dataStr = JsonConvert.SerializeObject(mbiDoc);
                string fileName = DateTime.Now.ToString("yyyyMMddHHmmss");
                string path = Path.Combine($"{thisDrawing.Name}_{fileName}.json");
                File.AppendAllText(path, dataStr);
                MessageBox.Show("导出成功");
                //thisDrawing.SaveAs("D:\\ww.dwg");
                //thisDrawing.DxfOut("D:\\dxf.dxf", Type.Missing, Type.Missing);
            }//end of try
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show("图形中有未知的错误，格式不正确或图形数据库需要修愎。系统错误提示：" + e.Message, "信息", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                thisDrawing = null;
            }//end of catch
            
        }//end of function GetBlockReference

        #endregion
    }//end of class CAutoCADConnector
}//end of namespace AutoCAD