/*-------------------------------------------------------------------------
 * 功能描述：ParseDuct
 * 作者：xulisong
 * 创建时间： 2019/6/20 9:40:13
 * 版本号：v1.0
 *  -------------------------------------------------------------------------*/

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using JBIM;
using JBIM.Definition;
using RevitExport.Export;
using RevitToJBim.Common;
using RevitToJBim.ParseData;
using SAGA.RevitUtils.Extends;
using SAGA.RevitUtils.MEP;
using System;
using System.Collections.Generic;
using System.Linq;
using JDuct = JBIM.Component.Duct;
using JDuctShape = JBIM.Definition.DuctShape;
using XYZ = JBIM.Definition.XYZ;

namespace RevitToJBim.ComponentParse
{
    [UsableParse]
    public class ParseDuct : ParseBase
    {
        public override List<string> FastIndex()
        {
            return new List<string>() { typeof(Duct).FullName, typeof(FlexDuct).FullName };
        }
        public override bool Match(ElementWrapper wrapper)
        {
            return wrapper.RefElement is Duct || wrapper.RefElement is FlexDuct;
        }

        protected override List<BimId> ParseInner(ElementWrapper wrapper, JBimParseContext context)
        {
            if (!(wrapper.RefElement is MEPCurve duct))
            {
                return null;
            }
            JDuct jDuct = new JDuct();
            if (duct is FlexDuct)
                jDuct = new JBIM.Component.FlexDuct();
            ParseCore.AttachObject(jDuct, wrapper);
            try
            {
                var locations = new List<XYZ>();
                locations.Add(BimConvert.ConvertToXYZ(duct.GetCurve().StartPoint()));
                locations.Add(BimConvert.ConvertToXYZ(duct.GetCurve().EndPoint()));
                jDuct.Location = GeometryLocation.CreateLineLocation(locations);
                Polygon outLine = new Polygon(locations);
                jDuct.OutLine.Add(outLine);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            context.AddBimObject(jDuct);

            //Parameters
            jDuct.Parameters = RevitUtil.GetMEPCurveParameters(duct);
            #region 关联数据处理相关
            #region 系统关系
            var pipeId = duct.Id.ToString();
            try
            {
                var systemTypeName = duct.Document.GetElement(duct.MEPSystem?.GetTypeId());
                jDuct.MepSystemTypeName = systemTypeName?.Name;
            }
            catch (Exception e)
            {
                //Console.WriteLine(e.Message+e.StackTrace);
            }

            #endregion

            ConnectorProfileType shape = ConnectorProfileType.Invalid;
            #region Connector连接关系
            var connectors = duct.GetConnectors(Autodesk.Revit.DB.Domain.DomainHvac);
            ElementOneToManyRel relMany = new ElementOneToManyRel(pipeId) { RelatedObjects = new List<string>() };
            relMany.SetElementType(TypeDefinition.Property_ConnectedIds);
            foreach (var refConnector in connectors)
            {
                relMany.RelatedObjects.Add(RevitIdGenerator.GetConnectorId(refConnector));
                shape = refConnector.Shape;
            }

            if (relMany.RelatedObjects.Any())
            {
                context.RelationShips.Add(relMany);
            }
            #endregion

            if (shape == ConnectorProfileType.Round)
            {//duct.
                jDuct.Diameter = duct.Diameter.FtToUse();
            }
            else
            {
                jDuct.Width = duct.Width.FtToUse();
                jDuct.Height = duct.Height.FtToUse();
            }

            jDuct.Shape = (JDuctShape)(int)shape;
            #endregion
            return new List<BimId>() { jDuct.Id };
        }

        public override List<ElementWrapper> ArrangeRefElements(ElementWrapper wrapper, JBimParseContext context)
        {
            if (!(wrapper.RefElement is MEPCurve duct))
            {
                return null;
            }
            var wrappers = new List<ElementWrapper>() { };
            var connectors = duct.GetConnectors(Autodesk.Revit.DB.Domain.DomainHvac);
            foreach (var connector in connectors)
            {
                wrappers.Add(ParseCore.GetConnectorWrapper(connector));
            }
            return wrappers;
        }
    }
}
