class UIInventoryItemRequirementsManager
{
	private var m_itemRequiredLevel : Int32;
	private var m_requiredStrength : Int32;
	private var m_requiredReflex : Int32;
	private var m_perkRequirementName : String;
	private var m_isSmartlinkRequirementMet : Bool;
	private var m_isLevelRequirementMet : Bool;
	private var m_isStrengthRequirementMet : Bool;
	private var m_isReflexRequirementMet : Bool;
	private var m_isPerkRequirementMet : Bool;
	private var m_isHumanityRequirementMet : Bool;
	private var m_isEquippable : Bool;
	private var m_isEquippableAdditionalValue : Bool;
	default m_isEquippableAdditionalValue = true;
	private var m_isEquippableFetched : Bool;
	private var m_equipRequirements : array< SItemStackRequirementData >;
	private var m_equipRequirementsFetched : Bool;
	private var m_player : weak< GameObject >;
	private var m_attachedItem : weak< UIInventoryItem >;

	public static function Make( inventoryItem : weak< UIInventoryItem >, player : weak< GameObject > ) : UIInventoryItemRequirementsManager
	{
		var instance : UIInventoryItemRequirementsManager;
		var itemData : gameItemData;
		var statsSystem : StatsSystem;
		instance = new UIInventoryItemRequirementsManager;
		instance.m_attachedItem = inventoryItem;
		instance.m_player = player;
		itemData = inventoryItem.GetItemData();
		statsSystem = GameInstance.GetStatsSystem( player.GetGame() );
		instance.m_itemRequiredLevel = ( ( Int32 )( itemData.GetStatValueByType( gamedataStatType.Level ) ) );
		instance.m_requiredStrength = ( ( Int32 )( itemData.GetStatValueByType( gamedataStatType.Strength ) ) );
		instance.m_requiredReflex = ( ( Int32 )( itemData.GetStatValueByType( gamedataStatType.Reflexes ) ) );
		instance.Update( statsSystem );
		return instance;
	}

	public function Update( optional statsSystem : StatsSystem )
	{
		var perkRequiredName : String;
		var itemData : gameItemData;
		itemData = m_attachedItem.GetItemData();
		if( statsSystem == NULL )
		{
			statsSystem = GameInstance.GetStatsSystem( m_player.GetGame() );
		}
		if( RPGManager.HasSmartLinkRequirement( itemData ) )
		{
			m_isSmartlinkRequirementMet = ( ( Bool )( statsSystem.GetStatValue( m_player.GetEntityID(), gamedataStatType.HasSmartLink ) ) );
		}
		else
		{
			m_isSmartlinkRequirementMet = true;
		}
		if( m_itemRequiredLevel > 0 )
		{
			m_isLevelRequirementMet = m_itemRequiredLevel <= ( ( Int32 )( statsSystem.GetStatValue( m_player.GetEntityID(), gamedataStatType.Level ) ) );
		}
		else
		{
			m_isLevelRequirementMet = true;
		}
		if( m_requiredStrength > 0 )
		{
			m_isStrengthRequirementMet = m_requiredStrength <= ( ( Int32 )( statsSystem.GetStatValue( m_player.GetEntityID(), gamedataStatType.Strength ) ) );
		}
		else
		{
			m_isStrengthRequirementMet = true;
		}
		if( m_requiredReflex > 0 )
		{
			m_isReflexRequirementMet = m_requiredReflex <= ( ( Int32 )( statsSystem.GetStatValue( m_player.GetEntityID(), gamedataStatType.Reflexes ) ) );
		}
		else
		{
			m_isReflexRequirementMet = true;
		}
		if( RPGManager.CheckPerkPrereqs( itemData, m_player, perkRequiredName ) )
		{
			m_isPerkRequirementMet = false;
			m_perkRequirementName = perkRequiredName;
		}
		else
		{
			m_isPerkRequirementMet = true;
		}
		if( m_attachedItem.IsCyberware() || m_attachedItem.IsCyberwareWeapon() )
		{
			if( CheckStatEquipRequirement( gamedataStatType.HumanityAvailable, m_player, statsSystem ) )
			{
				m_isHumanityRequirementMet = true;
			}
			else
			{
				m_isHumanityRequirementMet = false;
			}
		}
	}

