using FeMM.Common.Helpers;
using FeMM.Grasshopper.Helpers;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
using St7API;
using System;
using System.Collections.Generic;
using System.Linq;

namespace FeMM.Grasshopper.Components.ST2R
{
    public class St7GetAllLinkConnectivityComponent : GH_Component
    {
        private bool _run = false;

        public St7GetAllLinkConnectivityComponent()
            : base("Get Link Connectivity", "GetLinkConnectivity",
                  "Returns link connectivity",
                  CategoryNameConstants.CATEGORY_F2R, CategoryNameConstants.SUBCATEGORY_ST2R_BAKE)
        { }

        public override void CreateAttributes()
        {
            var buttonAttributes = new ComponentAttributes.ComponentOneButtonAttributes(this, "Get Link Coonnectivity");
            buttonAttributes.ButtonPressed += () =>
            {
                _run = true;
                ExpireSolution(true); // triggers SolveInstance
            };
            m_attributes = buttonAttributes;
        }

        protected override void RegisterInputParams(GH_InputParamManager p)
        {
            p.AddIntegerParameter("uID", "ID", "Straus7 model file ID", GH_ParamAccess.item);
        }

        protected override void RegisterOutputParams(GH_OutputParamManager p)
        {
            p.AddIntegerParameter("LinkNumbers", "Links", "Link numbers", GH_ParamAccess.tree);
            p.AddIntegerParameter("NumNodes", "NumNodes", "Number of nodes in each link", GH_ParamAccess.tree);
            p.AddIntegerParameter("NodeNumbers", "Nodes", "Node numbers for each link", GH_ParamAccess.tree);
            p.AddTextParameter("Log", "Log", "Debug messages", GH_ParamAccess.list);
        }

