class UIInventoryItemStatsManager
{
	var Stats : array< UIInventoryItemStat >;
	var TooltipStats : array< UIInventoryItemStat >;
	var AdditionalStats : array< UIInventoryItemStat >;
	var AttributeAllocationStats : array< UIInventoryItemStat >;
	private var m_item : weak< UIInventoryItem >;
	private var m_gameItemData : weak< gameItemData >;
	private var m_itemType : gamedataItemType;
	private var m_manager : weak< UIInventoryItemsManager >;
	private var m_statMap : weak< UIStatsMap_Record >;
	private var m_statsFetched : Bool;
	private var m_tooltipStatsFetched : Bool;
	private var m_weaponBars : UIInventoryItemWeaponBars;
	private var m_weaponBarsFetched : Bool;
	private var m_useBareStats : Bool;

	public function SetTooltipsStats( tooltipStats : ref< array< UIInventoryItemStat > > )
	{
		TooltipStats = tooltipStats;
	}

	public static function Make( item : weak< UIInventoryItem >, statMap : weak< UIStatsMap_Record >, optional manager : weak< UIInventoryItemsManager > ) : UIInventoryItemStatsManager
	{
		var instance : UIInventoryItemStatsManager;
		instance = new UIInventoryItemStatsManager;
		instance.m_manager = manager;
		instance.m_item = item;
		instance.m_itemType = item.GetItemType();
		instance.m_gameItemData = item.GetItemData();
		instance.m_statMap = statMap;
		return instance;
	}

	public static function Make( itemData : weak< gameItemData >, statMap : weak< UIStatsMap_Record >, optional manager : weak< UIInventoryItemsManager > ) : UIInventoryItemStatsManager
	{
		var instance : UIInventoryItemStatsManager;
		instance = new UIInventoryItemStatsManager;
		instance.m_manager = manager;
		instance.m_gameItemData = itemData;
		instance.m_itemType = itemData.GetItemType();
		instance.m_statMap = statMap;
		return instance;
	}

	private function FetchSecondayStats()
	{
		var i, limit : Int32;
		var secondaryStats : array< weak< Stat_Record > >;
		var isClothing, isGrenade : Bool;
		var statType : gamedataStatType;
		var stat : UIInventoryItemStat;
		if( m_statsFetched )
		{
			return;
		}
		m_statMap.SecondaryStats( secondaryStats );
		isClothing = UIInventoryItemsManager.IsItemTypeCloting( m_item.GetItemType() );
		isGrenade = UIInventoryItemsManager.IsItemTypeGrenade( m_item.GetItemType() );
		for( i = 0, limit = secondaryStats.Size(); i < limit; i += 1 )
		{
			statType = secondaryStats[ i ].StatType();
			if( isGrenade || ( isClothing && statType == gamedataStatType.Armor ) )
			{
				continue;
			}
			stat = this.InternalFetchStatByType( statType, secondaryStats[ i ].GetID(), true );
			if( stat != NULL )
			{
				if( UIItemsHelper.IsAttributeAllocationStat( statType ) )
				{
					this.AttributeAllocationStats.PushBack( stat );
				}
				else
				{
					this.Stats.PushBack( stat );
				}
			}
		}
		m_statsFetched = true;
	}

	private function FetchTooltipStats()
	{
		var i, limit : Int32;
		var tooltipStats : array< weak< Stat_Record > >;
		var stat : UIInventoryItemStat;
		if( m_tooltipStatsFetched )
		{
			return;
		}
		m_statMap.TooltipStats( tooltipStats );
		for( i = 0, limit = tooltipStats.Size(); i < limit; i += 1 )
		{
			stat = this.InternalFetchStatByType( tooltipStats[ i ].StatType(), tooltipStats[ i ].GetID(), true );
			if( stat != NULL )
			{
				this.TooltipStats.PushBack( stat );
			}
		}
		m_tooltipStatsFetched = true;
	}

	private function FetchAdditionalStatByType( statType : gamedataStatType ) : weak< UIInventoryItemStat >
	{
		var statId : TweakDBID;
		var stat : UIInventoryItemStat;
		statId = TDBID.Create( "BaseStats." + EnumValueToString( "gamedataStatType", ( ( Int32 )( statType ) ) ) );
		stat = InternalFetchStatByType( statType, statId, false );
		AdditionalStats.PushBack( stat );
		return stat;
	}

	private function InternalFetchStatByType( statType : gamedataStatType, statId : TweakDBID, skipEmpty : Bool ) : UIInventoryItemStat
	{
		var itemStat : UIInventoryItemStat;
		var value, absValue : Float;
		var roundValue : Bool;
		var gameItemDataStrong : gameItemData;
		gameItemDataStrong = m_gameItemData;
		if( gameItemDataStrong )
		{
			if( m_useBareStats )
			{
				value = gameItemDataStrong.GetBareStatValueByType( statType );
			}
			else
			{
				value = gameItemDataStrong.GetStatValueByType( statType );
			}
		}
		roundValue = TweakDBInterface.GetBool( statId + T".roundValue", false );
		absValue = AbsF( value );
		if( skipEmpty )
		{
			if( ( ( roundValue ) ? ( RoundF( absValue ) <= 0 ) : ( absValue <= 0.001 ) ) )
			{
				return NULL;
			}
		}
		itemStat = new UIInventoryItemStat;
		itemStat.Type = statType;
		itemStat.Value = value;
		itemStat.PropertiesProvider = DefaultUIInventoryItemStatsProvider.Make( itemStat.Type, m_manager );
		return itemStat;
	}

