// Copyright © Gamesmiths Guild.
#if TOOLS
using System;
using Gamesmiths.Forge.Godot.Resources.Statescript;
using Godot;
namespace Gamesmiths.Forge.Godot.Editor.Statescript;
///
/// Base class for all Statescript property resolver editor controls. Extends so it can be
/// added directly to the graph node UI and participates in the Godot scene tree (lifecycle, disposal, etc.).
///
[Tool]
internal abstract partial class NodeEditorProperty : PanelContainer
{
private Type[] _allowedExpectedTypes = [];
///
/// Gets the display name shown in the resolver type dropdown (e.g., "Variable", "Constant", "Attribute").
///
public abstract string DisplayName { get; }
///
/// Gets the resolver type identifier string used for matching against serialized resources.
///
public abstract string ResolverTypeId { get; }
///
/// Checks whether this resolver is compatible with the given expected type.
///
/// The type expected by the node's input property.
/// if this resolver can provide a value of the expected type.
public abstract bool IsCompatibleWith(Type expectedType);
///
/// Initializes the resolver editor UI. Called once after the control is created.
///
/// The current graph resource (for accessing variables, etc.).
/// The existing property binding to restore state from, or null for a new binding.
/// The type expected by the node's input property.
/// Callback invoked when the resolver configuration changes.
/// Whether the input expects an array of values.
public abstract void Setup(
StatescriptGraph graph,
StatescriptNodeProperty? property,
Type expectedType,
Action onChanged,
bool isArray);
///
/// Writes the current resolver configuration to the given property binding resource.
///
/// The property binding to write to.
public abstract void SaveTo(StatescriptNodeProperty property);
///
/// Raised when the editor's layout size has changed (e.g. nested resolver swap, foldable toggle) so that the owning
/// can call .
///
public event Action? LayoutSizeChanged;
///
/// Configures the concrete input types allowed for this editor when the surrounding context accepts more than one.
///
/// The allowed expected types.
public void ConfigureAllowedExpectedTypes(params Type[] allowedExpectedTypes)
{
_allowedExpectedTypes = allowedExpectedTypes;
}
///
/// Tries to provide a short inline summary for the current editor state when embedded in a collapsed foldout.
///
/// The inline summary, when available.
/// when an inline summary is available.
public virtual bool TryGetInlineSummary(out string summary)
{
summary = string.Empty;
return false;
}
///
/// Gets the preferred badge style for inline foldout summaries.
///
public virtual InlineSummaryBadgeKind GetInlineSummaryBadgeKind()
{
return InlineSummaryBadgeKind.Resolver;
}
///
/// Tries to provide the graph-variable name represented by this editor or one of its nested editors for highlight
/// propagation in folded summaries.
///
/// The variable name, when available.
public virtual bool TryGetHighlightedVariableName(out string variableName)
{
variableName = string.Empty;
return false;
}
///
/// Tries to provide the shared-variable identity represented by this editor or one of its nested editors for
/// highlight propagation in folded summaries.
///
/// The shared-variable set path, when available.
/// The shared variable name, when available.
public virtual bool TryGetHighlightedSharedVariable(out string sharedVariableSetPath, out string variableName)
{
sharedVariableSetPath = string.Empty;
variableName = string.Empty;
return false;
}
///
/// Clears all delegate fields to prevent serialization issues during hot-reload. Called before the editor is
/// serialized or freed.
///
public virtual void ClearCallbacks()
{
LayoutSizeChanged = null;
}
///
/// Notifies listeners that the editor layout has changed size.
///
protected void RaiseLayoutSizeChanged()
{
LayoutSizeChanged?.Invoke();
}
protected Type[] GetAllowedExpectedTypes(Type fallbackExpectedType)
{
return _allowedExpectedTypes.Length > 0 ? _allowedExpectedTypes : [fallbackExpectedType];
}
}
#endif