class MinimalItemTooltipData extends ATooltipData
{
	var itemID : ItemID;
	var itemTweakID : TweakDBID;
	var itemData : weak< gameItemData >;
	var transmogItem : ItemID;
	var itemName : String;
	var quality : gamedataQuality;
	var quantity : Int32;
	var description : String;
	var gameplayDescription : String;
	var weight : Float;
	var price : Float;
	var dpsValue : Float;
	var dpsDiff : Float;
	var armorValue : Float;
	var armorDiff : Float;
	var compareDPS : Bool;
	var compareArmor : Bool;
	var comparedQuality : gamedataQuality;
	var qualityF : Float;
	default qualityF = -1.0f;
	var comparisonQualityF : Float;
	default comparisonQualityF = -1.0f;
	var attackSpeed : Float;
	var projectilesPerShot : Float;
	var grenadeData : InventoryTooltiData_GrenadeData;
	var ammoCount : Int32;
	var hasSilencer : Bool;
	var hasScope : Bool;
	var isSilencerInstalled : Bool;
	var isScopeInstalled : Bool;
	var requirements : MinimalItemTooltipDataRequirements;
	var recipeData : MinimalItemTooltipRecipeData;
	var attributeAllocationStats : array< MinimalItemTooltipStatData >;
	var stats : array< MinimalItemTooltipStatData >;
	var mods : array< MinimalItemTooltipModData >;
	var dedicatedMods : array< MinimalItemTooltipModAttachmentData >;
	var cyberwareUpgradeData : InventoryTooltiData_CyberwareUpgradeData;
	var itemType : gamedataItemType;
	default itemType = gamedataItemType.Invalid;
	var itemCategory : gamedataItemCategory;
	var equipmentArea : gamedataEquipmentArea;
	default equipmentArea = gamedataEquipmentArea.Invalid;
	var itemEvolution : gamedataWeaponEvolution;
	default itemEvolution = gamedataWeaponEvolution.Invalid;
	var itemPerkGroup : gamedataPerkWeaponGroupType;
	var lootItemType : LootItemType;
	var iconPath : String;
	var useMaleIcon : Bool;
	var isIconic : Bool;
	var isPlus : Float;
	var isBroken : Bool;
	var isCrafted : Bool;
	var isEquipped : Bool;
	var hasRarity : Bool;
	var displayContextData : ItemDisplayContextData;
	var displayContext : InventoryTooltipDisplayContext;
	var DEBUG_iconErrorInfo : DEBUG_IconErrorInfo;
	private var statsManager : UIInventoryItemStatsManager;
	private var statsManagerFetched : Bool;
	private var managerRef : weak< UIInventoryItemsManager >;

	public constexpr static function FromInventoryItemData( itemData : ref< InventoryItemData > ) : MinimalItemTooltipData
	{
		return NULL;
	}

