Editor/FXParticlePropertyControlWidget.cs
using Editor;
using Sandbox;
using System.Collections.Generic;
using System.Linq;
using fxbox;
using fxbox.Graph;

namespace Editor;

/// <summary>
/// Custom control for parameter name selection with dropdown
/// </summary>
public class ParameterNameControlWidget : ControlWidget
{
    private SerializedProperty _property;
    private ComboBox _dropdown;
    private List<FloatParameter> _availableParameters;

    public ParameterNameControlWidget(SerializedProperty property) : base(property)
    {
        _property = property;
        
        SetSizeMode(SizeMode.Ignore, SizeMode.Default);

        Layout = Layout.Row();
        Layout.Spacing = 3;

        // Get available parameters from the currently editing resource
        _availableParameters = FXBoxEditor.CurrentEditingResource?.FloatParameters ?? new List<FloatParameter>();

        _dropdown = new ComboBox(this);
        _dropdown.MinimumWidth = 150;
        
        PopulateDropdown();
        
        // Set current value
        var currentValue = property.GetValue<string>();
        if (!string.IsNullOrEmpty(currentValue))
        {
            SelectParameter(currentValue);
        }

        _dropdown.ItemChanged += OnValueChanged;
        //_dropdown.On += OnValueChanged;

        Layout.Add(_dropdown, 1);
    }

    private void PopulateDropdown()
    {
        _dropdown.Clear();
        
        if (_availableParameters == null || _availableParameters.Count == 0)
        {
            _dropdown.AddItem("(No Parameters Available)");
            _dropdown.Enabled = false;
            return;
        }

        _dropdown.AddItem("(None)");
        
        foreach (var param in _availableParameters.OrderBy(p => p.Name))
        {
            _dropdown.AddItem($"{param.Name} (default: {param.DefaultValue})");
        }
        
        _dropdown.Enabled = true;
    }

    private void SelectParameter(string parameterName)
    {
        if (string.IsNullOrEmpty(parameterName))
        {
            _dropdown.CurrentIndex = 0;
            return;
        }

        // Find the index by matching parameter name
        var orderedParams = _availableParameters.OrderBy(p => p.Name).ToList();
        for (int i = 0; i < orderedParams.Count; i++)
        {
            if (orderedParams[i].Name == parameterName)
            {
                _dropdown.CurrentIndex = i + 1; // +1 because of "(None)" at index 0
                return;
            }
        }
    }

    private new void OnValueChanged()
    {
        var selectedIndex = _dropdown.CurrentIndex;
        
        if (selectedIndex <= 0)
        {
            // "(None)" selected
            _property.SetValue("");
            return;
        }
        
        // Get the parameter name from the selected item
        var orderedParams = _availableParameters.OrderBy(p => p.Name).ToList();
        if (selectedIndex - 1 < orderedParams.Count)
        {
            var selectedParam = orderedParams[selectedIndex - 1];
            _property.SetValue(selectedParam.Name);
        }
    }

    protected override void OnPaint()
    {
        // No custom painting
    }
}

public class VectorParameterNameControlWidget : ControlWidget
{
    private SerializedProperty _property;
    private ComboBox _dropdown;
    private List<VectorParameter> _availableParameters;

    public VectorParameterNameControlWidget(SerializedProperty property) : base(property)
    {
        _property = property;
        
        SetSizeMode(SizeMode.Ignore, SizeMode.Default);

        Layout = Layout.Row();
        Layout.Spacing = 3;

        _availableParameters = FXBoxEditor.CurrentEditingResource?.VectorParameters ?? new List<VectorParameter>();

        _dropdown = new ComboBox(this);
        _dropdown.MinimumWidth = 150;
        
        PopulateDropdown();
        
        var currentValue = property.GetValue<string>();
        if (!string.IsNullOrEmpty(currentValue))
        {
            SelectParameter(currentValue);
        }

        _dropdown.ItemChanged += OnValueChanged;

        Layout.Add(_dropdown, 1);
    }

