/// @addtogroup item Item
/// @brief Functions exposing additional item properties.
/// @{
/// @file nwnx_item.nss

const string NWNX_Item = "NWNX_Item"; ///< @private

/// @brief Set an item's weight.
/// @note Will not persist through saving.
/// @param oItem The item object.
/// @param weight The weight, note this is in tenths of pounds.
void NWNX_Item_SetWeight(object oItem, int weight);

/// @brief Set an item's base value in gold pieces.
/// @remark Total cost = base_value + additional_value.
/// @remark Equivalent to SetGoldPieceValue NWNX2 function.
/// @note Will not persist through saving.
/// @note This value will also revert if item is identified or player relogs into server.
/// @param oItem The item object.
/// @param gold The base gold value.
void NWNX_Item_SetBaseGoldPieceValue(object oItem, int gold);

/// @brief Set an item's additional value in gold pieces.
/// @remark Total cost = base_value + additional_value.
/// @note Will persist through saving.
/// @param oItem The item object.
/// @param gold The additional gold value.
void NWNX_Item_SetAddGoldPieceValue(object oItem, int gold);

/// @brief Get an item's base value in gold pieces.
/// @param oItem The item object.
/// @return The base gold piece value for the item.
int NWNX_Item_GetBaseGoldPieceValue(object oItem);

/// @brief Get an item's additional value in gold pieces.
/// @param oItem The item object.
/// @return The additional gold piece value for the item.
int NWNX_Item_GetAddGoldPieceValue(object oItem);

/// @brief Set an item's base item type.
/// @warning This will not be visible until the item is refreshed (e.g. drop and take the item,
/// or logging out and back in).
/// @param oItem The item object.
/// @param nBaseItem The new base item.
void NWNX_Item_SetBaseItemType(object oItem, int nBaseItem);

/// @brief Make a single change to the appearance of an item.
/// @warning This will not be visible to PCs until the item is refreshed for them (e.g. by logging out and back in).
///
/// Helmet models and simple items ignore nIndex.
/// ```
/// nType                            nIndex                              nValue
/// ITEM_APPR_TYPE_SIMPLE_MODEL      [Ignored]                           Model #
/// ITEM_APPR_TYPE_WEAPON_COLOR      ITEM_APPR_WEAPON_COLOR_*            0-255
/// ITEM_APPR_TYPE_WEAPON_MODEL      ITEM_APPR_WEAPON_MODEL_*            Model #
/// ITEM_APPR_TYPE_ARMOR_MODEL       ITEM_APPR_ARMOR_MODEL_*             Model #
/// ITEM_APPR_TYPE_ARMOR_COLOR       ITEM_APPR_ARMOR_COLOR_* [0]         0-255 [1]
/// ```
///
/// [0] Where ITEM_APPR_TYPE_ARMOR_COLOR is specified, if per-part coloring is
/// desired, the following equation can be used for nIndex to achieve that:
///
/// ITEM_APPR_ARMOR_NUM_COLORS + (ITEM_APPR_ARMOR_MODEL_ * ITEM_APPR_ARMOR_NUM_COLORS) + ITEM_APPR_ARMOR_COLOR_
///
/// For example, to change the CLOTH1 channel of the torso, nIndex would be:
///
///     6 + (7 * 6) + 2 = 50
///
/// [1] When specifying per-part coloring, the value 255 corresponds with the logical
/// function 'clear colour override', which clears the per-part override for that part.
/// @param oItem The item
/// @param nType The type
/// @param nIndex The index
/// @param nValue The value
/// @param bUpdateCreatureAppearance If TRUE, also update the appearance of oItem's possessor. Only works for armor/helmets/cloaks. Will remove the item from the quickbar as side effect.
void NWNX_Item_SetItemAppearance(object oItem, int nType, int nIndex, int nValue, int bUpdateCreatureAppearance = FALSE);

/// @brief Return a string containing the entire appearance for an item.
/// @sa NWNX_Item_RestoreItemAppearance
/// @param oItem The item object.
/// @return A string representing the item's appearance.
string NWNX_Item_GetEntireItemAppearance(object oItem);

/// @brief Restores an item's appearance using the value retrieved through NWNX_Item_GetEntireItemAppearance().
/// @param oItem The item object.
/// @param sApp A string representing the item's appearance.
void NWNX_Item_RestoreItemAppearance(object oItem, string sApp);

/// @brief Get an item's base armor class
/// @param oItem The item object.
/// @return The base armor class.
int NWNX_Item_GetBaseArmorClass(object oItem);

/// @brief Get an item's minimum level required to equip.
/// @param oItem The item object.
/// @return The minimum level required to equip the item.
int NWNX_Item_GetMinEquipLevel(object oItem);

/// @brief Move oItem to oTarget
/// @remark Moving items from a container to the inventory of the container's owner (or the other way around) is always "silent" and won't trigger feedback messages
/// @param oItem The item object.
/// @param oTarget The target bag/creature/placeable or store object to move oItem to.
/// @param bHideAllFeedback Hides all feedback messages generated by losing/acquiring items
/// @return TRUE if the item was successfully moved to the target, otherwise FALSE
int NWNX_Item_MoveTo(object oItem, object oTarget, int bHideAllFeedback = FALSE);