	private function CheckStatEquipRequirement( statToCheck : gamedataStatType, player : weak< GameObject >, statsSystem : StatsSystem ) : Bool
	{
		var i, limit : Int32;
		FetchEquipRequirements();
		for( i = 0, limit = m_equipRequirements.Size(); i < limit; i += 1 )
		{
			if( m_equipRequirements[ i ].statType == statToCheck )
			{
				if( statsSystem.GetStatValue( player.GetEntityID(), statToCheck ) < m_equipRequirements[ i ].requiredValue )
				{
					return false;
				}
				break;
			}
		}
		return true;
	}

	public function IsSmartlinkRequirementMet() : Bool
	{
		return m_isSmartlinkRequirementMet;
	}

	public function IsLevelRequirementMet() : Bool
	{
		return m_isLevelRequirementMet;
	}

	public function IsStrengthRequirementMet() : Bool
	{
		return m_isStrengthRequirementMet;
	}

	public function IsReflexRequirementMet() : Bool
	{
		return m_isReflexRequirementMet;
	}

	public function IsPerkRequirementMet() : Bool
	{
		return m_isPerkRequirementMet;
	}

	public function IsHumanityRequirementMet() : Bool
	{
		var shouldIgnore : Bool;
		if( m_isEquippableFetched )
		{
			shouldIgnore = m_isEquippable;
		}
		return m_isHumanityRequirementMet || shouldIgnore;
	}

	public function IsRarityRequirementMet( parentItem : weak< UIInventoryItem > ) : Bool
	{
		if( m_attachedItem.IsPart() && parentItem.IsClothing() )
		{
			return parentItem.GetQualityInt() <= m_attachedItem.GetQualityInt();
		}
		return true;
	}

	public function IsAnyRequirementNotMet() : Bool
	{
		return !( IsSmartlinkRequirementMet() ) || IsAnyItemDisplayRequirementNotMet();
	}

	public function IsAnyItemDisplayRequirementNotMet() : Bool
	{
		var isNotEquippable : Bool;
		if( !( m_attachedItem.IsEquipped() ) )
		{
			isNotEquippable = !( IsEquippable() );
		}
		return ( ( ( isNotEquippable || !( IsLevelRequirementMet() ) ) || !( IsStrengthRequirementMet() ) ) || !( IsReflexRequirementMet() ) ) || !( IsPerkRequirementMet() );
	}

	public function GetLevelRequirementValue() : Int32
	{
		return m_itemRequiredLevel;
	}

	public function GetStrengthRequirementValue() : Int32
	{
		return m_requiredStrength;
	}

	public function GetReflexRequirementValue() : Int32
	{
		return m_requiredReflex;
	}

	public function GetPerkRequirementValue() : String
	{
		return m_perkRequirementName;
	}

	public function SetIsEquippable( value : Bool )
	{
		m_isEquippableFetched = value;
		m_isEquippable = value;
		m_isHumanityRequirementMet = value;
	}

	public function SetIsEquippableAdditionalValue( value : Bool )
	{
		m_isEquippableAdditionalValue = value;
	}

	public function IsEquippableRaw( optional force : Bool ) : Bool
	{
		if( m_isEquippableFetched && !( force ) )
		{
			return m_isEquippable;
		}
		m_isEquippable = EquipmentSystem.GetInstance( m_player ).GetPlayerData( m_player ).IsEquippable( m_attachedItem.GetItemData() );
		m_isEquippableFetched = true;
		return m_isEquippable;
	}

	public function IsEquippable( optional force : Bool ) : Bool
	{
		return IsEquippableRaw( force ) && m_isEquippableAdditionalValue;
	}

	private function FetchEquipRequirements( optional force : Bool )
	{
		if( m_equipRequirementsFetched && !( force ) )
		{
			return;
		}
		m_equipRequirements = RPGManager.GetEquipRequirements( m_player, m_attachedItem.GetItemData() );
	}

	public function GetFirstUnmetEquipRequirement() : SItemStackRequirementData
	{
		FetchEquipRequirements();
		return RPGManager.GetFirstUnmetEquipRequirement( m_player, m_equipRequirements );
	}

}