    private void PopulateDropdown()
    {
        _dropdown.Clear();
        
        if (_availableParameters == null || _availableParameters.Count == 0)
        {
            _dropdown.AddItem("(No Vector Parameters Available)");
            _dropdown.Enabled = false;
            return;
        }

        _dropdown.AddItem("(None)");
        
        foreach (var param in _availableParameters.OrderBy(p => p.Name))
        {
            _dropdown.AddItem($"{param.Name} (default: {param.DefaultValue})");
        }
        
        _dropdown.Enabled = true;
    }

    private void SelectParameter(string parameterName)
    {
        if (string.IsNullOrEmpty(parameterName))
        {
            _dropdown.CurrentIndex = 0;
            return;
        }

        var orderedParams = _availableParameters.OrderBy(p => p.Name).ToList();
        for (int i = 0; i < orderedParams.Count; i++)
        {
            if (orderedParams[i].Name == parameterName)
            {
                _dropdown.CurrentIndex = i + 1;
                return;
            }
        }
    }

    private new void OnValueChanged()
    {
        var selectedIndex = _dropdown.CurrentIndex;
        
        if (selectedIndex <= 0)
        {
            _property.SetValue("");
            return;
        }
        
        var orderedParams = _availableParameters.OrderBy(p => p.Name).ToList();
        if (selectedIndex - 1 < orderedParams.Count)
        {
            var selectedParam = orderedParams[selectedIndex - 1];
            _property.SetValue(selectedParam.Name);
        }
    }

    protected override void OnPaint()
    {
    }
}

public class ColorParameterNameControlWidget : ControlWidget
{
    private SerializedProperty _property;
    private ComboBox _dropdown;
    private List<ColorParameter> _availableParameters;

    public ColorParameterNameControlWidget(SerializedProperty property) : base(property)
    {
        _property = property;
        
        SetSizeMode(SizeMode.Ignore, SizeMode.Default);

        Layout = Layout.Row();
        Layout.Spacing = 3;

        _availableParameters = FXBoxEditor.CurrentEditingResource?.ColorParameters ?? new List<ColorParameter>();

        _dropdown = new ComboBox(this);
        _dropdown.MinimumWidth = 150;
        
        PopulateDropdown();
        
        var currentValue = property.GetValue<string>();
        if (!string.IsNullOrEmpty(currentValue))
        {
            SelectParameter(currentValue);
        }

        _dropdown.ItemChanged += OnValueChanged;

        Layout.Add(_dropdown, 1);
    }

    private void PopulateDropdown()
    {
        _dropdown.Clear();
        
        if (_availableParameters == null || _availableParameters.Count == 0)
        {
            _dropdown.AddItem("(No Color Parameters Available)");
            _dropdown.Enabled = false;
            return;
        }

        _dropdown.AddItem("(None)");
        
        foreach (var param in _availableParameters.OrderBy(p => p.Name))
        {
            _dropdown.AddItem($"{param.Name}");
        }
        
        _dropdown.Enabled = true;
    }

    private void SelectParameter(string parameterName)
    {
        if (string.IsNullOrEmpty(parameterName))
        {
            _dropdown.CurrentIndex = 0;
            return;
        }

        var orderedParams = _availableParameters.OrderBy(p => p.Name).ToList();
        for (int i = 0; i < orderedParams.Count; i++)
        {
            if (orderedParams[i].Name == parameterName)
            {
                _dropdown.CurrentIndex = i + 1;
                return;
            }
        }
    }

    private new void OnValueChanged()
    {
        var selectedIndex = _dropdown.CurrentIndex;
        
        if (selectedIndex <= 0)
        {
            _property.SetValue("");
            return;
        }
        
        var orderedParams = _availableParameters.OrderBy(p => p.Name).ToList();
        if (selectedIndex - 1 < orderedParams.Count)
        {
            var selectedParam = orderedParams[selectedIndex - 1];
            _property.SetValue(selectedParam.Name);
        }
    }

    protected override void OnPaint()
    {
    }
}