        protected override void SolveInstance(IGH_DataAccess DA)
        {
            int uid = 0;
            if (!DA.GetData(0, ref uid)) return;

            List<string> log = [];
            GH_Structure<GH_Integer> linkNumbersTree = new();
            GH_Structure<GH_Integer> numNodesTree = new();
            GH_Structure<GH_Integer> nodeNumbersTree = new();

            if (!_run)
            {
                DA.SetDataTree(0, linkNumbersTree);
                DA.SetDataTree(1, numNodesTree);
                DA.SetDataTree(2, nodeNumbersTree);
                DA.SetDataList(3, log);
                return;
            }

            try
            {
                int linkNum = 0;
                while (true)
                {
                    linkNum++;
                    int maxNodes = 1000;
                    var connection = new int[maxNodes];
                    var connectionElement = new int[21];

                    if (StrausR3Helper.HandleError(St7.St7GetElementConnection(uid, St7.tyLINK, linkNum, connectionElement)) ||
                        connectionElement[0] == 0)
                    {
                        log.Add($"Stopped at Link {linkNum}");
                        break;
                    }

                    int linkType = 0;
                    if (StrausR3Helper.HandleError(St7.St7GetLinkType(uid, linkNum, ref linkType)))
                    {
                        log.Add($"Error on get type of Link {linkNum}");
                        continue;
                    }

                    int numNodesRes = 0;
                    int startIndexCon = 0;

                    if (linkType == St7.ltMasterSlaveLink)
                    {
                        int linkUcs = 0;
                        var linkIntegers = new int[6];
                        if (StrausR3Helper.HandleError(St7.St7GetMasterSlaveLink(uid, linkNum, ref linkUcs, connection, linkIntegers)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        numNodesRes = connection[0];
                        startIndexCon = 1;
                    }
                    else if (linkType == St7.ltSectorSymmetryLink)
                    {
                        int axis = 0;
                        if (StrausR3Helper.HandleError(St7.St7GetSectorSymmetryLink(uid, linkNum, ref axis, connection)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        numNodesRes = connection[0];
                        startIndexCon = 1;
                    }
                    else if (linkType == St7.ltCouplingLink)
                    {
                        int couple = 0;
                        if (StrausR3Helper.HandleError(St7.St7GetCouplingLink(uid, linkNum, ref couple, connection)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        numNodesRes = connection[0];
                        startIndexCon = 1;
                    }
                    else if (linkType == St7.ltPinnedLink)
                    {
                        if (StrausR3Helper.HandleError(St7.St7GetPinnedLink(uid, linkNum, connection)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        numNodesRes = connection[0];
                        startIndexCon = 1;
                    }
                    else if (linkType == St7.ltRigidLink)
                    {
                        int ucsId = 0;
                        int plane = 0;
                        if (StrausR3Helper.HandleError(St7.St7GetRigidLink(uid, linkNum, ref ucsId, ref plane, connection)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        numNodesRes = connection[0];
                        startIndexCon = 1;
                    }
                    else if (linkType == St7.ltShrinkLink)
                    {
                        var linkIntegers = new int[4];
                        if (StrausR3Helper.HandleError(St7.St7GetShrinkLink(uid, linkNum, connection, linkIntegers)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        numNodesRes = connection[0];
                        startIndexCon = 1;
                    }
                    else if (linkType == St7.ltTwoPointLink)
                    {
                        var linkIntegers = new int[5];
                        var linkDoubles = new double[3];
                        if (StrausR3Helper.HandleError(St7.St7GetTwoPointLink(uid, linkNum, connection, linkIntegers, linkDoubles)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        numNodesRes = connection[0];
                        startIndexCon = 1;
                    }
                    else if (linkType == St7.ltAttachmentLink)
                    {
                        var linkIntegers = new int[4];
                        var linkDoubles = new double[3];
                        if (StrausR3Helper.HandleError(St7.St7GetAttachmentLink(uid, linkNum, connection, linkIntegers, linkDoubles)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        numNodesRes = connection[0];
                        startIndexCon = 1;
                    }
                    else if (linkType == St7.ltInterpolatedMultiPointLink)
                    {
                        int couple = 0;
                        if (StrausR3Helper.HandleError(St7.St7GetInterpolatedMultiPointLink(uid, linkNum, maxNodes, ref numNodesRes, ref couple, connection)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        startIndexCon = 0;
                    }
                    else if (linkType == St7.ltReactionMultiPointLink)
                    {
                        int setNum = 0;
                        var origin = new double[3];
                        if (StrausR3Helper.HandleError(St7.St7GetReactionMultiPointLink(uid, linkNum, maxNodes, ref numNodesRes, ref setNum, connection, origin)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        startIndexCon = 0;
                    }
                    else if (linkType == St7.ltRigidMultiPointLink)
                    {
                        int ucsId = 0;
                        int axis = 0;
                        if (StrausR3Helper.HandleError(St7.St7GetRigidMultiPointLink(uid, linkNum, maxNodes, ref numNodesRes, ref ucsId, ref axis, connection)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        startIndexCon = 0;
                    }
                    else if (linkType == St7.ltPinnedMultiPointLink)
                    {
                        if (StrausR3Helper.HandleError(St7.St7GetPinnedMultiPointLink(uid, linkNum, maxNodes, ref numNodesRes, connection)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        startIndexCon = 0;
                    }
                    else if (linkType == St7.ltMasterSlaveMultiPointLink)
                    {
                        int ucsId = 0;
                        int dofBits = 0;
                        if (StrausR3Helper.HandleError(St7.St7GetMasterSlaveMultiPointLink(uid, linkNum, maxNodes, ref numNodesRes, ref ucsId, ref dofBits, connection)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        startIndexCon = 0;
                    }
                    else if (linkType == St7.ltUserDefinedMultiPointLink)
                    {
                        int caseNum = 0;
                        double cFactor = 0;
                        var linkIntegers = new int[maxNodes];
                        var linkDoubles = new double[maxNodes];
                        if (StrausR3Helper.HandleError(St7.St7GetUserDefinedMultiPointLink(uid, linkNum, maxNodes, ref numNodesRes, ref caseNum, ref cFactor, connection, linkIntegers, linkDoubles)))
                        {
                            log.Add($"Error on get connections of Link {linkNum}");
                            continue;
                        }
                        startIndexCon = 0;
                    }
                    else
                    {
                        log.Add($"Wrong type of Link {linkNum}");
                        continue;
                    }

                    GH_Path linkPath = new(linkNum - 1);

                    // Output the link number
                    linkNumbersTree.Append(new GH_Integer(linkNum), linkPath);

                    // Output the number of nodes
                    numNodesTree.Append(new GH_Integer(numNodesRes), linkPath);

                    // Output the node numbers (excluding the first number)
                    for (int i = startIndexCon; i < startIndexCon + numNodesRes; i++)
                    {
                        nodeNumbersTree.Append(new GH_Integer(connection[i]), linkPath);
                    }
                    var strConnection = StringExtensions.Join(",", [.. connection.Select(i => i.ToString())], startIndexCon, numNodesRes);
                    log.Add($"Link {linkNum}: Type={linkType} NumNodes={numNodesRes}, Nodes=[{strConnection}]");
                }
            }
            catch (Exception)
            {
            }

            DA.SetDataTree(0, linkNumbersTree);
            DA.SetDataTree(1, numNodesTree);
            DA.SetDataTree(2, nodeNumbersTree);
            DA.SetDataList(3, log);

            _run = false;
        }

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

        public override Guid ComponentGuid => new("a4b5c6d7-8901-4abc-9d12-abcdef123468");
    }
}
303 files24 directories