using SAP2000v1;
using FeMM.Grasshopper.Helpers;
using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Versioning;
using System.Windows.Forms;

namespace FeMM.Grasshopper.Components.SAPExtra
{
#if NETCOREAPP
    [SupportedOSPlatform("windows")]
#endif
    public class SAPAddLoadCase : GH_Component
    {
        private bool _run = false;

        public override void CreateAttributes()
        {
            var buttonAttributes = new ComponentAttributes.ComponentOneButtonAttributes(this, "Run");
            buttonAttributes.ButtonPressed += () =>
            {
                _run = true;
                ExpireSolution(true);
            };

            m_attributes = buttonAttributes;
        }

        /// <summary>
        /// Initializes a new instance of the SAPAddLoadCase class.
        /// </summary>
        public SAPAddLoadCase()
          : base("Add Load Cases", "ALC", "SAP Add Load Case", CategoryNameConstants.CATEGORY_CHECKS, CategoryNameConstants.SUBCATEGORY_SAPEXTRA)
        {
        }

        /// <summary>
        /// Registers all the input parameters for this component.
        /// </summary>
        protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
        {
            pManager.AddTextParameter("Sap Model", "M", "Sap model", GH_ParamAccess.item);
            pManager.AddTextParameter("Load Case Name", "LC", "Load Case Name", GH_ParamAccess.list);
            pManager.AddTextParameter("Load Pattern Name", "LP", "Load Name", GH_ParamAccess.tree);
            pManager.AddNumberParameter("Factors", "F", "Factors", GH_ParamAccess.tree);
            pManager.AddTextParameter("Type", "T", "Linear Add, Envelope, Absolute, SRSS, Range", GH_ParamAccess.list);
        }

        /// <summary>
        /// Registers all the output parameters for this component.
        /// </summary>
        protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
        {
            pManager.AddBooleanParameter("Worked", "W", "Worked", 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)
        {
            string sap_model = "";
            var LCName = new List<string>();
            var LoadName = new DataTree<string>();
            var LoadNameInput = new GH_Structure<GH_String>();
            var Factors = new DataTree<double>();
            var FactorsInput = new GH_Structure<GH_Number>();
            var Type = new List<string>();

            DA.GetData(0, ref sap_model);
            DA.GetDataList(1, LCName);
            DA.GetDataTree(2, out LoadNameInput);
            DA.GetDataTree(3, out FactorsInput);
            DA.GetDataList(4, Type);

            for (int i = 0; i < LoadNameInput.Branches.Count; i++)
                for (int j = 0; j < LoadNameInput.Branches[i].Count; j++)
                    LoadName.Add(LoadNameInput.Branches[i].ElementAt(j).Value, new GH_Path(i));

            for (int i = 0; i < FactorsInput.Branches.Count; i++)
                for (int j = 0; j < FactorsInput.Branches[i].Count; j++)
                    Factors.Add(FactorsInput.Branches[i].ElementAt(j).Value, new GH_Path(i));

            bool worked;
            bool problems = false;

            if (_run)
            {
                ExternalProgram.CSIComObjects.InizializeSAPModel(out cSapModel mySapModel, out cOAPI mySapObject, out cHelper myHelper, false, sap_model, eUnits.N_mm_C, true);

                for (int i = 0; i < LCName.Count; i++)
                {
                    if (Type[i].ToLower() == "linear")
                    {
                        if (mySapModel.LoadCases.StaticLinear.SetCase(LCName[i]) != 0)
                        {
                            problems = true;
                            MessageBox.Show($"Problem Set Linear Case {LCName[i]}");
                        }

                        //set Loads
                        int nr_loads = LoadName.Branch(i).Count;
                        string[] loadtype = new string[nr_loads]; // Load - Accel
                        for (int j = 0; j < nr_loads; j++)
                        {
                            if (LoadName.Branch(i)[j] == "UX" || LoadName.Branch(i)[j] == "UY" || LoadName.Branch(i)[j] == "UZ" ||
                                LoadName.Branch(i)[j] == "RX" || LoadName.Branch(i)[j] == "RY" || LoadName.Branch(i)[j] == "RZ")
                            {
                                loadtype[j] = "Accel";
                            }
                            else
                            {
                                loadtype[j] = "Load";
                            }
                        }

                        string[] loadname = [.. LoadName.Branch(i)];
                        double[] factors = [.. Factors.Branch(i)];

                        if (mySapModel.LoadCases.StaticLinear.SetLoads(LCName[i], nr_loads, ref loadtype, ref loadname, ref factors) != 0)
                        {
                            problems = true;
                            MessageBox.Show("Problem Set Loads for " + LCName[i]);
                        }
                    }
                    else
                    {
                        //add non linear case
                        if (mySapModel.LoadCases.StaticNonlinear.SetCase(LCName[i]) != 0)
                        {
                            problems = true;
                            MessageBox.Show("Problem Set Non Linear Case");
                        }

                        //set Loads
                        int nr_loads = LoadName.Branch(i).Count;
                        string[] loadtype = new string[nr_loads]; // Load - Accel
                        for (int j = 0; j < nr_loads; j++)
                        {
                            if (LoadName.Branch(i)[j] == "UX" || LoadName.Branch(i)[j] == "UY" || LoadName.Branch(i)[j] == "UZ" ||
                                LoadName.Branch(i)[j] == "RX" || LoadName.Branch(i)[j] == "RY" || LoadName.Branch(i)[j] == "RZ")
                            {
                                loadtype[j] = "Accel";
                            }
                            else
                            {
                                loadtype[j] = "Load";
                            }
                        }

                        string[] loadname = [.. LoadName.Branch(i)];
                        double[] factors = [.. Factors.Branch(i)];
                        if (mySapModel.LoadCases.StaticNonlinear.SetLoads(LCName[i], nr_loads, ref loadtype, ref loadname, ref factors) != 0)
                        {
                            problems = true;
                            MessageBox.Show("Problem Set Loads for " + LCName[i]);
                        }

                        //set non linear type
                        if (mySapModel.LoadCases.StaticNonlinear.SetGeometricNonlinearity(LCName[i], Convert_nl(Type[i])) != 0)
                        {
                            problems = true;
                            MessageBox.Show("Problem Set NON LINEAR TYPE for " + LCName[i]);
                        }
                    }
                }

                if (mySapObject.SapModel.File.Save() != 0)
                {
                    problems = true;
                    MessageBox.Show("Problem Save file");
                }


                if (problems == false)
                    worked = true;
                else
                    worked = false;

                DA.SetData(0, worked);

                _run = false;
            }
        }

        public int Convert_nl(string s)
        {
            int r;
            if (s.ToLower() == "nonlinear")
                r = 0;
            else if (s.ToLower() == "p-delta")
                r = 1;
            else
                return 2;

            return r;
        }

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

        /// <summary>
        /// Gets the unique ID for this component. Do not change this ID after release.
        /// </summary>
        public override Guid ComponentGuid => new("7b0941bb-325c-4540-bd64-5c87f3aaa557");
    }
}
303 files24 directories