using System.Text.Json.Serialization;

namespace Sandbox.ModelEditor.Nodes;

/// <summary>
/// Defines a single breakable prop gib.
/// </summary>
// This type is automatically generated by ModelDoc, it does not exist in .fgd.
[ModelEditor.GameData( "break_list_piece", AllowMultiple = true ), Hide]
public struct ModelBreakPiece
{
	[JsonPropertyName( "piece_name" )]
	public string PieceName { get; set; }
	public string Model { get; set; }
	public Vector3 Offset { get; set; }
	public float FadeTime { get; set; }
	[JsonPropertyName( "random_spawn_chance" )]
	public float RandomSpawnChance { get; set; }
	[JsonPropertyName( "is_essential_piece" )]
	public bool IsEssential { get; set; }
	[JsonPropertyName( "collision_tags" )]
	public string CollisionTags { get; set; }
	public string PlacementBone { get; set; }
	public string PlacementAttachment { get; set; }
	[JsonPropertyName( "clientonly" )]
	public bool IsClientOnly { get; set; }
}

/// <summary>
/// Generic prop settings. Support for this depends on the entity.
/// </summary>
[ModelEditor.GameData( "prop_data" )]
public class ModelPropData
{
	/// <summary>
	/// When this model is used as prop_static, it will bake lighting by default depending on this value.
	/// </summary>
	[Title( "Bake Lighting As Static Prop" )]
	public bool BakeLighting { get; set; } = true;

	/// <summary>
	/// When this model is used as prop_physics, it's health will be set to this value.
	/// </summary>
	public float Health { get; set; } = -1;

	/// <summary>
	/// If true well treat this prop as flammable, meaning it can catch fire and burn.
	/// </summary>
	public bool Flammable { get; set; }

	/// <summary>
	/// If true we'll explode this prop when it's destroyed
	/// </summary>
	public bool Explosive { get; set; }

	/// <summary>
	/// Amount of damage to do at the center on the explosion. It will falloff over distance.
	/// </summary>
	[JsonPropertyName( "explosive_damage" )]
	public float ExplosionDamage { get; set; } = -1;

	/// <summary>
	/// Range of explosion's damage.
	/// </summary>
	[JsonPropertyName( "explosive_radius" )]
	public float ExplosionRadius { get; set; } = -1;

	/// <summary>
	/// Scale of the force applied to entities damaged by the explosion and the models break pieces.
	/// </summary>
	[JsonPropertyName( "explosive_force" ), Title( "Force Scale" )]
	public float ExplosionForce { get; set; } = -1;
}

/// <summary>
/// Defines an eye on a character model.
/// </summary>
[ModelEditor.GameData( "eye", AllowMultiple = true )]
public class ModelEye
{
	[FGDType( "model_bone" )]
	public string BoneName { get; set; }

	public float Radius { get; set; } = 1;

	[Title( "Yaw (Degrees)" )]
	public float Yaw { get; set; } = 4;
}

/// <summary>
/// Carries navigation related data.
/// </summary>
[ModelEditor.GameData( "nav_data" )]
public class ModelNavData
{
	/// <summary>
	/// During map compile this model would mark its volume as an area that should be avoided by AI.
	/// </summary>
	[JsonPropertyName( "nav_attribute_avoid" )]
	public bool Avoid { get; set; } = false;
}

[ModelEditor.GameData( "eye_occlusion_renderer" )]
[ModelEditor.Box( "dimensions", Bone = "bonename", Origin = "offset_origin", Angles = "offset_angles" )]
[ModelEditor.Axis( Bone = "bonename", Origin = "offset_origin", Angles = "offset_angles" )]
public class ModelEyeOcclusion
{
	[FGDType( "model_bone" )]
	public string BoneName { get; set; }

	[ModelEditor.ScaleBoneRelative, DefaultValue( "12 12 12" )]
	public Vector3 Dimensions { get; set; }

	[JsonPropertyName( "offset_origin" ), ModelEditor.ScaleBoneRelative]
	public Vector3 OriginOffset { get; set; }

	[JsonPropertyName( "offset_angles" )]
	public Angles Angles { get; set; }
}

[ModelEditor.GameData( "bodygroup_driven_morph", AllowMultiple = true )]
public class ModelBodygroupDrivenMorph
{
	[JsonPropertyName( "bodygroup_name" ), FGDType( "model_bodygroup" )]
	public string BodygroupName { get; set; }

	[JsonPropertyName( "bodygroup_choice" )]
	public int bodygroupChoice { get; set; }

	[JsonPropertyName( "morph_name" ), FGDType( "model_morphchannel" )]
	public string MorphChannel { get; set; }
}

[ModelEditor.GameData( "materialgroup_driven_morph", AllowMultiple = true )]
public class ModelMaterialGroupDrivenMorph
{
	[JsonPropertyName( "materialgroup_name" ), FGDType( "materialgroup" )]
	public string MaterialGroup { get; set; }

	[JsonPropertyName( "morph_name" ), FGDType( "model_morphchannel" )]
	public string MorphChannel { get; set; }
}