	public static function FromMinimalItemTooltipData( data : MinimalItemTooltipData, optional manager : weak< UIInventoryItemsManager > ) : UIInventoryItemStatsManager
	{
		var instance : UIInventoryItemStatsManager;
		var i, limit : Int32;
		var itemStat : UIInventoryItemStat;
		instance = new UIInventoryItemStatsManager;
		instance.m_manager = manager;
		for( i = 0, limit = data.stats.Size(); i < limit; i += 1 )
		{
			itemStat = new UIInventoryItemStat;
			itemStat.Type = data.stats[ i ].type;
			itemStat.Value = data.stats[ i ].value;
			itemStat.SetProperties( UIItemStatProperties.Make( data.stats[ i ].statName, data.stats[ i ].decimalPlaces, data.stats[ i ].displayPercent, data.stats[ i ].displayPlus, data.stats[ i ].inMeters, data.stats[ i ].inSeconds, data.stats[ i ].inSpeed, data.stats[ i ].multiplyBy100InText, data.stats[ i ].roundValue, ( ( manager != NULL ) ? ( manager.GetWeaponStatMaxValue( itemStat.Type ) ) : ( -1.0 ) ), data.stats[ i ].flipNegative ) );
			instance.Stats.PushBack( itemStat );
		}
		return instance;
	}

	public static function FromMinimalItemTooltipDataToTooltipStats( data : MinimalItemTooltipData, optional manager : weak< UIInventoryItemsManager > ) : UIInventoryItemStatsManager
	{
		var instance : UIInventoryItemStatsManager;
		var i, limit : Int32;
		var itemStat : UIInventoryItemStat;
		instance = new UIInventoryItemStatsManager;
		instance.m_manager = manager;
		for( i = 0, limit = data.stats.Size(); i < limit; i += 1 )
		{
			itemStat = new UIInventoryItemStat;
			itemStat.Type = data.stats[ i ].type;
			itemStat.Value = data.stats[ i ].value;
			itemStat.SetProperties( UIItemStatProperties.Make( data.stats[ i ].statName, data.stats[ i ].decimalPlaces, data.stats[ i ].displayPercent, data.stats[ i ].displayPlus, data.stats[ i ].inMeters, data.stats[ i ].inSeconds, data.stats[ i ].inSpeed, data.stats[ i ].multiplyBy100InText, data.stats[ i ].roundValue, ( ( manager != NULL ) ? ( manager.GetWeaponStatMaxValue( itemStat.Type ) ) : ( -1.0 ) ), data.stats[ i ].flipNegative ) );
			instance.TooltipStats.PushBack( itemStat );
		}
		return instance;
	}

	public function Size() : Int32
	{
		FetchSecondayStats();
		return Stats.Size();
	}

	public function SizeTooltipStats() : Int32
	{
		FetchTooltipStats();
		return TooltipStats.Size();
	}

	public function SizeAttributeAllocationStats() : Int32
	{
		FetchSecondayStats();
		return AttributeAllocationStats.Size();
	}

	public function Get( index : Int32 ) : weak< UIInventoryItemStat >
	{
		FetchSecondayStats();
		return Stats[ index ];
	}

	public function GetTooltipStat( index : Int32 ) : weak< UIInventoryItemStat >
	{
		FetchTooltipStats();
		return TooltipStats[ index ];
	}

	public function GetAttributeAllocationStats( index : Int32 ) : weak< UIInventoryItemStat >
	{
		FetchSecondayStats();
		return AttributeAllocationStats[ index ];
	}

	public function GetByType( type : gamedataStatType ) : weak< UIInventoryItemStat >
	{
		var i, limit : Int32;
		FetchSecondayStats();
		for( i = 0, limit = Stats.Size(); i < limit; i += 1 )
		{
			if( Stats[ i ].Type == type )
			{
				return Stats[ i ];
			}
		}
		return NULL;
	}

	public function GetTooltipStatByType( type : gamedataStatType ) : weak< UIInventoryItemStat >
	{
		var i, limit : Int32;
		FetchTooltipStats();
		for( i = 0, limit = TooltipStats.Size(); i < limit; i += 1 )
		{
			if( TooltipStats[ i ].Type == type )
			{
				return TooltipStats[ i ];
			}
		}
		return NULL;
	}

	public function GetAdditionalStatByType( type : gamedataStatType ) : weak< UIInventoryItemStat >
	{
		var i, limit : Int32;
		for( i = 0, limit = AdditionalStats.Size(); i < limit; i += 1 )
		{
			if( AdditionalStats[ i ].Type == type )
			{
				return AdditionalStats[ i ];
			}
		}
		return FetchAdditionalStatByType( type );
	}

	public function GetAttributeAllocationStatByType( type : gamedataStatType ) : weak< UIInventoryItemStat >
	{
		var i, limit : Int32;
		FetchSecondayStats();
		for( i = 0, limit = AttributeAllocationStats.Size(); i < limit; i += 1 )
		{
			if( AttributeAllocationStats[ i ].Type == type )
			{
				return AttributeAllocationStats[ i ];
			}
		}
		return NULL;
	}

	private function GetWeaponBarsType( itemType : gamedataItemType, item : weak< UIInventoryItem > ) : UIInventoryItemWeaponBarsType
	{
		if( itemType == gamedataItemType.Con_Injector )
		{
			return UIInventoryItemWeaponBarsType.InjectorHealing;
		}
		if( itemType == gamedataItemType.Con_Inhaler )
		{
			return UIInventoryItemWeaponBarsType.InhalerHealing;
		}
		if( itemType == gamedataItemType.Cyb_Launcher )
		{
			return UIInventoryItemWeaponBarsType.CyberwareRangedWeapon;
		}
		if( RPGManager.IsItemTypeCyberwareWeapon( itemType ) )
		{
			return UIInventoryItemWeaponBarsType.CyberwareWeapon;
		}
		if( item.GetWeaponType() == WeaponType.Melee )
		{
			if( item.GetWeaponEvolution() == gamedataWeaponEvolution.Throwable )
			{
				return UIInventoryItemWeaponBarsType.Throwable;
			}
			return UIInventoryItemWeaponBarsType.Melee;
		}
		return UIInventoryItemWeaponBarsType.Ranged;
	}

