using FeMM.Common.Models;
using FeMM.Grasshopper.DataTypes.FeMM;
using FeMM.Grasshopper.Helpers;
using GH_IO.Serialization;
using Grasshopper.GUI;
using Grasshopper.Kernel;
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Text.Json;

namespace FeMM.Grasshopper.Components.Design
{
#if NETCOREAPP
    [SupportedOSPlatform("windows")]
#endif
    public abstract class BeamDesignOverrideComponent : GH_Component
    {
        private object _data;

        /// <summary>
        /// Initializes a new instance of the MixedSectionComponent class.
        /// </summary>
        public BeamDesignOverrideComponent(string name, string nickname, string description)
          : base(name, nickname, description, CategoryNameConstants.CATEGORY_FEMM, CategoryNameConstants.SUBCATEGORY_DESIGN)
        {
            _data = null;
        }

        public override void CreateAttributes()
        {
            var attr = new ComponentAttributes.ComponentOneButtonAttributes(this, "Set overrides");
            attr.ButtonPressed += () =>
            {
                System.Windows.Forms.Form form = GetForm(_data);
                GH_WindowsFormUtil.CenterFormOnCursor(form, true);
                if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    _data = GetData(form);
                    ExpireSolution(true);
                }
            };
            m_attributes = attr;
        }

        protected abstract System.Windows.Forms.Form GetForm(object data);

        protected abstract object GetData(System.Windows.Forms.Form form);

        /// <summary>
        /// Registers all the input parameters for this component.
        /// </summary>
        protected override void RegisterInputParams(GH_InputParamManager pManager)
        {
            pManager.AddGenericParameter("Beam", "B", "The beam where apply the overload", GH_ParamAccess.item);
        }

        /// <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 overload", 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;
            if (!DA.GetData(0, ref beam)) return;
            if (_data == null)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Define the overrides");
                DA.AbortComponentSolution();
                return;
            }

            var beamWithOverride = new GH_Beam(beam);
            beamWithOverride.Value.Attributes.Add(GetOverrideAttribute(_data));
            DA.SetData(0, beamWithOverride);
        }

        protected abstract AttributeModel GetOverrideAttribute(object data);

        public override GH_Exposure Exposure => GH_Exposure.primary;

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

        ///// <summary>
        ///// Gets the unique ID for this component. Do not change this ID after release.
        ///// </summary>
        //public override Guid ComponentGuid => new Guid("95D5CE5A-B259-4A87-8D5E-BFC681832F6E");

        public override bool Write(GH_IWriter writer)
        {
            if (base.Write(writer))
            {
                bool hasData = _data != null;
                writer.SetBoolean("hasData", hasData);
                if (hasData)
                {
                    writer.SetBoolean("JsonSerializer", true);
                    byte[] data = JsonSerializer.SerializeToUtf8Bytes(_data);
                    writer.SetByteArray("Data", data);
                }
                return true;
            }
            return false;
        }

        public override bool Read(GH_IReader reader)
        {
            if (base.Read(reader))
            {
                bool hasData = reader.GetBoolean("hasData");

                if (hasData)
                {
                    byte[] buffer = reader.GetByteArray("Data");
                    bool isJson = false;
                    bool succes = reader.TryGetBoolean("JsonSerializer", ref isJson);
                    if (succes && isJson)
                    {
                        var jsonReader = new Utf8JsonReader(new ReadOnlySpan<byte>(buffer));
                        _data = JsonSerializer.Deserialize<object>(ref jsonReader);
                    }
                    else
                    {
                        using (var ms = new MemoryStream(buffer))
                        {
                            var bf = new BinaryFormatter();
                            _data = bf.Deserialize(ms);
                        }
                    }
                }
                return true;
            }
            return false;
        }

    }
}
303 files24 directories