#nullable enable
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Content.Server.Body;
using Content.Shared.GameObjects.Components.Body;
using Robust.Shared.Interfaces.GameObjects;
namespace Content.Server.GameObjects.Components.Body
{
public interface IBodyPartManager : IComponent
{
///
/// The that this
///
/// is adhering to.
///
public BodyPreset Preset { get; }
///
/// Installs the given into the
/// given slot, deleting the afterwards.
///
/// True if successful, false otherwise.
bool TryAddPart(string slot, DroppedBodyPartComponent part, bool force = false);
bool TryAddPart(string slot, IBodyPart part, bool force = false);
bool HasPart(string slot);
///
/// Removes the given reference, potentially
/// dropping other BodyParts if they
/// were hanging off of it.
///
void RemovePart(IBodyPart part, bool drop);
///
/// Removes the body part in slot from this body,
/// if one exists.
///
/// The slot to remove it from.
///
/// Whether or not to drop the removed .
///
/// True if the part was removed, false otherwise.
bool RemovePart(string slot, bool drop);
///
/// Removes the body part from this body, if one exists.
///
/// The part to remove from this body.
/// The slot that the part was in, if any.
/// True if was removed, false otherwise.
bool RemovePart(IBodyPart part, [NotNullWhen(true)] out string? slotName);
///
/// Disconnects the given reference, potentially
/// dropping other BodyParts if they were hanging
/// off of it.
///
///
/// The representing the dropped
/// , or null if none was dropped.
///
IEntity? DropPart(IBodyPart part);
///
/// Recursively searches for if is connected to
/// the center.
///
/// The body part to find the center for.
/// True if it is connected to the center, false otherwise.
bool ConnectedToCenter(IBodyPart part);
///
/// Finds the central , if any, of this body based on
/// the . For humans, this is the torso.
///
/// The if one exists, null otherwise.
IBodyPart? CenterPart();
///
/// Returns whether the given part slot name exists within the current
/// .
///
/// The slot to check for.
/// True if the slot exists in this body, false otherwise.
bool HasSlot(string slot);
///
/// Finds the in the given if
/// one exists.
///
/// The part slot to search in.
/// The body part in that slot, if any.
/// True if found, false otherwise.
bool TryGetPart(string slot, [NotNullWhen(true)] out IBodyPart? result);
///
/// Finds the slotName that the given resides in.
///
/// The to find the slot for.
/// The slot found, if any.
/// True if a slot was found, false otherwise
bool TryGetSlot(IBodyPart part, [NotNullWhen(true)] out string? slot);
///
/// Finds the in the given
/// if one exists.
///
/// The slot to search in.
///
/// The of that slot, if any.
///
/// True if found, false otherwise.
bool TryGetSlotType(string slot, out BodyPartType result);
///
/// Finds the names of all slots connected to the given
/// for the template.
///
/// The slot to search in.
/// The connections found, if any.
/// True if the connections are found, false otherwise.
bool TryGetSlotConnections(string slot, [NotNullWhen(true)] out List? connections);
///
/// Grabs all occupied slots connected to the given slot,
/// regardless of whether the given is occupied.
///
/// The slot name to find connections from.
/// The connected body parts, if any.
///
/// True if successful, false if the slot couldn't be found on this body.
///
bool TryGetPartConnections(string slot, [NotNullWhen(true)] out List? connections);
///
/// Grabs all parts connected to the given , regardless
/// of whether the given is occupied.
///
/// The part to find connections from.
/// The connected body parts, if any.
///
/// True if successful, false if the part couldn't be found on this body.
///
bool TryGetPartConnections(IBodyPart part, [NotNullWhen(true)] out List? connections);
///
/// Grabs all of the given type in this body.
///
List GetPartsOfType(BodyPartType type);
}
}