	private function GetWeaponBarsType( itemType : gamedataItemType, itemData : gameItemData ) : UIInventoryItemWeaponBarsType
	{
		var weaponRecord : weak< WeaponItem_Record >;
		var itemID : ItemID;
		var itemTweakID : TweakDBID;
		itemID = itemData.GetID();
		itemTweakID = ItemID.GetTDBID( itemID );
		if( itemType == gamedataItemType.Con_Injector )
		{
			return UIInventoryItemWeaponBarsType.InjectorHealing;
		}
		if( itemType == gamedataItemType.Con_Inhaler )
		{
			return UIInventoryItemWeaponBarsType.InhalerHealing;
		}
		if( itemType == gamedataItemType.Cyb_Launcher )
		{
			return UIInventoryItemWeaponBarsType.CyberwareRangedWeapon;
		}
		if( RPGManager.IsItemTypeCyberwareWeapon( itemType ) )
		{
			return UIInventoryItemWeaponBarsType.CyberwareWeapon;
		}
		if( UIInventoryItemsManager.IsItemTypeMeleeWeapon( m_gameItemData.GetItemType() ) )
		{
			weaponRecord = ( ( weak< weak< WeaponItem_Record > > )( TweakDBInterface.GetItemRecord( itemTweakID ) ) );
			if( weaponRecord && weaponRecord.Evolution().Type() == gamedataWeaponEvolution.Throwable )
			{
				return UIInventoryItemWeaponBarsType.Throwable;
			}
			return UIInventoryItemWeaponBarsType.Melee;
		}
		return UIInventoryItemWeaponBarsType.Ranged;
	}

	private function IsItemTypeUsingBars( itemData : UIInventoryItem ) : Bool
	{
		return itemData.IsWeapon() || itemData.IsUsingBars();
	}

	public function GetWeaponBars( optional force : Bool ) : weak< UIInventoryItemWeaponBars >
	{
		var weaponType : UIInventoryItemWeaponBarsType;
		var itemType : gamedataItemType;
		var itemStrong : UIInventoryItem;
		var gameItemDataStrong : gameItemData;
		var itemData : gameItemData;
		itemStrong = m_item;
		gameItemDataStrong = m_gameItemData;
		if( itemStrong )
		{
			if( !( IsItemTypeUsingBars( itemStrong ) ) )
			{
				return NULL;
			}
		}
		if( m_weaponBarsFetched && !( force ) )
		{
			return m_weaponBars;
		}
		if( itemStrong )
		{
			itemType = itemStrong.GetItemType();
			weaponType = GetWeaponBarsType( itemType, itemStrong );
			itemData = itemStrong.GetItemData();
		}
		else
		{
			itemType = gameItemDataStrong.GetItemType();
			weaponType = GetWeaponBarsType( itemType, gameItemDataStrong );
			itemData = gameItemDataStrong;
		}
		m_useBareStats = true;
		m_weaponBars = UIInventoryItemWeaponBars.Make( this, itemData, itemType, weaponType );
		m_weaponBarsFetched = true;
		return m_weaponBars;
	}

	public function FlushComparedBars()
	{
		if( m_weaponBarsFetched )
		{
			m_weaponBars.SetComparedBars( NULL );
		}
	}

	public function GetGameItemData() : weak< gameItemData >
	{
		return m_gameItemData;
	}

	public function GetAttachedPlayer() : weak< PlayerPuppet >
	{
		return m_manager.GetAttachedPlayer();
	}

	public function IsCurveBarsEnabled() : Bool
	{
		if( m_manager != NULL )
		{
			return m_manager.GetCurveBarsEnabled();
		}
		return true;
	}

	public function IsSeparatorBarsEnabled() : Bool
	{
		if( m_manager != NULL )
		{
			return m_manager.GetSeparatorBarsEnabled();
		}
		return true;
	}

	private static function MapBarTypeToStat( type : WeaponBarType ) : gamedataStatType
	{
		switch( type )
		{
			case WeaponBarType.AttackSpeed:
				return gamedataStatType.AttacksPerSecond;
			case WeaponBarType.DamagePerHit:
				return gamedataStatType.EffectiveDamagePerHit;
			case WeaponBarType.ReloadSpeed:
				return gamedataStatType.ReloadTime;
			case WeaponBarType.Range:
				return gamedataStatType.EffectiveRange;
			case WeaponBarType.Handling:
				return gamedataStatType.Handling;
			case WeaponBarType.Stamina:
				return gamedataStatType.Stamina;
			case WeaponBarType.MeleeAttackSpeed:
				return gamedataStatType.AttacksPerSecond;
			case WeaponBarType.MeleeDamagePerHit:
				return gamedataStatType.EffectiveDamagePerHit;
			case WeaponBarType.MeleeStamina:
				return gamedataStatType.Stamina;
			case WeaponBarType.ThrowableEffectiveRange:
				return gamedataStatType.EffectiveRange;
			case WeaponBarType.ThrowableReturnTime:
				return gamedataStatType.ThrowRecovery;
			case WeaponBarType.CyberwareAttackSpeed:
				return gamedataStatType.AttacksPerSecond;
			case WeaponBarType.CyberwareDamagePerHit:
				return gamedataStatType.EffectiveDamagePerHit;
			case WeaponBarType.Healing:
				return gamedataStatType.InhalerBaseHealing;
			case WeaponBarType.HealingOverTime:
				return gamedataStatType.InjectorBaseHealing;
		}
		return gamedataStatType.Invalid;
	}

	private static function IsBarTypeMelee( type : WeaponBarType ) : Bool
	{
		return ( ( ( type == WeaponBarType.MeleeAttackSpeed || type == WeaponBarType.MeleeDamagePerHit ) || type == WeaponBarType.MeleeStamina ) || type == WeaponBarType.ThrowableEffectiveRange ) || type == WeaponBarType.ThrowableReturnTime;
	}

	private static function IsUsingCurveCustom( itemType : gamedataItemType, type : WeaponBarType ) : Bool
	{
		if( type == WeaponBarType.DamagePerHit )
		{
			if( ( itemType == gamedataItemType.Wea_Shotgun || itemType == gamedataItemType.Wea_ShotgunDual ) || itemType == gamedataItemType.Wea_SniperRifle )
			{
				return true;
			}
		}
		if( type == WeaponBarType.CyberwareDamagePerHit )
		{
			if( itemType == gamedataItemType.Cyb_Launcher )
			{
				return true;
			}
		}
		return false;
	}