	public static function FromInventoryTooltipData( tooltipData : InventoryTooltipData ) : MinimalItemTooltipData
	{
		var i : Int32;
		var result : MinimalItemTooltipData;
		var itemRecord : weak< Item_Record >;
		var itemTransmogRecord : weak< Item_Record >;
		var silencerAttachmentSlot, scopeAttachmentSlot : InventoryItemAttachments;
		var attachmentsSize : Int32;
		var attachments : InventoryItemAttachments;
		var manager : weak< UIInventoryItemsManager >;
		if( ( tooltipData == NULL ) || !( ItemID.IsValid( tooltipData.itemID ) ) )
		{
			return NULL;
		}
		result = new MinimalItemTooltipData;
		result.itemID = tooltipData.itemID;
		result.itemTweakID = ItemID.GetTDBID( tooltipData.itemID );
		result.itemData = InventoryItemData.GetGameItemData( tooltipData.inventoryItemData );
		itemRecord = TweakDBInterface.GetItemRecord( result.itemTweakID );
		result.itemCategory = itemRecord.ItemCategory().Type();
		result.itemType = ( ( tooltipData.itemType != gamedataItemType.Invalid ) ? ( tooltipData.itemType ) : ( InventoryItemData.GetItemType( tooltipData.inventoryItemData ) ) );
		result.equipmentArea = InventoryItemData.GetEquipmentArea( tooltipData.inventoryItemData );
		if( result.equipmentArea == gamedataEquipmentArea.Weapon )
		{
			result.itemEvolution = RPGManager.GetWeaponEvolution( result.itemID );
		}
		result.lootItemType = InventoryItemData.GetLootItemType( tooltipData.inventoryItemData );
		result.itemName = UIItemsHelper.GetTooltipItemName( result.itemTweakID, result.itemData, tooltipData.itemName );
		result.comparedQuality = tooltipData.comparedQuality;
		result.isIconic = RPGManager.IsItemIconic( result.itemData );
		result.isPlus = RPGManager.GetItemPlus( result.itemData );
		result.isBroken = RPGManager.IsItemBroken( result.itemData );
		if( tooltipData.overrideRarity )
		{
			result.quality = UIItemsHelper.QualityNameToEnum( StringToName( tooltipData.quality ) );
		}
		else
		{
			result.quality = RPGManager.GetItemDataQuality( result.itemData );
		}
		result.useMaleIcon = InventoryItemData.GetIconGender( tooltipData.inventoryItemData ) == ItemIconGender.Male;
		result.qualityF = UIItemsHelper.GetQualityF( UIItemsHelper.QualityEnumToInt( result.quality ), result.isIconic, result.isPlus );
		result.transmogItem = tooltipData.transmogItem;
		if( ItemID.IsValid( result.transmogItem ) )
		{
			itemTransmogRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( result.transmogItem ) );
			result.iconPath = itemTransmogRecord.IconPath();
		}
		else
		{
			result.iconPath = InventoryItemData.GetIconPath( tooltipData.inventoryItemData );
		}
		if( result.equipmentArea == gamedataEquipmentArea.Weapon || RPGManager.IsItemTypeCyberwareWeapon( result.itemType ) )
		{
			for( i = 0; i < tooltipData.primaryStats.Size(); i += 1 )
			{
				if( tooltipData.primaryStats[ i ].statType == gamedataStatType.EffectiveDPS )
				{
					result.dpsValue = tooltipData.primaryStats[ i ].currentValueF;
					result.dpsDiff = tooltipData.primaryStats[ i ].diffValueF;
				}
			}
			result.attackSpeed = result.itemData.GetStatValueByType( gamedataStatType.AttacksPerSecond );
			result.projectilesPerShot = result.itemData.GetStatValueByType( gamedataStatType.ProjectilesPerShot );
			attachmentsSize = InventoryItemData.GetAttachmentsSize( tooltipData.inventoryItemData );
			for( i = 0; i < attachmentsSize; i += 1 )
			{
				attachments = InventoryItemData.GetAttachment( tooltipData.inventoryItemData, i );
				if( attachments.SlotID == T"AttachmentSlots.PowerModule" )
				{
					silencerAttachmentSlot = attachments;
				}
				else if( attachments.SlotID == T"AttachmentSlots.Scope" )
				{
					scopeAttachmentSlot = attachments;
				}
			}
			if( TDBID.IsValid( silencerAttachmentSlot.SlotID ) )
			{
				result.hasSilencer = true;
				result.isSilencerInstalled = !( InventoryItemData.IsEmpty( silencerAttachmentSlot.ItemData ) );
			}
			if( TDBID.IsValid( scopeAttachmentSlot.SlotID ) )
			{
				result.hasScope = true;
				result.isScopeInstalled = !( InventoryItemData.IsEmpty( scopeAttachmentSlot.ItemData ) );
			}
			result.ammoCount = InventoryItemData.GetAmmo( tooltipData.inventoryItemData );
		}
		else if( result.itemCategory == gamedataItemCategory.Clothing || result.itemCategory == gamedataItemCategory.Cyberware )
		{
			for( i = 0; i < tooltipData.primaryStats.Size(); i += 1 )
			{
				if( tooltipData.primaryStats[ i ].statType == gamedataStatType.Armor )
				{
					result.armorValue = tooltipData.primaryStats[ i ].currentValueF;
					result.armorDiff = tooltipData.primaryStats[ i ].diffValueF;
					break;
				}
			}
		}
		else if( result.itemType == gamedataItemType.Gad_Grenade )
		{
			result.grenadeData = tooltipData.grenadeData;
		}
		result.displayContext = tooltipData.displayContext;
		result.description = tooltipData.description;
		result.gameplayDescription = tooltipData.gameplayDescription;
		result.price = ( ( tooltipData.isVendorItem ) ? ( tooltipData.buyPrice ) : ( tooltipData.price ) );
		result.weight = result.itemData.GetStatValueByType( gamedataStatType.Weight );
		result.isEquipped = tooltipData.isEquipped;
		result.hasRarity = true;
		result.requirements = MinimalItemTooltipData.GetMinimalTooltipDataRequirements( result.itemData, tooltipData );
		if( ( result.displayContext == InventoryTooltipDisplayContext.Crafting && !( result.isIconic ) ) || result.displayContext == InventoryTooltipDisplayContext.Upgrading )
		{
			result.recipeData = new MinimalItemTooltipRecipeData;
			result.recipeData.statsNumber = tooltipData.randomizedStatQuantity;
			result.recipeData.damageTypes = tooltipData.randomDamageTypes;
			result.recipeData.recipeStats = tooltipData.recipeAdditionalStats;
		}
		else if( result.displayContext == InventoryTooltipDisplayContext.Crafting && result.isIconic )
		{
			result.recipeData = new MinimalItemTooltipRecipeData;
			result.recipeData.statsNumber = tooltipData.randomizedStatQuantity;
			result.recipeData.recipeStats = tooltipData.recipeAdditionalStats;
			result.stats = GetSecondaryStatsFromTooltipData( tooltipData, result.itemCategory, true );
		}
		else
		{
			result.stats = GetSecondaryStatsFromTooltipData( tooltipData, result.itemCategory, true );
		}
		result.attributeAllocationStats = GetAttributeAllocationStatsFromTooltipData( tooltipData, true );
		FillModsFromTooltipData( tooltipData, result.mods, result.dedicatedMods );
		manager = tooltipData.GetManager();
		if( manager != NULL )
		{
			result.managerRef = manager;
			result.statsManager = tooltipData.GetStatsManagerHandle();
			result.statsManagerFetched = result.statsManager != NULL;
		}
		result.cyberwareUpgradeData = tooltipData.cyberwareUpgradeData;
		return result;
	}

	private static function ShouldFilterOutGrenadeStat( stat : gamedataStatType ) : Bool
	{
		switch( stat )
		{
			case gamedataStatType.Range:
			case gamedataStatType.BaseDamage:
			case gamedataStatType.PhysicalDamage:
			case gamedataStatType.ChemicalDamage:
			case gamedataStatType.ElectricDamage:
			case gamedataStatType.ThermalDamage:
				return true;
			default:
				return false;
		}
		return false;
	}

	public static function IsAttributeAllocationStat( stat : gamedataStatType ) : Bool
	{
		switch( stat )
		{
			case gamedataStatType.StrengthAllocated:
			case gamedataStatType.ReflexesAllocated:
			case gamedataStatType.IntelligenceAllocated:
			case gamedataStatType.TechnicalAbilityAllocated:
			case gamedataStatType.CoolAllocated:
			case gamedataStatType.HumanityAllocated:
			case gamedataStatType.StrengthAvailable:
			case gamedataStatType.ReflexesAvailable:
			case gamedataStatType.IntelligenceAvailable:
			case gamedataStatType.TechnicalAbilityAvailable:
			case gamedataStatType.CoolAvailable:
			case gamedataStatType.HumanityAvailable:
				return true;
			default:
				return false;
		}
		return false;
	}

	public static function GetSecondaryStatsFromTooltipData( data : InventoryTooltipData, itemCategory : gamedataItemCategory, optional filterZero : Bool ) : array< MinimalItemTooltipStatData >
	{
		var pushedStats : array< gamedataStatType >;
		var result : array< MinimalItemTooltipStatData >;
		var stat : MinimalItemTooltipStatData;
		var statsTweakID : TweakDBID;
		var i : Int32;
		var roundValue : Bool;
		var currentValue : Float;
		for( i = 0; i < data.additionalStats.Size(); i += 1 )
		{
			if( !( pushedStats.Contains( data.additionalStats[ i ].statType ) ) )
			{
				statsTweakID = TDBID.Create( "BaseStats." + EnumValueToString( "gamedataStatType", ( ( Int32 )( data.additionalStats[ i ].statType ) ) ) );
				roundValue = TweakDBInterface.GetBool( statsTweakID + T".roundValue", false );
				currentValue = data.additionalStats[ i ].currentValueF;
				if( filterZero && ( ( roundValue ) ? ( ( RoundF( currentValue ) <= 0 ) ) : ( ( AbsF( currentValue ) <= 0.001 ) ) ) )
				{
					continue;
				}
				if( ( itemCategory != gamedataItemCategory.Part && itemCategory != gamedataItemCategory.WeaponMod ) && data.additionalStats[ i ].statType == gamedataStatType.Armor )
				{
					continue;
				}
				if( data.itemType == gamedataItemType.Gad_Grenade )
				{
					if( ShouldFilterOutGrenadeStat( data.additionalStats[ i ].statType ) )
					{
						continue;
					}
				}
				if( IsAttributeAllocationStat( data.additionalStats[ i ].statType ) )
				{
					continue;
				}
				stat = new MinimalItemTooltipStatData;
				stat.type = data.additionalStats[ i ].statType;
				stat.statName = data.additionalStats[ i ].statName;
				stat.value = currentValue;
				stat.diff = data.additionalStats[ i ].diffValueF;
				stat.decimalPlaces = TweakDBInterface.GetInt( statsTweakID + T".decimalPlaces", 2 );
				stat.displayPercent = TweakDBInterface.GetBool( statsTweakID + T".displayPercent", false );
				stat.displayPlus = TweakDBInterface.GetBool( statsTweakID + T".displayPlus", false );
				stat.inMeters = TweakDBInterface.GetBool( statsTweakID + T".inMeters", false );
				stat.inSeconds = TweakDBInterface.GetBool( statsTweakID + T".inSeconds", false );
				stat.inSpeed = TweakDBInterface.GetBool( statsTweakID + T".inSpeed", false );
				stat.multiplyBy100InText = TweakDBInterface.GetBool( statsTweakID + T".multiplyBy100InText", false );
				stat.roundValue = roundValue;
				stat.flipNegative = TweakDBInterface.GetBool( statsTweakID + T".shouldFlipNegativeValue", false );
				result.PushBack( stat );
				pushedStats.PushBack( stat.type );
			}
		}
		for( i = 0; i < data.comparedStats.Size(); i += 1 )
		{
			if( !( pushedStats.Contains( data.comparedStats[ i ].statType ) ) )
			{
				statsTweakID = TDBID.Create( "BaseStats." + EnumValueToString( "gamedataStatType", ( ( Int32 )( data.comparedStats[ i ].statType ) ) ) );
				roundValue = TweakDBInterface.GetBool( statsTweakID + T".roundValue", false );
				currentValue = data.comparedStats[ i ].currentValueF;
				if( ( itemCategory != gamedataItemCategory.Part && itemCategory != gamedataItemCategory.WeaponMod ) && data.comparedStats[ i ].statType == gamedataStatType.Armor )
				{
					continue;
				}
				if( data.itemType == gamedataItemType.Gad_Grenade )
				{
					if( ShouldFilterOutGrenadeStat( data.comparedStats[ i ].statType ) )
					{
						continue;
					}
				}
				stat = new MinimalItemTooltipStatData;
				stat.type = data.comparedStats[ i ].statType;
				stat.statName = data.comparedStats[ i ].statName;
				stat.value = currentValue;
				stat.diff = data.comparedStats[ i ].diffValueF;
				stat.decimalPlaces = TweakDBInterface.GetInt( statsTweakID + T".decimalPlaces", 2 );
				stat.displayPercent = TweakDBInterface.GetBool( statsTweakID + T".displayPercent", false );
				stat.displayPlus = TweakDBInterface.GetBool( statsTweakID + T".displayPlus", false );
				stat.inMeters = TweakDBInterface.GetBool( statsTweakID + T".inMeters", false );
				stat.inSeconds = TweakDBInterface.GetBool( statsTweakID + T".inSeconds", false );
				stat.inSpeed = TweakDBInterface.GetBool( statsTweakID + T".inSpeed", false );
				stat.multiplyBy100InText = TweakDBInterface.GetBool( statsTweakID + T".multiplyBy100InText", false );
				stat.roundValue = roundValue;
				stat.flipNegative = TweakDBInterface.GetBool( statsTweakID + T".shouldFlipNegativeValue", false );
				result.PushBack( stat );
				pushedStats.PushBack( stat.type );
			}
		}
		return result;
	}

	public static function GetAttributeAllocationStatsFromTooltipData( data : InventoryTooltipData, optional filterZero : Bool ) : array< MinimalItemTooltipStatData >
	{
		var pushedStats : array< gamedataStatType >;
		var result : array< MinimalItemTooltipStatData >;
		var stat : MinimalItemTooltipStatData;
		var statsTweakID : TweakDBID;
		var i : Int32;
		var roundValue : Bool;
		var currentValue : Float;
		for( i = 0; i < data.additionalStats.Size(); i += 1 )
		{
			if( !( IsAttributeAllocationStat( data.additionalStats[ i ].statType ) ) )
			{
				continue;
			}
			if( !( pushedStats.Contains( data.additionalStats[ i ].statType ) ) )
			{
				statsTweakID = TDBID.Create( "BaseStats." + EnumValueToString( "gamedataStatType", ( ( Int32 )( data.additionalStats[ i ].statType ) ) ) );
				roundValue = TweakDBInterface.GetBool( statsTweakID + T".roundValue", false );
				currentValue = data.additionalStats[ i ].currentValueF;
				if( filterZero && ( ( roundValue ) ? ( ( RoundF( currentValue ) <= 0 ) ) : ( ( AbsF( currentValue ) <= 0.001 ) ) ) )
				{
					continue;
				}
				stat = new MinimalItemTooltipStatData;
				stat.type = data.additionalStats[ i ].statType;
				stat.statName = data.additionalStats[ i ].statName;
				stat.value = currentValue;
				stat.diff = data.additionalStats[ i ].diffValueF;
				stat.decimalPlaces = TweakDBInterface.GetInt( statsTweakID + T".decimalPlaces", 2 );
				stat.displayPercent = TweakDBInterface.GetBool( statsTweakID + T".displayPercent", false );
				stat.displayPlus = TweakDBInterface.GetBool( statsTweakID + T".displayPlus", false );
				stat.inMeters = TweakDBInterface.GetBool( statsTweakID + T".inMeters", false );
				stat.inSeconds = TweakDBInterface.GetBool( statsTweakID + T".inSeconds", false );
				stat.inSpeed = TweakDBInterface.GetBool( statsTweakID + T".inSpeed", false );
				stat.multiplyBy100InText = TweakDBInterface.GetBool( statsTweakID + T".multiplyBy100InText", false );
				stat.roundValue = roundValue;
				stat.flipNegative = TweakDBInterface.GetBool( statsTweakID + T".shouldFlipNegativeValue", false );
				result.PushBack( stat );
				pushedStats.PushBack( stat.type );
			}
		}
		for( i = 0; i < data.comparedStats.Size(); i += 1 )
		{
			if( !( IsAttributeAllocationStat( data.comparedStats[ i ].statType ) ) )
			{
				continue;
			}
			if( !( pushedStats.Contains( data.comparedStats[ i ].statType ) ) )
			{
				statsTweakID = TDBID.Create( "BaseStats." + EnumValueToString( "gamedataStatType", ( ( Int32 )( data.comparedStats[ i ].statType ) ) ) );
				roundValue = TweakDBInterface.GetBool( statsTweakID + T".roundValue", false );
				currentValue = data.comparedStats[ i ].currentValueF;
				stat = new MinimalItemTooltipStatData;
				stat.type = data.comparedStats[ i ].statType;
				stat.statName = data.comparedStats[ i ].statName;
				stat.value = currentValue;
				stat.diff = data.comparedStats[ i ].diffValueF;
				stat.decimalPlaces = TweakDBInterface.GetInt( statsTweakID + T".decimalPlaces", 2 );
				stat.displayPercent = TweakDBInterface.GetBool( statsTweakID + T".displayPercent", false );
				stat.displayPlus = TweakDBInterface.GetBool( statsTweakID + T".displayPlus", false );
				stat.inMeters = TweakDBInterface.GetBool( statsTweakID + T".inMeters", false );
				stat.inSeconds = TweakDBInterface.GetBool( statsTweakID + T".inSeconds", false );
				stat.inSpeed = TweakDBInterface.GetBool( statsTweakID + T".inSpeed", false );
				stat.multiplyBy100InText = TweakDBInterface.GetBool( statsTweakID + T".multiplyBy100InText", false );
				stat.roundValue = roundValue;
				stat.flipNegative = TweakDBInterface.GetBool( statsTweakID + T".shouldFlipNegativeValue", false );
				result.PushBack( stat );
				pushedStats.PushBack( stat.type );
			}
		}
		return result;
	}

	public static function FillModsFromTooltipData( data : InventoryTooltipData, mods : ref< array< MinimalItemTooltipModData > >, dedicatedMods : ref< array< MinimalItemTooltipModAttachmentData > > )
	{
		var i, limit : Int32;
		var attachmentData : MinimalItemTooltipModAttachmentData;
		var type : InventoryItemAttachmentType;
		var packages : array< MinimalItemTooltipModData >;
		GetModsDataPackages( InventoryItemData.GetGameItemData( data.inventoryItemData ), TweakDBInterface.GetItemRecord( ItemID.GetTDBID( data.itemID ) ), data.displayContext, data.parentItemData, data.slotID, packages );
		for( i = 0; i < packages.Size(); i += 1 )
		{
			mods.PushBack( packages[ i ] );
		}
		limit = data.itemAttachments.Size();
		for( i = 0; i < limit; i += 1 )
		{
			type = data.itemAttachments[ i ].SlotType;
			attachmentData = GetDefaultModAttachmentData( data, i, type );
			if( type == InventoryItemAttachmentType.Dedicated )
			{
				if( attachmentData != NULL )
				{
					dedicatedMods.PushBack( attachmentData );
				}
			}
			else
			{
				mods.PushBack( attachmentData );
			}
		}
	}

	public static function GetModsDataPackages( itemData : weak< gameItemData >, itemRecord : weak< Item_Record >, displayContext : InventoryTooltipDisplayContext, optional parentItemData : weak< gameItemData >, optional slotID : TweakDBID, mods : ref< array< MinimalItemTooltipModData > > )
	{
		var i : Int32;
		var dataPackages : array< weak< GameplayLogicPackage_Record > >;
		var uiDataPackage : weak< GameplayLogicPackageUIData_Record >;
		var dataPackagesToDisplay : array< weak< GameplayLogicPackageUIData_Record > >;
		var innerItemData : InnerItemData;
		var recordData : MinimalItemTooltipModRecordData;
		var attunementStatRecord : Stat_Record;
		attunementStatRecord = TweakDBInterface.GetStatRecord( T"BaseStats.AttunementHelper" );
		itemRecord.OnEquip( dataPackages );
		for( i = 0; i < dataPackages.Size(); i += 1 )
		{
			uiDataPackage = dataPackages[ i ].UIData();
			if( uiDataPackage && IsStringValid( uiDataPackage.LocalizedDescription() ) )
			{
				dataPackagesToDisplay.PushBack( uiDataPackage );
			}
		}
		dataPackages.Clear();
		itemRecord.OnAttach( dataPackages );
		for( i = 0; i < dataPackages.Size(); i += 1 )
		{
			uiDataPackage = dataPackages[ i ].UIData();
			if( uiDataPackage && IsStringValid( uiDataPackage.LocalizedDescription() ) )
			{
				dataPackagesToDisplay.PushBack( uiDataPackage );
			}
		}
		for( i = 0; i < dataPackagesToDisplay.Size(); i += 1 )
		{
			recordData = new MinimalItemTooltipModRecordData;
			recordData.description = dataPackagesToDisplay[ i ].LocalizedDescription();
			if( dataPackagesToDisplay[ i ].StatsContains( attunementStatRecord ) )
			{
				recordData.attunementData = new MinimalItemTooltipModsAttunementData;
				recordData.attunementData.name = dataPackagesToDisplay[ i ].LocalizedName();
				recordData.attunementData.icon = dataPackagesToDisplay[ i ].IconPath();
			}
			if( displayContext == InventoryTooltipDisplayContext.Attachment )
			{
				innerItemData = InnerItemData();
				parentItemData.GetItemPart( innerItemData, slotID );
				recordData.dataPackage = UILocalizationDataPackage.FromLogicUIDataPackage( dataPackagesToDisplay[ i ], , innerItemData );
			}
			else
			{
				recordData.dataPackage = UILocalizationDataPackage.FromLogicUIDataPackage( dataPackagesToDisplay[ i ], itemData );
			}
			mods.PushBack( recordData );
		}
	}

	private static function GetDefaultModAttachmentData( isEmpty : Bool, qualityName : CName, slotID : TweakDBID, const itemName : ref< String >, abilities : ref< array< InventoryItemAbility > >, type : InventoryItemAttachmentType ) : MinimalItemTooltipModAttachmentData
	{
		var attachmentData : MinimalItemTooltipModAttachmentData;
		var emptySlotName : String;
		if( isEmpty && type == InventoryItemAttachmentType.Dedicated )
		{
			return NULL;
		}
		attachmentData = new MinimalItemTooltipModAttachmentData;
		attachmentData.isEmpty = isEmpty;
		attachmentData.qualityName = qualityName;
		if( !( IsNameValid( attachmentData.qualityName ) ) )
		{
			attachmentData.qualityName = 'Empty';
		}
		if( attachmentData.isEmpty )
		{
			emptySlotName = UIItemsHelper.GetEmptySlotName( slotID );
			attachmentData.slotName = GetLocalizedText( emptySlotName );
			if( !( IsStringValid( attachmentData.slotName ) ) )
			{
				attachmentData.slotName = emptySlotName;
			}
		}
		else
		{
			attachmentData.abilitiesSize = abilities.Size();
			if( attachmentData.abilitiesSize == 0 )
			{
				attachmentData.slotName = itemName;
			}
			else
			{
				attachmentData.abilities = abilities;
			}
		}
		return attachmentData;
	}

	private static function GetDefaultModAttachmentData( data : InventoryTooltipData, index : Int32, type : InventoryItemAttachmentType ) : MinimalItemTooltipModAttachmentData
	{
		var attachmentData : MinimalItemTooltipModAttachmentData;
		var emptySlotName : String;
		var isEmpty : Bool;
		isEmpty = InventoryItemData.IsEmpty( data.itemAttachments[ index ].ItemData );
		if( isEmpty && type == InventoryItemAttachmentType.Dedicated )
		{
			return NULL;
		}
		attachmentData = new MinimalItemTooltipModAttachmentData;
		attachmentData.isEmpty = isEmpty;
		attachmentData.qualityName = InventoryItemData.GetQuality( data.itemAttachments[ index ].ItemData );
		if( !( IsNameValid( attachmentData.qualityName ) ) )
		{
			attachmentData.qualityName = 'Empty';
		}
		if( attachmentData.isEmpty )
		{
			emptySlotName = UIItemsHelper.GetEmptySlotName( data.itemAttachments[ index ].SlotID );
			attachmentData.slotName = GetLocalizedText( emptySlotName );
			if( !( IsStringValid( attachmentData.slotName ) ) )
			{
				attachmentData.slotName = emptySlotName;
			}
		}
		else
		{
			attachmentData.abilitiesSize = InventoryItemData.GetAbilitiesSize( data.itemAttachments[ index ].ItemData );
			if( attachmentData.abilitiesSize == 0 )
			{
				attachmentData.slotName = InventoryItemData.GetName( data.itemAttachments[ index ].ItemData );
			}
			else
			{
				attachmentData.abilities = InventoryItemData.GetAbilities( data.itemAttachments[ index ].ItemData );
			}
		}
		return attachmentData;
	}

	public static function GetMinimalTooltipDataRequirements( itemData : weak< gameItemData >, m_dataManager : InventoryDataManagerV2 ) : MinimalItemTooltipDataRequirements
	{
		return MinimalItemTooltipData.GetMinimalTooltipDataRequirements( itemData, GameInstance.GetPlayerSystem( m_dataManager.GetGame() ).GetLocalPlayerControlledGameObject(), m_dataManager.HasPlayerSmartGunLink(), m_dataManager.GetPlayerStrength(), m_dataManager.GetPlayerReflex(), m_dataManager.GetPlayerLevel() );
	}

	public static function GetMinimalTooltipDataRequirements( itemData : weak< gameItemData >, owner : weak< GameObject >, hasSmartlink : Bool, playerStrength : Int32, playerReflex : Int32, playerLevel : Int32 ) : MinimalItemTooltipDataRequirements
	{
		var result : MinimalItemTooltipDataRequirements;
		var requiredStrength, requiredReflex, requiredLevel : Int32;
		var perkRequiredName : String;
		result = new MinimalItemTooltipDataRequirements;
		result.isSmartlinkRequirementNotMet = RPGManager.HasSmartLinkRequirement( itemData ) && !( hasSmartlink );
		requiredStrength = ( ( Int32 )( itemData.GetStatValueByType( gamedataStatType.Strength ) ) );
		requiredReflex = ( ( Int32 )( itemData.GetStatValueByType( gamedataStatType.Reflexes ) ) );
		requiredLevel = ( ( Int32 )( itemData.GetStatValueByType( gamedataStatType.Level ) ) );
		if( ( requiredLevel > 0 ) && ( playerLevel < requiredLevel ) )
		{
			result.isLevelRequirementNotMet = true;
			result.requiredLevel = requiredLevel;
		}
		if( ( requiredStrength > 0 ) && ( playerStrength < requiredStrength ) )
		{
			result.strengthOrReflexStatName = UILocalizationHelper.GetStatNameLockey( RPGManager.GetStatRecord( gamedataStatType.Strength ) );
			result.strengthOrReflexValue = requiredStrength;
			result.isStrengthRequirementNotMet = true;
		}
		if( ( requiredReflex > 0 ) && ( playerReflex < requiredReflex ) )
		{
			result.strengthOrReflexStatName = UILocalizationHelper.GetStatNameLockey( RPGManager.GetStatRecord( gamedataStatType.Reflexes ) );
			result.strengthOrReflexValue = requiredReflex;
			result.isReflexRequirementNotMet = true;
		}
		if( RPGManager.CheckPerkPrereqs( itemData, owner, perkRequiredName ) )
		{
			result.isPerkRequirementNotMet = true;
			result.perkLocKey = perkRequiredName;
		}
		return result;
	}

	public static function GetMinimalTooltipDataRequirements( itemData : weak< gameItemData >, tooltipData : InventoryTooltipData ) : MinimalItemTooltipDataRequirements
	{
		var result : MinimalItemTooltipDataRequirements;
		var resultStat : MinimalItemTooltipDataStatRequirement;
		var requiredStrength, requiredReflex, requiredLevel : Int32;
		var i : Int32;
		var requirement : SItemStackRequirementData;
		var requirements : array< SItemStackRequirementData >;
		var statRecord : Stat_Record;
		var perkRequiredName : String;
		var player : weak< PlayerPuppet >;
		result = new MinimalItemTooltipDataRequirements;
		result.isSmartlinkRequirementNotMet = RPGManager.HasSmartLinkRequirement( itemData ) && !( tooltipData.m_HasPlayerSmartGunLink );
		requiredStrength = ( ( Int32 )( itemData.GetStatValueByType( gamedataStatType.Strength ) ) );
		requiredReflex = ( ( Int32 )( itemData.GetStatValueByType( gamedataStatType.Reflexes ) ) );
		requiredLevel = ( ( Int32 )( itemData.GetStatValueByType( gamedataStatType.Level ) ) );
		if( ( requiredLevel > 0 ) && ( tooltipData.m_PlayerLevel < requiredLevel ) )
		{
			result.isLevelRequirementNotMet = true;
			result.requiredLevel = requiredLevel;
		}
		if( ( requiredStrength > 0 ) && ( tooltipData.m_PlayerStrenght < requiredStrength ) )
		{
			result.strengthOrReflexStatName = UILocalizationHelper.GetStatNameLockey( RPGManager.GetStatRecord( gamedataStatType.Strength ) );
			result.strengthOrReflexValue = requiredStrength;
			result.isStrengthRequirementNotMet = true;
		}
		if( ( requiredReflex > 0 ) && ( tooltipData.m_PlayerReflexes < requiredReflex ) )
		{
			result.strengthOrReflexStatName = UILocalizationHelper.GetStatNameLockey( RPGManager.GetStatRecord( gamedataStatType.Reflexes ) );
			result.strengthOrReflexValue = requiredReflex;
			result.isReflexRequirementNotMet = true;
		}
		if( !( InventoryItemData.IsEmpty( tooltipData.inventoryItemData ) ) )
		{
			requirement = InventoryItemData.GetRequirement( tooltipData.inventoryItemData );
			if( requirement.statType != gamedataStatType.Invalid && !( InventoryItemData.IsRequirementMet( tooltipData.inventoryItemData ) ) )
			{
				result.isAnyStatRequirementNotMet = true;
				resultStat = new MinimalItemTooltipDataStatRequirement;
				resultStat.statValue = RoundF( requirement.requiredValue );
				statRecord = RPGManager.GetStatRecord( requirement.statType );
				resultStat.statName = GetLocalizedText( UILocalizationHelper.GetStatNameLockey( statRecord ) );
				resultStat.statColor = "StatTypeColor." + EnumValueToString( "gamedataStatType", ( ( Int32 )( requirement.statType ) ) );
				resultStat.statLocKey = "LocKey#49215";
				result.anyStatRequirements.PushBack( resultStat );
			}
			player = tooltipData.GetManager().GetAttachedPlayer();
			if( ( player && tooltipData.isPerkRequired ) && RPGManager.CheckPerkPrereqs( itemData, player, perkRequiredName ) )
			{
				result.isPerkRequirementNotMet = true;
				result.perkLocKey = tooltipData.perkRequiredName;
			}
			if( InventoryItemData.GetItemType( tooltipData.inventoryItemData ) == gamedataItemType.Cyb_HealingAbility && tooltipData.category == "Cyberware" )
			{
				requirements = InventoryItemData.GetEquipRequirements( tooltipData.inventoryItemData );
				for( i = 0; i < requirements.Size(); i += 1 )
				{
					if( requirements[ i ].statType == gamedataStatType.HumanityAvailable )
					{
						resultStat = new MinimalItemTooltipDataStatRequirement;
						resultStat.statValue = RoundF( requirements[ i ].requiredValue );
						resultStat.statName = GetLocalizedText( "LocKey#88304" );
						resultStat.statLocKey = "LocKey#88304";
						result.anyStatRequirements.PushBack( resultStat );
					}
				}
			}
		}
		if( !( InventoryItemData.IsEquippable( tooltipData.inventoryItemData ) ) )
		{
			result.isAnyStatRequirementNotMet = true;
			requirements = InventoryItemData.GetEquipRequirements( tooltipData.inventoryItemData );
			for( i = 0; i < requirements.Size(); i += 1 )
			{
				if( requirements[ i ].statType == gamedataStatType.HumanityAvailable )
				{
					result.isHumanityStatRequirementNotMet = true;
				}
			}
			requirement = InventoryItemData.GetEquipRequirement( tooltipData.inventoryItemData );
			if( requirement.statType != gamedataStatType.Invalid )
			{
				requirements.PushBack( requirement );
			}
			for( i = 0; i < requirements.Size(); i += 1 )
			{
				resultStat = new MinimalItemTooltipDataStatRequirement;
				resultStat.statValue = RoundF( requirements[ i ].requiredValue );
				statRecord = RPGManager.GetStatRecord( requirements[ i ].statType );
				resultStat.statName = GetLocalizedText( UILocalizationHelper.GetStatNameLockey( statRecord ) );
				resultStat.statColor = "StatTypeColor." + EnumValueToString( "gamedataStatType", ( ( Int32 )( requirements[ i ].statType ) ) );
				if( IsAttributeAllocationStat( requirements[ i ].statType ) )
				{
					resultStat.statLocKey = "LocKey#80932";
				}
				else
				{
					resultStat.statLocKey = "LocKey#77652";
				}
				result.anyStatRequirements.PushBack( resultStat );
			}
			requirement = InventoryItemData.GetEquipRequirement( tooltipData.inventoryItemData );
		}
		result.isRarityRequirementNotMet = InventoryItemData.IsPart( tooltipData.inventoryItemData ) && !( InventoryItemData.IsRequirementMet( tooltipData.inventoryItemData ) );
		return result;
	}

	public static function GetSecondaryStatsForStatMap( itemData : weak< gameItemData >, itemType : gamedataItemType, itemCategory : gamedataItemCategory ) : array< MinimalItemTooltipStatData >
	{
		var i, limit : Int32;
		var statsMap : weak< UIStatsMap_Record >;
		var secondaryStats : array< weak< Stat_Record > >;
		var result : array< MinimalItemTooltipStatData >;
		var statData : MinimalItemTooltipStatData;
		var statId : TweakDBID;
		var statValue : Float;
		var statType : gamedataStatType;
		statsMap = TDB.GetUIStatsMapRecord( TDBID.Create( "UIMaps." + EnumValueToString( "gamedataItemType", ( ( Int32 )( itemType ) ) ) ) );
		if( statsMap )
		{
			statsMap.SecondaryStats( secondaryStats );
			for( i = 0, limit = secondaryStats.Size(); i < limit; i += 1 )
			{
				statType = secondaryStats[ i ].StatType();
				if( itemCategory == gamedataItemCategory.Clothing && statType == gamedataStatType.Armor )
				{
					continue;
				}
				if( IsAttributeAllocationStat( statType ) )
				{
					continue;
				}
				if( itemType == gamedataItemType.Gad_Grenade )
				{
					if( ShouldFilterOutGrenadeStat( statType ) )
					{
						continue;
					}
				}
				statValue = itemData.GetStatValueByType( statType );
				statId = secondaryStats[ i ].GetID();
				statData.roundValue = TweakDBInterface.GetBool( statId + T".roundValue", false );
				if( ( ( statData.roundValue ) ? ( RoundF( statValue ) > 0 ) : ( AbsF( statValue ) > 0.001 ) ) )
				{
					statData = new MinimalItemTooltipStatData;
					statData.statName = secondaryStats[ i ].LocalizedName();
					statData.value = statValue;
					statData.type = statType;
					statData.decimalPlaces = TweakDBInterface.GetInt( statId + T".decimalPlaces", 2 );
					statData.displayPercent = TweakDBInterface.GetBool( statId + T".displayPercent", false );
					statData.displayPlus = TweakDBInterface.GetBool( statId + T".displayPlus", false );
					statData.inMeters = TweakDBInterface.GetBool( statId + T".inMeters", false );
					statData.inSeconds = TweakDBInterface.GetBool( statId + T".inSeconds", false );
					statData.inSpeed = TweakDBInterface.GetBool( statId + T".inSpeed", false );
					statData.multiplyBy100InText = TweakDBInterface.GetBool( statId + T".multiplyBy100InText", false );
					statData.flipNegative = TweakDBInterface.GetBool( statId + T".shouldFlipNegativeValue", false );
					result.PushBack( statData );
				}
			}
		}
		return result;
	}

	public function SetManager( manager : weak< UIInventoryItemsManager > )
	{
		managerRef = manager;
	}

	public function GetStatsManager( optional refetch : Bool ) : weak< UIInventoryItemStatsManager >
	{
		var record : weak< UIStatsMap_Record >;
		if( statsManagerFetched && !( refetch ) )
		{
			return statsManager;
		}
		record = UIInventoryItemsManager.GetUIStatsMap( itemType );
		statsManager = UIInventoryItemStatsManager.Make( itemData, record, managerRef );
		statsManagerFetched = true;
		return statsManager;
	}

	public function GetStatsManagerPure( optional refetch : Bool ) : weak< UIInventoryItemStatsManager >
	{
		return statsManager;
	}

}