/// @brief Set a modifier to the Minimum Level to Equip (Item Level Restriction).
/// @param oItem The item object.
/// @param nModifier the modifier to apply (After any Override)
/// @param bPersist Whether the modifier should persist to gff field. Strongly Recommended to be TRUE (See warning)
/// @note This function (or override partner) must be used each server reset to reenable persistence. Recommended use on OBJECT_INVALID OnModuleLoad.
/// @warning if Persistence is FALSE, or not renabled, beware characters may trigger ELC logging in with now-invalid ItemLevelRestrictions equipped.
void NWNX_Item_SetMinEquipLevelModifier(object oItem, int nModifier, int bPersist = TRUE);

/// @brief Gets the applied modifier to the Minimum Level to Equip (Item Level Restriction).
/// @param oItem The item object.
int NWNX_Item_GetMinEquipLevelModifier(object oItem);

/// @brief Set an override to the Minimum Level to Equip (Item Level Restriction).
/// @param oItem The item object.
/// @param nOverride the nOverride to apply (Before any Modifier)
/// @param bPersist Whether the modifier should persist to gff field. Strongly Recommended to be TRUE (See warning)
/// @note This function (or modifier partner) must be used each server reset to reenable persistence. Recommended use on OBJECT_INVALID OnModuleLoad.
/// @warning if Persistence is FALSE, or not renabled, beware characters may trigger ELC logging in with now-invalid ItemLevelRestrictions equipped.
void NWNX_Item_SetMinEquipLevelOverride(object oItem, int nOverride, int bPersist = TRUE);

/// @brief Gets the applied override to the Minimum Level to Equip (Item Level Restriction).
/// @param oItem The item object.
int NWNX_Item_GetMinEquipLevelOverride(object oItem);


/// @}

void NWNX_Item_SetWeight(object oItem, int w)
{
    NWNXPushInt(w);
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "SetWeight");
}

void NWNX_Item_SetBaseGoldPieceValue(object oItem, int g)
{
    NWNXPushInt(g);
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "SetBaseGoldPieceValue");
}

void NWNX_Item_SetAddGoldPieceValue(object oItem, int g)
{
    NWNXPushInt(g);
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "SetAddGoldPieceValue");
}

int NWNX_Item_GetBaseGoldPieceValue(object oItem)
{
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "GetBaseGoldPieceValue");
    return NWNXPopInt();
}

int NWNX_Item_GetAddGoldPieceValue(object oItem)
{
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "GetAddGoldPieceValue");
    return NWNXPopInt();
}

void NWNX_Item_SetBaseItemType(object oItem, int nBaseItem)
{
    NWNXPushInt(nBaseItem);
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "SetBaseItemType");
}

void NWNX_Item_SetItemAppearance(object oItem, int nType, int nIndex, int nValue, int bUpdateCreatureAppearance = FALSE)
{
    NWNXPushInt(bUpdateCreatureAppearance);
    NWNXPushInt(nValue);
    NWNXPushInt(nIndex);
    NWNXPushInt(nType);
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "SetItemAppearance");
}

string NWNX_Item_GetEntireItemAppearance(object oItem)
{
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "GetEntireItemAppearance");
    return NWNXPopString();
}

void NWNX_Item_RestoreItemAppearance(object oItem, string sApp)
{
    NWNXPushString(sApp);
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "RestoreItemAppearance");
}

int NWNX_Item_GetBaseArmorClass(object oItem)
{
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "GetBaseArmorClass");
    return NWNXPopInt();
}

int NWNX_Item_GetMinEquipLevel(object oItem)
{
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "GetMinEquipLevel");
    return NWNXPopInt();
}

int NWNX_Item_MoveTo(object oItem, object oTarget, int bHideAllFeedback = FALSE)
{
    NWNXPushInt(bHideAllFeedback);
    NWNXPushObject(oTarget);
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "MoveTo");
    return NWNXPopInt();
}

void NWNX_Item_SetMinEquipLevelModifier(object oItem, int nModifier, int bPersist = TRUE)
{
    NWNXPushInt(bPersist);
    NWNXPushInt(nModifier);
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "SetMinEquipLevelModifier");
}

int NWNX_Item_GetMinEquipLevelModifier(object oItem)
{
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "GetMinEquipLevelModifier");
    return NWNXPopInt();
}

void NWNX_Item_SetMinEquipLevelOverride(object oItem, int nOverride, int bPersist = TRUE)
{

    NWNXPushInt(bPersist);
    NWNXPushInt(nOverride);
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "SetMinEquipLevelOverride");
}

int NWNX_Item_GetMinEquipLevelOverride(object oItem)
{
    NWNXPushObject(oItem);
    NWNXCall(NWNX_Item, "GetMinEquipLevelOverride");
    return NWNXPopInt();
}