	private function GetPercentageCurveName( type : WeaponBarType ) : CName
	{
		var statType : gamedataStatType;
		var prefix : String;
		statType = UIInventoryItemStatsManager.MapBarTypeToStat( type );
		if( UIInventoryItemStatsManager.IsBarTypeMelee( type ) )
		{
			prefix = "melee_";
		}
		if( UIInventoryItemStatsManager.IsUsingCurveCustom( m_itemType, type ) )
		{
			return StringToName( ( ( prefix + EnumValueToString( "gamedataStatType", ( ( Int64 )( statType ) ) ) ) + "_" ) + EnumValueToString( "gamedataItemType", ( ( Int64 )( m_itemType ) ) ) );
		}
		return StringToName( ( prefix + EnumValueToString( "gamedataStatType", ( ( Int64 )( statType ) ) ) ) + "_default" );
	}

	public function GetPercentageFromCurve( type : WeaponBarType, value : Float ) : Float
	{
		if( m_manager )
		{
			return m_manager.GetStatsSystemValueFromCurve( 'tooltip_weapon_bars', GetPercentageCurveName( type ), value );
		}
		return -1.0;
	}

}

class UIItemStatProperties
{
	private var localizedName : String;
	private var decimalPlaces : Int32;
	private var displayPercent : Bool;
	private var displayPlus : Bool;
	private var inMeters : Bool;
	private var inSeconds : Bool;
	private var inSpeed : Bool;
	private var multiplyBy100InText : Bool;
	private var roundValue : Bool;
	private var maxValue : Float;
	private var flipNegative : Bool;

	public static function Make( const localizedName : ref< String >, decimalPlaces : Int32, displayPercent : Bool, displayPlus : Bool, inMeters : Bool, inSeconds : Bool, inSpeed : Bool, multiplyBy100InText : Bool, roundValue : Bool, maxValue : Float, flipNegative : Bool ) : UIItemStatProperties
	{
		var instance : UIItemStatProperties;
		instance = new UIItemStatProperties;
		instance.localizedName = localizedName;
		instance.decimalPlaces = decimalPlaces;
		instance.displayPercent = displayPercent;
		instance.displayPlus = displayPlus;
		instance.inMeters = inMeters;
		instance.inSeconds = inSeconds;
		instance.inSpeed = inSpeed;
		instance.multiplyBy100InText = multiplyBy100InText;
		instance.roundValue = roundValue;
		instance.maxValue = maxValue;
		instance.flipNegative = flipNegative;
		return instance;
	}

	public function GetName() : String
	{
		return localizedName;
	}

	public function DecimalPlaces() : Int32
	{
		return decimalPlaces;
	}

	public function DisplayPercent() : Bool
	{
		return displayPercent;
	}

	public function DisplayPlus() : Bool
	{
		return displayPlus;
	}

	public function InMeters() : Bool
	{
		return inMeters;
	}

	public function InSeconds() : Bool
	{
		return inSeconds;
	}

	public function InSpeed() : Bool
	{
		return inSpeed;
	}

	public function MultiplyBy100InText() : Bool
	{
		return multiplyBy100InText;
	}

	public function RoundValue() : Bool
	{
		return roundValue;
	}

	public function MaxValue() : Float
	{
		return maxValue;
	}

	public function FlipNegative() : Bool
	{
		return flipNegative;
	}

}

enum WeaponBarType
{
	AttackSpeed = 0,
	DamagePerHit = 1,
	ReloadSpeed = 2,
	Range = 3,
	Handling = 4,
	Stamina = 5,
	RangedCount = 6,
	MeleeAttackSpeed = 7,
	MeleeDamagePerHit = 8,
	MeleeStamina = 9,
	ThrowableEffectiveRange = 10,
	ThrowableReturnTime = 11,
	MeleeCount = 12,
	CyberwareAttackSpeed = 13,
	CyberwareDamagePerHit = 14,
	CyberwareCount = 15,
	Healing = 16,
	HealingOverTime = 17,
	HealingCount = 18,
	Invalid = -1,
}

enum WeaponBarTypeGroup
{
	AttackSpeed = 0,
	DamagePerHit = 1,
	Range = 2,
	ReloadSpeed = 3,
	Stamina = 4,
	Handling = 5,
	ReturnTime = 6,
	Healing = 7,
	HealingOverTime = 8,
	Invalid = -1,
}

class UIInventoryItemWeaponBar
{
	var Value : Float;
	var MaxValue : Float;
	var Percentage : Float;
	var Type : WeaponBarType;
	private var m_isValueSet : Bool;

	public static function Make( itemType : gamedataItemType, type : WeaponBarType, value : Float, maxValue : Float, optional withoutValue : Bool ) : UIInventoryItemWeaponBar
	{
		var instance : UIInventoryItemWeaponBar;
		instance = new UIInventoryItemWeaponBar;
		if( withoutValue )
		{
			value = 0.0;
		}
		instance.Value = value;
		instance.MaxValue = maxValue;
		instance.Type = type;
		instance.m_isValueSet = !( withoutValue );
		if( UIInventoryItemWeaponBars.IsBarReversed( type ) )
		{
			value = maxValue - value;
		}
		instance.Percentage = ( value * UIInventoryItemWeaponBars.GetItemTypeMultiplier( itemType ) ) / maxValue;
		return instance;
	}

	public static function MakeCurve( type : WeaponBarType, value : Float, statsManager : UIInventoryItemStatsManager, optional withoutValue : Bool ) : UIInventoryItemWeaponBar
	{
		var instance : UIInventoryItemWeaponBar;
		instance = new UIInventoryItemWeaponBar;
		if( withoutValue )
		{
			value = 0.0;
		}
		instance.Value = value;
		instance.Type = type;
		instance.m_isValueSet = !( withoutValue );
		instance.Percentage = statsManager.GetPercentageFromCurve( type, value );
		return instance;
	}

	public function IsValueSet() : Bool
	{
		return m_isValueSet;
	}

