using FeMM.Grasshopper.Helpers;
using Grasshopper.Kernel;
using St7API;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace FeMM.Grasshopper.Components.ST2R
{
    public class St7OpenModelComponent : GH_Component
    {
        private bool _run = false;
        private static readonly HashSet<int> _usedIDs = [];

        public St7OpenModelComponent()
            : base("Open Straus7 Model", "OpenModel",
                  "Open a Straus7 model and create scratch files",
                  CategoryNameConstants.CATEGORY_F2R, CategoryNameConstants.SUBCATEGORY_ST2R_BAKE)
        {
        }

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

        protected override void RegisterInputParams(GH_InputParamManager pManager)
        {
            pManager.AddTextParameter("Model Path", "MP", "Straus7 model path to open", GH_ParamAccess.item);
        }

        protected override void RegisterOutputParams(GH_OutputParamManager pManager)
        {
            pManager.AddIntegerParameter("uID", "ID", "Straus7 Model ID", GH_ParamAccess.item);
            pManager.AddTextParameter("Log", "Log", "Debug log messages", GH_ParamAccess.list);
        }

        protected override void SolveInstance(IGH_DataAccess DA)
        {
            string modelPath = "";
            if (!DA.GetData(0, ref modelPath)) return;
            List<string> log = [];

            if (!_run)
            {
                DA.SetDataList(1, log);
                return;
            }

            if (!File.Exists(modelPath))
            {
                log.Add("ERROR: Model path does not exist: " + modelPath);
                DA.SetDataList(1, log);
                _run = false;
                return;
            }

            // Initialize API
            int initErr = St7.St7Init();
            log.Add("St7Init code = " + initErr);
            if (initErr != St7.ERR7_NoError)
            {
                log.Add("ERROR: Failed to initialize Straus7 API");
                DA.SetDataList(1, log);
                _run = false;
                return;
            }

            // Select a free uID (1–32)
            int uID = -1;
            for (int i = 1; i <= 32; i++)
            {
                if (!_usedIDs.Contains(i))
                {
                    uID = i;
                    _usedIDs.Add(i);
                    break;
                }
            }

            if (uID == -1)
            {
                log.Add("ERROR: No free model IDs available (max 32 models can be open)");
                DA.SetDataList(1, log);
                _run = false;
                return;
            }

            log.Add("Using uID = " + uID);

            // Use temp folder as scratch path
            string scratchPath = Path.GetTempPath();
            log.Add("Using scratch path: " + scratchPath);

            // Open model
            int openErr = St7.St7OpenFile(uID, modelPath, scratchPath);
            if (openErr != St7.ERR7_NoError)
            {
                StringBuilder sb = new(St7.kMaxStrLen);
                var _ = St7.St7GetAPIErrorString(openErr, sb, sb.Capacity);
                log.Add("ERROR: Failed to open model: " + sb);
                _usedIDs.Remove(uID); // free ID
                DA.SetDataList(1, log);
                _run = false;
                return;
            }

            log.Add("Model opened successfully, uID = " + uID);
            DA.SetData(0, uID);
            DA.SetDataList(1, log);

            _run = false;
        }

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

        public override Guid ComponentGuid => new("a7f6f3e8-1234-4b56-987a-abcdef123456");
    }
}
303 files24 directories