using FeMM.Common.Helpers;
using FeMM.Common.Models;
using FeMM.Grasshopper.ComponentAttributes;
using FeMM.Grasshopper.Components.Parameters;
using FeMM.Grasshopper.DataTypes.FeMM;
using FeMM.Grasshopper.Helpers;
using GH_IO.Serialization;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Parameters;
using Rhino.Geometry;
using System;
using System.Runtime.Versioning;

namespace FeMM.Grasshopper.Components.Loads
{
#if NETCOREAPP
    [SupportedOSPlatform("windows")]
#endif
    public class BeamNSMassComponent : GH_Component
    {
        /// <summary>
        /// Initializes a new instance of the BeamNSMassComponent class.
        /// </summary>
        public BeamNSMassComponent()
          : base("Beam non structural Mass", "BNSM", "Assign a beam non structural mass", CategoryNameConstants.CATEGORY_FEMM, CategoryNameConstants.SUBCATEGORY_LOADS)
        {

        }

        public override void CreateAttributes()
        {
            var attr = new ComponentWithImageAttributes(this, Properties.Resources.BeamDistributedLoadType1Image);
            attr.AddOverlappedBitmap(new System.Drawing.PointF(5, -65), Properties.Resources.LocalAxisImage);
            m_attributes = attr;
        }

        /// <summary>
        /// Registers all the input parameters for this component.
        /// </summary>
        protected override void RegisterInputParams(GH_InputParamManager pManager)
        {
            pManager.AddGenericParameter("Beam", "B", "The beam where add the mass", GH_ParamAccess.item);
            pManager.AddGenericParameter("LoadCase", "LC", "The load case", GH_ParamAccess.item);
            pManager.AddIntegerParameter("Type", "T", "Load Type", GH_ParamAccess.item, 0);
            Param_Integer type_param = (Param_Integer)pManager[2];
            Array values = Enum.GetValues(typeof(BeamNSMassModel.LoadSchema));
            foreach (BeamNSMassModel.LoadSchema val in values)
                type_param.AddNamedValue(val.GetDescription(), (int)val);

            pManager.AddNumberParameter("P1", "P1", "The value of non structural mass at end 1 [Mass]", GH_ParamAccess.item);
            pManager[3].Optional = true;
            pManager.AddNumberParameter("PA", "Pa", "The value of non structural mass at position A [Mass]", GH_ParamAccess.item);
            pManager[4].Optional = true;
            pManager.AddNumberParameter("PB", "Pb", "The value of non structural mass at position B [Mass]", GH_ParamAccess.item);
            pManager[5].Optional = true;
            pManager.AddNumberParameter("P2", "P2", "The value of non structural mass at end 2 [Mass]", GH_ParamAccess.item);
            pManager[6].Optional = true;
            pManager.AddNumberParameter("a", "a", "The distance ratio (0-1) from the starting node", GH_ParamAccess.item, 0);
            pManager.AddNumberParameter("b", "b", "The distance ratio (0-1) from the ending node", GH_ParamAccess.item, 0);
            pManager.AddNumberParameter("Dyn factor", "DF", "The dynamic factor of the structural mass", GH_ParamAccess.item);
            pManager.AddVectorParameter("Offset", "O", "Offset of the mass", GH_ParamAccess.item, Vector3d.Zero);
        }

        private void SetSchemaImage()
        {
            Param_Integer type_param = (Param_Integer)Params.Input[2];
            switch (type_param.PersistentData.Branches[0][0].Value)
            {
                case 0:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType1Image;
                    break;
                case 1:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType2Image;
                    break;
                case 2:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType3Image;
                    break;
                case 3:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType4Image;
                    break;
                case 4:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType5Image;
                    break;
                case 5:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType6Image;
                    break;
            }
        }



        /// <summary>
        /// Registers all the output parameters for this component.
        /// </summary>
        protected override void RegisterOutputParams(GH_OutputParamManager pManager)
        {
            pManager.AddGenericParameter("Beam", "B", "The beam with the NS mass applied", GH_ParamAccess.item);
        }

        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            GH_Beam beam = null;
            GH_Case lc = null;
            int schema = 0;
            double p1 = 0, pa = 0, pb = 0, p2 = 0;
            double a = 0, b = 0;
            double dynFactor = 0;
            Vector3d offset = Vector3d.Unset;

