#ifndef EDITSCENE_CHARACTER_HPP
#define EDITSCENE_CHARACTER_HPP
#pragma once

#include <Ogre.h>
#include <Jolt/Jolt.h>
#include <Jolt/Physics/Body/BodyID.h>

/**
 * Character physics component
 *
 * Attaches a Jolt JPH::Character (kinematic capsule) to the entity.
 * The entity may also have CharacterSlotsComponent; the character
 * physics lives on the same entity as the visual character.
 *
 * Child entities can add extra collision shapes via PhysicsColliderComponent.
 */
struct CharacterComponent {
	/* Capsule dimensions */
	float radius = 0.3f;
	float height = 1.8f; /* cylinder height (excluding spherical caps) */

	/* Offset from the entity's scene node */
	Ogre::Vector3 offset = Ogre::Vector3::ZERO;

	/* Current linear velocity (m/s), applied each frame by CharacterSystem */
	Ogre::Vector3 linearVelocity = Ogre::Vector3::ZERO;

	/* Enable/disable physics character */
	bool enabled = true;

	/* Physics was explicitly disabled (e.g. by behavior tree node).
	 * When true, the character's JPH::BodyID is removed from the physics
	 * system but the JPH::Character object is kept alive so it can be
	 * re-added later. This is separate from 'enabled' which controls
	 * whether the character system processes this entity at all. */
	bool physicsDisabled = false;

	/* Dirty flag — triggers rebuild of the Jolt character */
	bool dirty = true;

	/* When true, the scene node position is driven by root motion
	 * (AnimationTreeSystem), not by physics. The physics character
	 * position is synced to match the scene node each frame, and
	 * physics does NOT write its position back to the scene node. */
	bool useRootMotion = false;

	/* Floor detection: raycast downward to find ground before enabling gravity */
	bool hasFloor = false;
	float floorCheckDistance = 2.0f;
	bool useGravity = true;

	/* Per-character collision group. Body = subgroup 0, head = subgroup 1,
	 * hair joints = 2+. Runtime only — regenerated when character is rebuilt. */
	uint32_t collisionGroupId = 0;

	/* Separate head collider body for hair physics. Runtime only. */
	JPH::BodyID headColliderBody;

	/* Head sphere radius for hair physics collision. */
	float headRadius = 0.13f;

	/* Vertical offset from the character base to the head sphere centre.
	 * If zero, defaults to getTotalHeight() - headRadius. */
	float headOffsetY = 0.0f;

	/* Bone that drives the head collider. If empty, falls back to the
	 * static offset above. */
	Ogre::String headBoneName = "mixamorig:Head";

	/* Optional chest/upper-body collider to stop long hair from clipping
	 * through the torso. Runtime only. */
	JPH::BodyID chestColliderBody;

	/* Chest box half-extents. If any axis is zero, no chest collider is
	 * created. */
	Ogre::Vector3 chestHalfExtents = Ogre::Vector3(0.2f, 0.12f, 0.12f);

	/* Vertical offset along the world Y axis applied to the chest bone
	 * position when placing the chest collider. */
	float chestOffsetY = 0.0f;

	/* Bone that drives the chest collider. */
	Ogre::String chestBoneName = "mixamorig:Spine2";

	float getHalfHeight() const
	{
		return height * 0.5f;
	}
	float getTotalHeight() const
	{
		return height + 2.0f * radius;
	}
};

#endif // EDITSCENE_CHARACTER_HPP