	public static function GetBarTypeGroup( barType : WeaponBarType ) : WeaponBarTypeGroup
	{
		switch( barType )
		{
			case WeaponBarType.AttackSpeed:
				return WeaponBarTypeGroup.AttackSpeed;
			case WeaponBarType.MeleeAttackSpeed:
				return WeaponBarTypeGroup.AttackSpeed;
			case WeaponBarType.DamagePerHit:
				return WeaponBarTypeGroup.DamagePerHit;
			case WeaponBarType.MeleeDamagePerHit:
				return WeaponBarTypeGroup.DamagePerHit;
			case WeaponBarType.Range:
				return WeaponBarTypeGroup.Range;
			case WeaponBarType.ThrowableEffectiveRange:
				return WeaponBarTypeGroup.Range;
			case WeaponBarType.Stamina:
				return WeaponBarTypeGroup.Stamina;
			case WeaponBarType.MeleeStamina:
				return WeaponBarTypeGroup.Stamina;
			case WeaponBarType.ReloadSpeed:
				return WeaponBarTypeGroup.ReloadSpeed;
			case WeaponBarType.ThrowableReturnTime:
				return WeaponBarTypeGroup.ReturnTime;
			case WeaponBarType.Handling:
				return WeaponBarTypeGroup.Handling;
			case WeaponBarType.Healing:
				return WeaponBarTypeGroup.Healing;
			case WeaponBarType.HealingOverTime:
				return WeaponBarTypeGroup.HealingOverTime;
		}
		return WeaponBarTypeGroup.Invalid;
	}

	public function GetBarTypeGroup() : WeaponBarTypeGroup
	{
		return UIInventoryItemWeaponBar.GetBarTypeGroup( Type );
	}

}

class UIInventoryItemWeaponBars
{
	var Values : array< UIInventoryItemWeaponBar >;
	private var m_type : UIInventoryItemWeaponBarsType;
	private var m_itemType : gamedataItemType;
	private var m_comparedBars : UIInventoryItemWeaponBars;

	public static function Make( statsManager : UIInventoryItemStatsManager, itemData : gameItemData, itemType : gamedataItemType, type : UIInventoryItemWeaponBarsType ) : UIInventoryItemWeaponBars
	{
		if( type == UIInventoryItemWeaponBarsType.InjectorHealing || type == UIInventoryItemWeaponBarsType.InhalerHealing )
		{
			return MakeHealing( statsManager, itemData, itemType );
		}
		if( type == UIInventoryItemWeaponBarsType.CyberwareRangedWeapon )
		{
			return MakeCyberwareRangedWeapon( statsManager, itemType );
		}
		if( type != UIInventoryItemWeaponBarsType.Ranged )
		{
			return MakeMelee( statsManager, itemType, type );
		}
		return MakeRanged( statsManager, itemType );
	}