            if (!DA.GetData("Beam", ref beam))
                return;
            if (!DA.GetData("LoadCase", ref lc))
                return;
            if (!DA.GetData("Type", ref schema))
                return;
            bool p1_has_value = DA.GetData("P1", ref p1);
            bool pa_has_value = DA.GetData("PA", ref pa);
            bool pb_has_value = DA.GetData("PB", ref pb);
            bool p2_has_value = DA.GetData("P2", ref p2);
            if (!DA.GetData("a", ref a))
                return;
            if (!DA.GetData("b", ref b))
                return;
            if (!DA.GetData("Dyn factor", ref dynFactor))
                return;
            if (!DA.GetData("Offset", ref offset))
                return;

            bool input_errors = false;
            LoadCaseModel loadCaseModel = null;
            if (lc.Value != null && lc.Value is LoadCaseModel lccc)
                loadCaseModel = new LoadCaseModel(lccc);
            else
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Input case must be a load case");
                return;
            }


            switch (schema)
            {
                case 0:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType1Image;
                    if (!pa_has_value)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameter 'PA' failed to collect data");
                        input_errors = true;
                    }
                    break;
                case 1:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType2Image;
                    if (!pa_has_value || !pb_has_value)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameters 'PA', 'PB' failed to collect data");
                        input_errors = true;
                    }
                    break;
                case 2:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType3Image;
                    if (!p1_has_value || !pa_has_value || !p2_has_value)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameters 'P1', 'PA', 'P2' failed to collect data");
                        input_errors = true;
                    }
                    if (a == 0)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameter 'a' must be greater than 0");
                        input_errors = true;
                    }
                    break;
                case 3:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType4Image;
                    if (!p1_has_value || !pa_has_value || !pb_has_value)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameters 'P1', 'PA', 'PB' failed to collect data");
                        input_errors = true;
                    }
                    if (a == 0)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameter 'a' must be greater than 0");
                        input_errors = true;
                    }
                    break;
                case 4:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType5Image;
                    if (!pa_has_value || !pb_has_value || !p2_has_value)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameters 'PA', 'PB', 'P2' failed to collect data");
                        input_errors = true;
                    }
                    if (b == 0)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameter 'b' must be greater than 0");
                        input_errors = true;
                    }
                    break;
                case 5:
                    ((ComponentWithImageAttributes)m_attributes).Bitmap = Properties.Resources.BeamDistributedLoadType6Image;
                    if (!p1_has_value || !pa_has_value || !pb_has_value || !p2_has_value)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameters 'P1', 'PA', 'PB', 'P2' failed to collect data");
                        input_errors = true;
                    }
                    if (a == 0 || b == 0)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input parameters 'a' and 'b' must be greater than 0");
                        input_errors = true;
                    }
                    break;
            }
            if (a >= 1)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The 'a' value must be lower than 1");
                input_errors = true;
            }
            if (b >= 1)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The 'b' value must be lower than 1");
                input_errors = true;
            }
            if (a + b >= 1)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The sum of a+b must less than 1");
                input_errors = true;
            }


            if (input_errors)
                return;

            BeamNSMassModel.LoadSchema load_schema = (BeamNSMassModel.LoadSchema)schema; 
            var load_value = new BeamNSMassModel.LoadData()
            {
                LoadSchema = load_schema,
                P1 = p1,
                PA = pa,
                PB = pb,
                P2 = p2,
                A = a,
                B = b,
                DynFactor = dynFactor,
                Offset = offset
            };


            var load = new BeamNSMassModel(loadCaseModel, load_value);
            var newBeam = new GH_Beam(beam);
            newBeam.Value.Loads.Add(load);
            DA.SetData(0, newBeam);
        }

        

        public override GH_Exposure Exposure => GH_Exposure.secondary;

        /// <summary>
        /// Provides an Icon for the component. // To be updated
        /// </summary>
        protected override System.Drawing.Bitmap Icon => Properties.Resources.PlateNSMassIcon;

        /// <summary>
        /// Gets the unique ID for this component. Do not change this ID after release.
        /// </summary>
        public override Guid ComponentGuid => new("BEE9A12A-369E-4B22-B8A5-9B617DFCE768");
    }
}
303 files24 directories