class MinimalItemTooltipDataRequirements
{
	var isLevelRequirementNotMet : Bool;
	var isSmartlinkRequirementNotMet : Bool;
	var isStrengthRequirementNotMet : Bool;
	var isReflexRequirementNotMet : Bool;
	var isAnyStatRequirementNotMet : Bool;
	var isHumanityStatRequirementNotMet : Bool;
	var isPerkRequirementNotMet : Bool;
	var isRarityRequirementNotMet : Bool;
	var strengthOrReflexStatName : String;
	var perkLocKey : String;
	var strengthOrReflexValue : Int32;
	var requiredLevel : Int32;
	var anyStatRequirements : array< MinimalItemTooltipDataStatRequirement >;
}

class MinimalItemTooltipDataStatRequirement
{
	var statName : String;
	var statColor : String;
	var statLocKey : String;
	var statValue : Int32;
}

class MinimalItemTooltipRecipeData
{
	var statsNumber : Int32;
	var damageTypes : array< InventoryTooltipData_StatData >;
	var recipeStats : array< InventoryTooltipData_StatData >;
}

class MinimalItemTooltipStatData
{
	var value : Float;
	var diff : Float;
	var statName : String;
	var type : gamedataStatType;
	var decimalPlaces : Int32;
	var displayPercent : Bool;
	var displayPlus : Bool;
	var inMeters : Bool;
	var inSeconds : Bool;
	var inSpeed : Bool;
	var multiplyBy100InText : Bool;
	var roundValue : Bool;
	var flipNegative : Bool;
}

class MinimalItemTooltipModData
{
}

class MinimalItemTooltipModRecordData extends MinimalItemTooltipModData
{
	var dataPackage : UILocalizationDataPackage;
	var description : String;
	var attunementData : MinimalItemTooltipModsAttunementData;
}

class MinimalItemTooltipModsAttunementData
{
	var name : String;
	var icon : CName;
}

class MinimalItemTooltipModAttachmentData extends MinimalItemTooltipModData
{
	var isEmpty : Bool;
	var slotName : String;
	var qualityName : CName;
	var abilitiesSize : Int32;
	var abilities : array< InventoryItemAbility >;
}

