using FeMM.Common.Helpers;
using FeMM.Common.Models;
using FeMM.Grasshopper.DataTypes.FeMM;
using FeMM.Grasshopper.Helpers;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Parameters;
using System;
using System.Collections.Generic;

namespace FeMM.Grasshopper.Components.ElementProperties
{
    public class LinkDirectionPropertyComponent : GH_Component
    {
        public LinkDirectionPropertyComponent()
          : base("Link Direction Property", "LDP", "Link direction properties", CategoryNameConstants.CATEGORY_FEMM, CategoryNameConstants.SUBCATEGORY_PROPERTIES)
        {
        }

        protected override void RegisterInputParams(GH_InputParamManager pManager)
        {
            pManager.AddIntegerParameter("DOF", "DOF", "Direction", GH_ParamAccess.item);
            foreach (LinkDirectionPropertyModel.DirectionTypes v in Enum.GetValues(typeof(LinkDirectionPropertyModel.DirectionTypes)))
                ((Param_Integer)pManager[pManager.ParamCount - 1]).AddNamedValue(v.GetDescription(), (int)v);
            pManager.AddBooleanParameter("Fixed", "DF", "Is this degree of freedom fixed?", GH_ParamAccess.item, false);
            pManager.AddBooleanParameter("Non linear", "DNL", "Non linear?", GH_ParamAccess.item, false);
            pManager[pManager.ParamCount - 1].Optional = true;
            pManager.AddNumberParameter("Ke", "KE", "Effective Stiffness [F/L or FL]", GH_ParamAccess.item, 0);
            pManager[pManager.ParamCount - 1].Optional = true;
            pManager.AddNumberParameter("Ce", "CE", "Effective damping [F/L or FL]", GH_ParamAccess.item, 0);
            pManager[pManager.ParamCount - 1].Optional = true;
            pManager.AddNumberParameter("k", "k", "Initial stiffness [F/L or FL]", GH_ParamAccess.item, 0);
            pManager[pManager.ParamCount - 1].Optional = true;
            pManager.AddNumberParameter("c", "c", "Damping coefficient [F/(L^cexp) or FL] [Damper link]", GH_ParamAccess.item, 0);
            pManager[pManager.ParamCount - 1].Optional = true;
            pManager.AddNumberParameter("cexp", "cexp", "Damping exponent [Damper link]", GH_ParamAccess.item, 0);
            pManager[pManager.ParamCount - 1].Optional = true;
            pManager.AddNumberParameter("Distance", "Distance", "Initial gap opening or initial hook opening [L or rad] [Gap/Hook link]", GH_ParamAccess.item, 0);
            pManager[pManager.ParamCount - 1].Optional = true;
            pManager.AddIntegerParameter("Hysteresis Type", "HT", "Hysteresis Type [Multilinear plastic link]", GH_ParamAccess.item, 1);
            foreach (LinkDirectionPropertyModel.HysteresisTypes v in Enum.GetValues(typeof(LinkDirectionPropertyModel.HysteresisTypes)))
                ((Param_Integer)pManager[pManager.ParamCount - 1]).AddNamedValue(v.GetDescription(), (int)v);
            pManager[pManager.ParamCount - 1].Optional = true;
            pManager.AddNumberParameter("Displacements", "D", "Displacement / Rotation at each point [Multilinear linear/plastic link]." +
                "The displacements list must be as long as the forces e must have a 0 at the same position in the list", GH_ParamAccess.list);
            pManager[pManager.ParamCount - 1].Optional = true;
            pManager.AddNumberParameter("Forces", "F", "Forces / Moment at each points [Multilinear linear/plastic link]" +
                "The forces list must be as long as the displacements e must have a 0 at the same position in the list", GH_ParamAccess.list);
            pManager[pManager.ParamCount - 1].Optional = true;
        }

        protected override void RegisterOutputParams(GH_OutputParamManager pManager)
        {
            pManager.AddGenericParameter("Link direction property", "DP", "Link direction property", GH_ParamAccess.item);
        }

        protected override void SolveInstance(IGH_DataAccess DA)
        {
            int direction = 0;
            bool isFixed = false;
            bool isNonLinear = false;
            double effectiveStiffness = 0;
            double effectiveDamping = 0;
            double initialStiffness = 0;
            double dampingCoefficient = 0;
            double dampingCoefficientExponent = 0;
            double distance = 0;
            int hystersisType = 0;
            var displacements = new List<double>();
            var forces = new List<double>();

            if (!DA.GetData(0, ref direction))
                return;
            if (!DA.GetData(1, ref isFixed))
                return;
            if (!DA.GetData(2, ref isNonLinear))
                return;
            if (!DA.GetData(3, ref effectiveStiffness))
                return;
            if (!DA.GetData(4, ref effectiveDamping))
                return;
            if (!DA.GetData(5, ref initialStiffness))
                return;
            if (!DA.GetData(6, ref dampingCoefficient))
                return;
            if (!DA.GetData(7, ref dampingCoefficientExponent))
                return;
            if (!DA.GetData(8, ref distance))
                return;
            if (!DA.GetData(9, ref hystersisType))
                return;
            DA.GetDataList(10, displacements);
            DA.GetDataList(11, forces);

            if (!Enum.IsDefined(typeof(LinkDirectionPropertyModel.DirectionTypes), direction))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid degree of freedom");
            }

            if (!Enum.IsDefined(typeof(LinkDirectionPropertyModel.HysteresisTypes), hystersisType))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid hystersis Type");
            }

            if (displacements.Count != forces.Count)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Lenght of displacements and forces must be equal");
            }

            var linkDirectionProperty = new LinkDirectionPropertyModel()
            {
                Direction = (LinkDirectionPropertyModel.DirectionTypes)direction,
                HysteresisType = (LinkDirectionPropertyModel.HysteresisTypes)hystersisType,
                IsFixed = isFixed,
                IsNonLinear = isNonLinear,
                EffectiveDamping = effectiveDamping,
                EffectiveStiffness = effectiveStiffness,
                InitialStiffness = initialStiffness,
                DampingCoefficient = dampingCoefficient,
                DampingCoefficientExponent = dampingCoefficientExponent,
                Distance = distance,
                Displacements = displacements,
                Forces = forces,
            };

            var dataType = new GH_LinkDirectionProperty(linkDirectionProperty);
            DA.SetData(0, dataType);
        }

        public override GH_Exposure Exposure => GH_Exposure.secondary;

        protected override System.Drawing.Bitmap Icon => Properties.Resources.SupportSapLinkConfigIcon;

        public override Guid ComponentGuid => new("4b051322-95a7-46af-9bd7-91634324fd15");
    }
}
303 files24 directories