using System.Text.Json.Serialization;
using Cthangover.Core.Factories;
using Cthangover.Core.UI.Theming;
using Godot;
namespace Cthangover.Core.Interactive
{
///
/// JSON-driven definition of an interactive scene object loaded from mods.
/// The texture is always full-screen (alpha determines visibility outside the collider).
/// The collider defines the clickable region in normalised 0..1 viewport coordinates.
/// Interactives keep their own resolver and {"Items": [...]} envelope;
/// unlike other entity kinds they are not part of the kind-routed pipeline.
///
public class InteractiveDefinition : IIdentifiable
{
/// Unique identifier used in scenario commands and registry lookups.
[JsonPropertyName("id")]
public string ID { get; set; }
/// Owning mod identifier set by ModManager during collection.
[JsonIgnore]
public string ModId { get; set; }
/// Texture key resolved via ModManager.ResolveTexture. Full-screen with alpha.
[JsonPropertyName("texture")]
public string Texture { get; set; }
/// Visual layer: "background", "foreground" or "ui". Defaults to "foreground".
[JsonPropertyName("layer")]
public string Layer { get; set; } = "foreground";
/// Z-index for ordering within the layer. Higher = on top.
[JsonPropertyName("zIndex")]
public int ZIndex { get; set; }
/// Whether the object is initially enabled (responds to input). Default true.
[JsonPropertyName("enabled")]
public bool Enabled { get; set; } = true;
/// Whether the object is initially visible. Default true.
[JsonPropertyName("visible")]
public bool Visible { get; set; } = true;
/// Mouse cursor override when hovering (Godot CursorShape enum name, e.g. "PointingHand").
[JsonPropertyName("cursor")]
public string Cursor { get; set; }
/// Collider shape and position in normalised viewport coordinates (0..1).
[JsonPropertyName("hitArea")]
public HitAreaDefinition HitArea { get; set; }
/// Visual highlight settings applied on hover.
[JsonPropertyName("highlight")]
public HighlightDefinition Highlight { get; set; }
/// Actions triggered by pointer events.
[JsonPropertyName("actions")]
public InteractiveActionDefinition Actions { get; set; }
}
///
/// Shape and position of the clickable collider in normalised viewport
/// coordinates (0..1), where (0,0) is the top-left corner and (1,1) is bottom-right.
///
public class HitAreaDefinition
{
/// "rect", "circle" or "polygon". Defaults to "rect".
[JsonPropertyName("type")]
public string Type { get; set; } = "rect";
/// X position of the collider origin (top-left for rect, centre for circle). Normalised 0..1.
[JsonPropertyName("x")]
public float X { get; set; }
/// Y position of the collider origin. Normalised 0..1.
[JsonPropertyName("y")]
public float Y { get; set; }
/// Width for rect type. Normalised 0..1.
[JsonPropertyName("width")]
public float Width { get; set; } = 0.1f;
/// Height for rect type. Normalised 0..1.
[JsonPropertyName("height")]
public float Height { get; set; } = 0.1f;
/// Radius for circle type. Normalised 0..1 (relative to viewport min dimension).
[JsonPropertyName("radius")]
public float Radius { get; set; } = 0.05f;
/// Polygon vertices as an array of normalised Vector2 points. Only for "polygon" type.
[JsonPropertyName("vertices")]
[JsonConverter(typeof(Vector2ArrayJsonConverter))]
public Vector2[] Vertices { get; set; }
}
///
/// Highlight effect applied when the pointer hovers over the collider.
/// Uses a shader-based colour modulation on the full-screen texture.
///
public class HighlightDefinition
{
/// Modulate colour as a hex string (e.g. "#FFFF0033"). Parsed to Godot.Color at runtime.
[JsonPropertyName("color")]
public string ColorHex { get; set; } = "#FFFF0033";
/// Pulse scale multiplier applied during hover (e.g. 1.02 = 2% bigger).
[JsonPropertyName("scale")]
public float Scale { get; set; } = 1.02f;
/// Duration in seconds of the hover/unhover animation.
[JsonPropertyName("duration")]
public float Duration { get; set; } = 0.15f;
/// Parsed Godot.Color from ColorHex. Computed at load time, not serialised.
[JsonIgnore]
public Color Color => ParseColor(ColorHex);
private static Color ParseColor(string hex)
{
if (string.IsNullOrEmpty(hex))
return UiTokens.Alpha(UiTokens.Accent, 0.3f);
try
{
return new Color(hex);
}
catch
{
return UiTokens.Alpha(UiTokens.Accent, 0.3f);
}
}
}
///
/// Actions dispatched on pointer events.
///
public class InteractiveActionDefinition
{
/// Action executed on left-click.
[JsonPropertyName("onClick")]
public ClickAction OnClick { get; set; }
/// Inline DSL commands executed on mouse enter.
[JsonPropertyName("onHoverEnter")]
public string OnHoverEnter { get; set; }
/// Inline DSL commands executed on mouse leave.
[JsonPropertyName("onHoverLeave")]
public string OnHoverLeave { get; set; }
}
///
/// Click action descriptor. Supports a referenced .scenario file
/// and/or inline DSL commands.
///
public class ClickAction
{
/// Path to a .scenario file within a mod.
[JsonPropertyName("scenario")]
public string Scenario { get; set; }
/// Inline DSL commands to execute (one command per array element).
[JsonPropertyName("commands")]
public string[] Commands { get; set; }
}
}