	public static function MakeHealing( statsManager : UIInventoryItemStatsManager, itemData : gameItemData, itemType : gamedataItemType ) : UIInventoryItemWeaponBars
	{
		var instance : UIInventoryItemWeaponBars;
		instance = new UIInventoryItemWeaponBars;
		instance.m_type = ( ( itemType == gamedataItemType.Con_Injector ) ? ( UIInventoryItemWeaponBarsType.InjectorHealing ) : ( UIInventoryItemWeaponBarsType.InhalerHealing ) );
		instance.m_itemType = itemType;
		instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.Healing, GetInstantHealing( itemData ), statsManager ) );
		instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.HealingOverTime, GetCumulativeHealing( itemData ), statsManager ) );
		return instance;
	}

	private static function GetInstantHealing( itemData : gameItemData ) : Float
	{
		var i, j, iLimit, jLimit : Int32;
		var itemRecord : weak< Item_Record >;
		var dataPackages : array< weak< GameplayLogicPackage_Record > >;
		var stats : array< weak< StatModifier_Record > >;
		var constantStatModifier : weak< ConstantStatModifier_Record >;
		itemRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemData.GetID() ) );
		itemRecord.OnEquip( dataPackages );
		for( i = 0, iLimit = dataPackages.Size(); i < iLimit; i += 1 )
		{
			stats.Clear();
			dataPackages[ i ].Stats( stats );
			for( j = 0, jLimit = stats.Size(); j < jLimit; j += 1 )
			{
				if( stats[ j ].StatType().StatType() == gamedataStatType.InhalerBaseHealing || stats[ j ].StatType().StatType() == gamedataStatType.InjectorBaseHealing )
				{
					constantStatModifier = ( ( weak< weak< ConstantStatModifier_Record > > )( stats[ j ] ) );
					if( constantStatModifier != NULL )
					{
						return constantStatModifier.Value();
					}
				}
			}
		}
		return 0.0;
	}

	private static function GetInjectorDuration() : Float
	{
		var injectorDurationStat : weak< StatModifierGroup_Record >;
		var stat : weak< ConstantStatModifier_Record >;
		injectorDurationStat = TweakDBInterface.GetStatModifierGroupRecord( T"Items.BonesMcCoy70Duration" );
		if( injectorDurationStat != NULL )
		{
			stat = ( ( weak< weak< ConstantStatModifier_Record > > )( injectorDurationStat.GetStatModifiersItem( 0 ) ) );
			if( stat != NULL )
			{
				return stat.Value();
			}
		}
		return 0.0;
	}

	private static function GetCumulativeHealing( itemData : gameItemData ) : Float
	{
		var i, j, iLimit, jLimit : Int32;
		var itemRecord : weak< Item_Record >;
		var dataPackages : array< weak< GameplayLogicPackage_Record > >;
		var stats : array< weak< StatModifier_Record > >;
		var constantStatModifier : weak< ConstantStatModifier_Record >;
		var instantValue : Float;
		var overTimeValue : Float;
		var injectorDuration : Float;
		var statType : gamedataStatType;
		itemRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemData.GetID() ) );
		injectorDuration = GetInjectorDuration();
		itemRecord.OnEquip( dataPackages );
		for( i = 0, iLimit = dataPackages.Size(); i < iLimit; i += 1 )
		{
			stats.Clear();
			dataPackages[ i ].Stats( stats );
			for( j = 0, jLimit = stats.Size(); j < jLimit; j += 1 )
			{
				statType = stats[ j ].StatType().StatType();
				if( statType == gamedataStatType.InjectorBaseOverTheTimeHealing )
				{
					constantStatModifier = ( ( weak< weak< ConstantStatModifier_Record > > )( stats[ j ] ) );
					if( constantStatModifier != NULL )
					{
						overTimeValue += ( constantStatModifier.Value() * injectorDuration );
					}
				}
			}
		}
		return instantValue + overTimeValue;
	}

	private static function GetProjectileLauncherDamage( itemData : weak< gameItemData >, player : weak< PlayerPuppet > ) : Float
	{
		var i, limit : Int32;
		var installedProjectile : InnerItemData;
		var attackString : String;
		var attackRecord : weak< Attack_Record >;
		var statModifiers : array< weak< StatModifier_Record > >;
		var resultDamage : Float;
		var curveModifier : weak< CurveStatModifier_Record >;
		var qualityMultiplier : Float;
		itemData.GetItemPart( installedProjectile, T"AttachmentSlots.ProjectileLauncherRound" );
		attackString = TweakDBInterface.GetString( ItemID.GetTDBID( InnerItemData.GetItemID( installedProjectile ) ) + T".attack", "" );
		attackRecord = TweakDBInterface.GetAttackRecord( TDBID.Create( attackString ) );
		attackRecord.StatModifiers( statModifiers );
		for( i = 0, limit = statModifiers.Size(); i < limit; i += 1 )
		{
			if( !( RPGManager.IsDamageStat( statModifiers[ i ].StatType().StatType() ) ) )
			{
				continue;
			}
			if( ( ( ConstantStatModifier_Record )( statModifiers[ i ] ) ) )
			{
				resultDamage += ( ( ConstantStatModifier_Record )( statModifiers[ i ] ) ).Value();
			}
			curveModifier = ( ( CurveStatModifier_Record )( statModifiers[ i ] ) );
			if( curveModifier )
			{
				if( curveModifier.Column() == "quality_to_dps_multiplier_new" )
				{
					qualityMultiplier = itemData.GetStatValueByType( gamedataStatType.ProjectileLauncherQualityMult );
					resultDamage *= GameInstance.GetStatsDataSystem( player.GetGame() ).GetValueFromCurve( StringToName( curveModifier.Id() ), qualityMultiplier, StringToName( curveModifier.Column() ) );
				}
			}
		}
		return resultDamage;
	}

	public static function MakeCyberwareRangedWeapon( statsManager : UIInventoryItemStatsManager, itemType : gamedataItemType ) : UIInventoryItemWeaponBars
	{
		var instance : UIInventoryItemWeaponBars;
		var attacksPerSecondStat, cycleTimeBaseStat : UIInventoryItemStat;
		var effectiveDamagePerHitStat : UIInventoryItemStat;
		var statCurveEnabled : Bool;
		statCurveEnabled = statsManager.IsCurveBarsEnabled();
		instance = new UIInventoryItemWeaponBars;
		instance.m_type = UIInventoryItemWeaponBarsType.CyberwareRangedWeapon;
		instance.m_itemType = itemType;
		if( statCurveEnabled )
		{
			cycleTimeBaseStat = statsManager.GetAdditionalStatByType( gamedataStatType.CycleTimeBase );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.CyberwareAttackSpeed, 1.0 / ( cycleTimeBaseStat.Value / 5.0 ), statsManager ) );
			effectiveDamagePerHitStat = statsManager.GetAdditionalStatByType( gamedataStatType.EffectiveDamagePerHit );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.CyberwareDamagePerHit, GetProjectileLauncherDamage( statsManager.GetGameItemData(), statsManager.GetAttachedPlayer() ), statsManager ) );
			return instance;
		}
		attacksPerSecondStat = statsManager.GetAdditionalStatByType( gamedataStatType.AttacksPerSecond );
		cycleTimeBaseStat = statsManager.GetAdditionalStatByType( gamedataStatType.CycleTimeBase );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.AttackSpeed, 1.0 / ( cycleTimeBaseStat.Value / 5.0 ), attacksPerSecondStat.GetProperties().MaxValue() ) );
		effectiveDamagePerHitStat = statsManager.GetAdditionalStatByType( gamedataStatType.EffectiveDamagePerHit );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.DamagePerHit, GetProjectileLauncherDamage( statsManager.GetGameItemData(), statsManager.GetAttachedPlayer() ), effectiveDamagePerHitStat.GetProperties().MaxValue() ) );
		return instance;
	}

	public static function MakeRanged( statsManager : UIInventoryItemStatsManager, itemType : gamedataItemType ) : UIInventoryItemWeaponBars
	{
		var instance : UIInventoryItemWeaponBars;
		var attacksPerSecondStat, cycleTimeStat : UIInventoryItemStat;
		var effectiveDamagePerHitStat : UIInventoryItemStat;
		var reloadSpeedStat : UIInventoryItemStat;
		var effectiveRangeStat : UIInventoryItemStat;
		var statCurveEnabled : Bool;
		statCurveEnabled = statsManager.IsCurveBarsEnabled();
		instance = new UIInventoryItemWeaponBars;
		instance.m_type = UIInventoryItemWeaponBarsType.Ranged;
		instance.m_itemType = itemType;
		if( statCurveEnabled )
		{
			cycleTimeStat = statsManager.GetAdditionalStatByType( gamedataStatType.CycleTime );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.AttackSpeed, 1.0 / cycleTimeStat.Value, statsManager ) );
			effectiveDamagePerHitStat = statsManager.GetAdditionalStatByType( gamedataStatType.EffectiveDamagePerHit );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.DamagePerHit, effectiveDamagePerHitStat.Value, statsManager ) );
			reloadSpeedStat = statsManager.GetAdditionalStatByType( gamedataStatType.ReloadTime );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.ReloadSpeed, reloadSpeedStat.Value, statsManager ) );
			effectiveRangeStat = statsManager.GetAdditionalStatByType( gamedataStatType.EffectiveRange );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.Range, effectiveRangeStat.Value, statsManager ) );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.Handling, CalculateHandling( statsManager.GetAdditionalStatByType( gamedataStatType.CycleTime ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.SpreadDefaultX ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.RecoilKickMax ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.RecoilDir ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.RecoilAngle ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.SwaySideMaximumAngleDistance ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.SwaySideBottomAngleLimit ).Value ), statsManager ) );
			return instance;
		}
		attacksPerSecondStat = statsManager.GetAdditionalStatByType( gamedataStatType.AttacksPerSecond );
		cycleTimeStat = statsManager.GetAdditionalStatByType( gamedataStatType.CycleTime );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.AttackSpeed, 1.0 / cycleTimeStat.Value, attacksPerSecondStat.GetProperties().MaxValue() ) );
		effectiveDamagePerHitStat = statsManager.GetAdditionalStatByType( gamedataStatType.EffectiveDamagePerHit );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.DamagePerHit, effectiveDamagePerHitStat.Value, effectiveDamagePerHitStat.GetProperties().MaxValue() ) );
		reloadSpeedStat = statsManager.GetAdditionalStatByType( gamedataStatType.ReloadTime );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.ReloadSpeed, reloadSpeedStat.Value, reloadSpeedStat.GetProperties().MaxValue() ) );
		effectiveRangeStat = statsManager.GetAdditionalStatByType( gamedataStatType.EffectiveRange );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.Range, effectiveRangeStat.Value, effectiveRangeStat.GetProperties().MaxValue() ) );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.Handling, CalculateHandling( statsManager.GetAdditionalStatByType( gamedataStatType.CycleTime ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.SpreadDefaultX ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.RecoilKickMax ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.RecoilDir ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.RecoilAngle ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.SwaySideMaximumAngleDistance ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.SwaySideBottomAngleLimit ).Value ), statsManager.GetAdditionalStatByType( gamedataStatType.Handling ).GetProperties().MaxValue() ) );
		return instance;
	}

	public static function MakeMelee( statsManager : UIInventoryItemStatsManager, itemType : gamedataItemType, type : UIInventoryItemWeaponBarsType ) : UIInventoryItemWeaponBars
	{
		var instance : UIInventoryItemWeaponBars;
		var attacksPerSecondStat : UIInventoryItemStat;
		var effectiveDamagePerHitStat : UIInventoryItemStat;
		var effectiveRangeStat : UIInventoryItemStat;
		var meleeAttackComboDurationStat : UIInventoryItemStat;
		var statCurveEnabled : Bool;
		statCurveEnabled = statsManager.IsCurveBarsEnabled();
		instance = new UIInventoryItemWeaponBars;
		instance.m_type = type;
		instance.m_itemType = itemType;
		if( statCurveEnabled )
		{
			meleeAttackComboDurationStat = statsManager.GetAdditionalStatByType( gamedataStatType.AttacksPerSecond );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.MeleeAttackSpeed, meleeAttackComboDurationStat.Value, statsManager ) );
			effectiveDamagePerHitStat = statsManager.GetAdditionalStatByType( gamedataStatType.EffectiveDamagePerHit );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.MeleeDamagePerHit, effectiveDamagePerHitStat.Value, statsManager ) );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.MeleeStamina, statsManager.GetAdditionalStatByType( gamedataStatType.BaseMeleeAttackStaminaCost ).Value, statsManager ) );
			effectiveRangeStat = statsManager.GetAdditionalStatByType( gamedataStatType.EffectiveRange );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.ThrowableEffectiveRange, effectiveRangeStat.Value, statsManager, type != UIInventoryItemWeaponBarsType.Throwable ) );
			instance.Values.PushBack( UIInventoryItemWeaponBar.MakeCurve( WeaponBarType.ThrowableReturnTime, statsManager.GetAdditionalStatByType( gamedataStatType.ThrowRecovery ).Value, statsManager, type != UIInventoryItemWeaponBarsType.Throwable ) );
			return instance;
		}
		attacksPerSecondStat = statsManager.GetAdditionalStatByType( gamedataStatType.AttacksPerSecond );
		meleeAttackComboDurationStat = statsManager.GetAdditionalStatByType( gamedataStatType.MeleeAttackComboDuration );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.MeleeAttackSpeed, 1.0 / meleeAttackComboDurationStat.Value, attacksPerSecondStat.GetProperties().MaxValue() ) );
		effectiveDamagePerHitStat = statsManager.GetAdditionalStatByType( gamedataStatType.EffectiveDamagePerHit );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.MeleeDamagePerHit, effectiveDamagePerHitStat.Value, effectiveDamagePerHitStat.GetProperties().MaxValue() ) );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.MeleeStamina, statsManager.GetAdditionalStatByType( gamedataStatType.BaseMeleeAttackStaminaCost ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.Stamina ).GetProperties().MaxValue() ) );
		effectiveRangeStat = statsManager.GetAdditionalStatByType( gamedataStatType.EffectiveRange );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.ThrowableEffectiveRange, effectiveRangeStat.Value, effectiveRangeStat.GetProperties().MaxValue(), type != UIInventoryItemWeaponBarsType.Throwable ) );
		instance.Values.PushBack( UIInventoryItemWeaponBar.Make( itemType, WeaponBarType.ThrowableReturnTime, statsManager.GetAdditionalStatByType( gamedataStatType.ThrowRecovery ).Value, statsManager.GetAdditionalStatByType( gamedataStatType.ThrowRecovery ).GetProperties().MaxValue(), type != UIInventoryItemWeaponBarsType.Throwable ) );
		return instance;
	}

	public function SetComparedBars( comparedBars : UIInventoryItemWeaponBars ) : UIInventoryItemWeaponBars
	{
		m_comparedBars = comparedBars;
		return this;
	}

	public function GetComparedBars() : weak< UIInventoryItemWeaponBars >
	{
		return m_comparedBars;
	}

	public function GetPercentages() : array< Float >
	{
		var i, limit : Int32;
		var itemTypeMultiplier, value : Float;
		var result : array< Float >;
		var displayedStats : array< WeaponBarType >;
		displayedStats = UIInventoryItemWeaponBars.GetDisplayedStats( GetType() );
		for( i = 0, limit = displayedStats.Size(); i < limit; i += 1 )
		{
			value = Values[ i ].Value;
			itemTypeMultiplier = GetItemTypeMultiplier( GetItemType() );
			value *= itemTypeMultiplier;
			result.PushBack( ( value / Values[ i ].MaxValue ) * 100.0 );
		}
		return result;
	}

	public static function GetItemTypeMultiplier( itemType : gamedataItemType ) : Float
	{
		if( itemType == gamedataItemType.Wea_SniperRifle )
		{
			return 0.5;
		}
		if( itemType == gamedataItemType.Wea_Shotgun || itemType == gamedataItemType.Wea_ShotgunDual )
		{
			return 0.69999999;
		}
		return 1.0;
	}

	public static function IsBarReversed( barType : WeaponBarType ) : Bool
	{
		return ( ( barType == WeaponBarType.ReloadSpeed || barType == WeaponBarType.ThrowableReturnTime ) || barType == WeaponBarType.Stamina ) || barType == WeaponBarType.MeleeStamina;
	}

	public static function GetDisplayedStats( barsType : UIInventoryItemWeaponBarsType ) : array< WeaponBarType >
	{
		var result : array< WeaponBarType >;
		if( barsType == UIInventoryItemWeaponBarsType.Ranged )
		{
			result.PushBack( WeaponBarType.AttackSpeed );
			result.PushBack( WeaponBarType.DamagePerHit );
			result.PushBack( WeaponBarType.ReloadSpeed );
			result.PushBack( WeaponBarType.Range );
			result.PushBack( WeaponBarType.Handling );
		}
		else if( barsType == UIInventoryItemWeaponBarsType.CyberwareRangedWeapon )
		{
			result.PushBack( WeaponBarType.CyberwareAttackSpeed );
			result.PushBack( WeaponBarType.CyberwareDamagePerHit );
		}
		else if( barsType == UIInventoryItemWeaponBarsType.InjectorHealing || barsType == UIInventoryItemWeaponBarsType.InhalerHealing )
		{
			result.PushBack( WeaponBarType.Healing );
			result.PushBack( WeaponBarType.HealingOverTime );
		}
		else
		{
			result.PushBack( WeaponBarType.MeleeAttackSpeed );
			result.PushBack( WeaponBarType.MeleeDamagePerHit );
			result.PushBack( WeaponBarType.MeleeStamina );
			if( barsType == UIInventoryItemWeaponBarsType.Throwable )
			{
				result.PushBack( WeaponBarType.ThrowableEffectiveRange );
				result.PushBack( WeaponBarType.ThrowableReturnTime );
			}
		}
		return result;
	}

	public function GetType() : UIInventoryItemWeaponBarsType
	{
		return m_type;
	}

	public function GetItemType() : gamedataItemType
	{
		return m_itemType;
	}

	public function GetComparableBar( barType : WeaponBarType ) : weak< UIInventoryItemWeaponBar >
	{
		var i, limit : Int32;
		var targetGroup : WeaponBarTypeGroup;
		targetGroup = UIInventoryItemWeaponBar.GetBarTypeGroup( barType );
		for( i = 0, limit = Values.Size(); i < limit; i += 1 )
		{
			if( Values[ i ].GetBarTypeGroup() == targetGroup )
			{
				return Values[ i ];
			}
		}
		return NULL;
	}

	private static function CalculateHandling( cycleTime, spreadDefaultX, recoilKickMax, recoilDirection, recoilAngle, swaySide, swayBottom : Float ) : Float
	{
		return 1.0 / ( ( ( 1.0 + ( ( 1.0 + cycleTime ) * spreadDefaultX ) ) + ( ( ( 1.0 + ( recoilKickMax / 5.0 ) ) * ( 1.0 + ( AbsF( recoilDirection ) / 360.0 ) ) ) * ( 1.0 + ( recoilAngle / 90.0 ) ) ) ) + ( 0.1 + ( ( swaySide * swayBottom ) / 90.0 ) ) );
	}

	private static function CalculateStamina( weaponTypeToStaminaCost, magazineCapacity, weaponEvolutionToStaminaCost, firePower : Float ) : Float
	{
		return ( ( weaponTypeToStaminaCost * ( 1.0 / magazineCapacity ) ) * weaponEvolutionToStaminaCost ) * firePower;
	}

	private constexpr static function CalculateMeleeStamina() : Float
	{
		return 0.0;
	}

	private constexpr static function CalculateMeleeReturnTime() : Float
	{
		return 0.0;
	}

}

