using AppsClient.Database;
using AppsClient.Profiles;
using FeMM.Common.Helpers;
using FeMM.Common.Models;
using FeMM.Grasshopper.DataTypes.FeMM;
using FeMM.Grasshopper.Helpers;
using GH_IO.Serialization;
using Grasshopper.GUI;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Types;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.Versioning;
using System.Windows.Forms;

namespace FeMM.Grasshopper.Components.Parameters
{
#if NETCOREAPP
    [SupportedOSPlatform("windows")]
#endif
    public class BeamSectionParamV2 : GH_PersistentParam<GH_BeamSection>
    {
        private ModelModel.ModelUnits _units;

        private bool CanMirror
        {
            get
            {
                if (PersistentData.DataCount > 0)
                {
                    GH_BeamSection bs = PersistentData.Branches[0][0];
                    return bs.SectionType == SectionModel.SectionTypes.C || bs.SectionType == SectionModel.SectionTypes.Angle;
                }
                return false;
            }
        }

        private bool IsMirror
        {
            get
            {
                if (PersistentData.DataCount > 0)
                {
                    GH_BeamSection bs = PersistentData.Branches[0][0];
                    return bs.MirrorType != SectionModel.MirrorTypes.None;
                }
                return false;
            }
        }

        public BeamSectionParamV2()
            : base("SectionV2", "S2", "Section for Database 2.0", CategoryNameConstants.CATEGORY_FEMM, CategoryNameConstants.SUBCATEGORY_PARAMETERS)
        {
            _units = ModelModel.ModelUnits.Nmm;
        }

        protected override GH_GetterResult Prompt_Singular(ref GH_BeamSection value)
        {
            var profile = AppsClientUI.AppsClientUI.SelectOneProfile(null);
            if (profile != null)
            {
                value = new GH_BeamSection(NamingConventionHelper.ConvertProfileToSection(profile));
                return GH_GetterResult.success;
            }
            return GH_GetterResult.cancel;
        }

        protected override GH_GetterResult Prompt_Plural(ref List<GH_BeamSection> values)
        {
            return GH_GetterResult.cancel;
        }

        public override bool AppendMenuItems(ToolStripDropDown menu)
        {
            Menu_AppendObjectNameEx(menu);
            Menu_AppendWireDisplay(menu);
            Menu_AppendDisconnectWires(menu);

            // Section menu
            Menu_AppendSeparator(menu);
            Menu_AppendPromptOne(menu);

            // Mirror
            Menu_AppendSeparator(menu);
            Menu_AppendItem(menu, "Set Mirror", new EventHandler(OnSetMirror), CanMirror, IsMirror);
            string gap_text = "Gap";
            if (PersistentData.DataCount > 0)
            {
                GH_BeamSection bs = PersistentData.Branches[0][0];
                if (bs.MirrorGapA > 0)
                    gap_text = bs.MirrorGapA.ToString();
            }
            Menu_AppendTextItem(menu, gap_text, new GH_MenuTextBox.KeyDownEventHandler(OnGapKeyDown), null, IsMirror, 0, true);

            // Units menu
            Menu_AppendSeparator(menu);
            foreach (object en in Enum.GetValues(typeof(ModelModel.ModelUnits)))
            {
                ModelModel.ModelUnits value;
                value = (ModelModel.ModelUnits)en;

                Menu_AppendItem(menu, Enum.GetName(typeof(ModelModel.ModelUnits), en), OnUnitsClick,
                    PersistentDataCount > 0 || VolatileDataCount > 0, value == _units ? true : false);
            }

            Menu_AppendSeparator(menu);
            Menu_AppendDestroyPersistent(menu);
            Menu_AppendInternaliseData(menu);
            return true;
        }

        private void OnSetMirror(object sender, EventArgs e)
        {
            if (PersistentData.DataCount > 0)
            {
                GH_BeamSection bs = PersistentData.Branches[0][0];
                if (bs.MirrorType == SectionModel.MirrorTypes.None)
                    bs.MirrorType = SectionModel.MirrorTypes.Left;
                else
                    bs.MirrorType = SectionModel.MirrorTypes.None;
                ExpireSolution(true);
            }
        }

        private void OnGapKeyDown(GH_MenuTextBox textBox, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                GH_BeamSection bs = PersistentData.Branches[0][0];
                if (double.TryParse(textBox.Text, out double gap))
                {
                    bs.MirrorGapA = gap;
                    bs.IsDBSection = false;
                    ExpireSolution(true);
                }
            }
        }

        private void OnUnitsClick(object sender, EventArgs e)
        {
            if (Enum.TryParse(((ToolStripMenuItem)sender).Text, out ModelModel.ModelUnits value))
            {
                ModelModel.ModelUnits prevUnits = _units;
                //GH_BeamSection bs;

                _units = value;

                foreach (GH_BeamSection bs in PersistentData.AllData(true))
                    bs.ConvertUnits(prevUnits, _units);

                ExpireSolution(true);
            }
        }

        protected override GH_BeamSection PreferredCast(object data)
        {
            if (data is GH_String str)
            {
                try
                {
                    DBProfile profile;
                    var result = Profiles.GetProfilesByName(str.Value);
                    if (result == null || result.Count == 0)
                        profile = Profiles.GetProfileByMaffeisName(str.Value);
                    else
                        profile = result[0];

                    if (profile == null || (profile.Custom == false && profile.Name == ""))
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid name");
                    else
                    {
                        if (profile.Tapered)
                            AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Tapered property not applicable to 2D section. The nomenclature used to define the section has a tapered property associated. The section itself can't contain this property, therefore the solid produced by this section won't be tapered.");
                        return new GH_BeamSection(NamingConventionHelper.ConvertProfileToSection(profile));
                    }
                }
                catch (Exception ex)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, ex.Message);
                }
            }
            return base.PreferredCast(data);
        }

        public override bool Write(GH_IWriter writer)
        {
            bool success = base.Write(writer);
            if (!success)
                return false;
            writer.SetInt32("Units", Convert.ToInt32(_units));
            return true;
        }

        public override bool Read(GH_IReader reader)
        {
            bool success = base.Read(reader);
            if (!success)
                return false;

            int units = -1;
            if (reader.TryGetInt32("Units", ref units))
            {
                _units = (ModelModel.ModelUnits)Enum.Parse(typeof(ModelModel.ModelUnits), units.ToString());
            }
            else
            {
                return false;
            }
            return true;
        }

        public override GH_Exposure Exposure => GH_Exposure.secondary;

        protected override Bitmap Icon => Properties.Resources.BeamSectionParamV2Icon;

        public override Guid ComponentGuid => new("bfdc814e-5d0f-4ba0-86e4-c3c8cf48850c");
    }
}
303 files24 directories