class UIInventoryItemStat
{
	var Type : gamedataStatType;
	var Value : Float;
	var PropertiesProvider : IUIInventoryItemStatsProvider;
	private var m_properties : UIItemStatProperties;
	private var m_propertiesFetched : Bool;

	public function GetProperties() : weak< UIItemStatProperties >
	{
		if( m_propertiesFetched )
		{
			return m_properties;
		}
		m_properties = PropertiesProvider.Get();
		m_propertiesFetched = true;
		return m_properties;
	}

	public function SetProperties( properties : UIItemStatProperties )
	{
		m_propertiesFetched = true;
		m_properties = properties;
	}

}

abstract class IUIInventoryItemStatsProvider
{

	public virtual function Get() : UIItemStatProperties
	{
		return NULL;
	}

}

class DefaultUIInventoryItemStatsProvider extends IUIInventoryItemStatsProvider
{
	private var m_statType : gamedataStatType;
	private var m_manager : weak< UIInventoryItemsManager >;

	public static function Make( statType : gamedataStatType, optional manager : weak< UIInventoryItemsManager > ) : DefaultUIInventoryItemStatsProvider
	{
		var instance : DefaultUIInventoryItemStatsProvider;
		instance = new DefaultUIInventoryItemStatsProvider;
		instance.m_statType = statType;
		instance.m_manager = manager;
		return instance;
	}

	public override function Get() : UIItemStatProperties
	{
		if( m_manager != NULL )
		{
			return m_manager.GetCachedUIStatProperties( m_statType );
		}
		else
		{
			return UIInventoryItemsManager.GetUIStatProperties( m_statType );
		}
	}

}

enum UIInventoryItemWeaponBarsType
{
	Ranged = 0,
	Melee = 1,
	Throwable = 2,
	CyberwareWeapon = 3,
	CyberwareRangedWeapon = 4,
	InjectorHealing = 5,
	InhalerHealing = 6,
}

