class UpgradingScreenController extends CraftingMainLogicController
{
	default m_maxIngredientCount = 8;
	private editable var m_itemNameUpgrade : inkTextRef;
	private editable var m_arrowComparison : inkWidgetRef;
	private var m_itemTooltipControllerLeft : weak< AGenericTooltipController >;
	private var m_itemTooltipControllerRight : weak< AGenericTooltipController >;
	private var m_tooltipDataLeft : MinimalItemTooltipData;
	private var m_tooltipDataRight : MinimalItemTooltipData;
	private var m_WeaponAreas : array< gamedataItemType >;
	private var m_EquipAreas : array< gamedataEquipmentArea >;
	private const var DELAYED_TOOLTIP_RIGHT : Float;
	default DELAYED_TOOLTIP_RIGHT = 0.15f;

	public override function Init( craftingGameController : weak< CraftingMainGameController > )
	{
		super.Init( craftingGameController );
		SetCraftingButton( "UI-Crafting-Upgrade" );
		m_EquipAreas = InventoryDataManagerV2.GetInventoryEquipmentAreas();
		m_WeaponAreas = InventoryDataManagerV2.GetInventoryWeaponTypes();
		SpawnItemTooltipAsync( inkWidgetRef.Get( m_tooltipContainer ), this, 'OnItemTooltipSpawnedLeft' );
		SpawnItemTooltipAsync( inkWidgetRef.Get( m_tooltipContainer ), this, 'OnItemTooltipSpawnedRight' );
		m_hasSpawnedTooltip = true;
	}

	public override function RefreshListViewContent( optional inventoryItemData : InventoryItemData )
	{
		m_dataSource.Clear();
		m_dataSource.Reset( GetUpgradableList() );
		if( IsEmptyData() )
		{
			HideContent();
			return;
		}
		if( !( inventoryItemData.Empty ) )
		{
			UpdateItemPreviewPanel( inventoryItemData );
		}
		else
		{
			UpdateItemPreviewPanel( m_selectedItemData );
		}
	}

	private function HideContent()
	{
		inkWidgetRef.SetVisible( m_itemDetailsContainer, false );
		m_isCraftable = false;
		inkTextRef.SetVisible( m_blockedText, !( m_isCraftable ) );
		inkWidgetRef.SetVisible( m_arrowComparison, m_isCraftable );
		inkCompoundRef.SetVisible( m_progressBarContainer, m_isCraftable );
		inkCompoundRef.SetVisible( m_progressButtonContainer, m_isCraftable );
		m_progressButtonController.SetAvaibility( EProgressBarState.Invisible );
	}

	protected override function SetupFilters()
	{
		m_filters.PushBack( ( ( Int32 )( ItemFilterCategory.AllCount ) ) );
		m_filters.PushBack( ( ( Int32 )( ItemFilterCategory.RangedWeapons ) ) );
		m_filters.PushBack( ( ( Int32 )( ItemFilterCategory.MeleeWeapons ) ) );
		super.SetupFilters();
	}

	protected override function UpdateItemPreview( craftableController : CraftableItemLogicController )
	{
		var selectedItem : InventoryItemData;
		m_progressButtonController.Reset();
		selectedItem = ( ( ItemCraftingData )( ( ( IScriptable )( craftableController.GetData() ) ) ) ).inventoryItem;
		UpdateItemPreviewPanel( selectedItem );
	}

	private function UpdateItemPreviewPanel( const selectedItem : ref< InventoryItemData > )
	{
		var itemQuality : gamedataQuality;
		var isMaxed : Bool;
		var buttonState : EProgressBarState;
		itemQuality = RPGManager.GetItemTierForUpgrades( InventoryItemData.GetGameItemData( selectedItem ) );
		isMaxed = IsItemMaxedLevel( itemQuality );
		if( selectedItem.Empty || isMaxed )
		{
			inkWidgetRef.SetVisible( m_itemDetailsContainer, false );
			return;
		}
		inkWidgetRef.SetVisible( m_itemDetailsContainer, true );
		m_selectedItemData = selectedItem;
		m_selectedRecipe = m_craftingSystem.GetUpgradeRecipeData( m_selectedItemData.ID );
		SetupIngredients( m_selectedRecipe.ingredients );
		m_isCraftable = IsUpgradable( m_selectedItemData, true );
		UpdateTooltipData();
		SetItemNames();
		buttonState = ( ( m_isCraftable ) ? ( EProgressBarState.Available ) : ( EProgressBarState.Blocked ) );
		inkTextRef.SetVisible( m_blockedText, !( m_isCraftable ) );
		inkWidgetRef.SetVisible( m_arrowComparison, m_isCraftable );
		m_progressButtonController.SetAvaibility( buttonState );
	}

	private function SetupIngredients( const ingredient : ref< array< IngredientData > > )
	{
		var i, ingredientCount : Int32;
		var controller : weak< IngredientListItemLogicController >;
		ingredientCount = ingredient.Size();
		for( i = 0; i < ingredientCount; i += 1 )
		{
			controller = m_ingredientsControllerList[ i ];
			controller.SetupData( ingredient[ i ], m_tooltipsManager, 1 );
		}
		for( i = ingredientCount; i < m_maxIngredientCount; i += 1 )
		{
			controller = m_ingredientsControllerList[ i ];
			controller.SetUnusedState();
		}
	}

	private function UpdateTooltipData()
	{
		var delayedCall : DelayedTooltipCall;
		var itemQuality : gamedataQuality;
		var isQualityShown : Bool;
		delayedCall = CreateDelayedCall();
		itemQuality = RPGManager.GetItemQuality( InventoryItemData.GetGameItemData( m_selectedItemData ) );
		isQualityShown = IsQualityShown( itemQuality );
		if( m_isCraftable || isQualityShown )
		{
			UpdateTooltipLeft();
			m_DelaySystem.DelayCallback( delayedCall, DELAYED_TOOLTIP_RIGHT, false );
			return;
		}
		else
		{
			HideTooltips();
		}
	}

	private function CreateDelayedCall() : DelayedTooltipCall
	{
		var delay : DelayedTooltipCall;
		delay = new DelayedTooltipCall;
		delay.m_controller = this;
		return delay;
	}

	private function UpdateTooltipLeft()
	{
		m_tooltipDataLeft = m_inventoryManager.GetMinimalTooltipDataForInventoryItem( m_selectedItemData, false, NULL, false );
		m_tooltipDataLeft.displayContext = InventoryTooltipDisplayContext.Upgrading;
		m_itemTooltipControllerLeft.SetData( m_tooltipDataLeft );
	}

	public function UpdateTooltipRightAndShow()
	{
		ApplyQualityModifier( 1.0 );
		m_tooltipDataRight = m_inventoryManager.GetMinimalTooltipDataForInventoryItem( m_selectedItemData, false, NULL, false );
		m_tooltipDataRight.isEquipped = false;
		m_tooltipDataRight.price = ( ( Float )( RPGManager.CalculateSellPriceItemData( m_Game, m_Player, InventoryItemData.GetGameItemData( m_selectedItemData ) ) ) );
		m_tooltipDataRight.displayContext = InventoryTooltipDisplayContext.Upgrading;
		FillBarsComparisonData( m_tooltipDataLeft, m_tooltipDataRight );
		m_itemTooltipControllerRight.SetData( m_tooltipDataRight );
		ApplyQualityModifier( -1.0 );
		ShowTooltips();
	}

	private function ShowTooltips()
	{
		if( m_itemTooltipControllerLeft )
		{
			m_itemTooltipControllerLeft.Show();
		}
		if( m_itemTooltipControllerRight )
		{
			m_itemTooltipControllerRight.Show();
		}
	}

	private function HideTooltips()
	{
		if( m_itemTooltipControllerLeft )
		{
			m_itemTooltipControllerLeft.Hide();
		}
		if( m_itemTooltipControllerRight )
		{
			m_itemTooltipControllerRight.Hide();
		}
	}

	private function FillBarsComparisonData( tooltipDataLeft : MinimalItemTooltipData, tooltipDataRight : MinimalItemTooltipData )
	{
		var statsManagerLeft : weak< UIInventoryItemStatsManager >;
		var statsManagerRight : weak< UIInventoryItemStatsManager >;
		var weaponBarsLeft : weak< UIInventoryItemWeaponBars >;
		var weaponBarsRight : weak< UIInventoryItemWeaponBars >;
		statsManagerLeft = tooltipDataLeft.GetStatsManager();
		statsManagerRight = tooltipDataRight.GetStatsManager();
		weaponBarsLeft = statsManagerLeft.GetWeaponBars();
		weaponBarsRight = statsManagerRight.GetWeaponBars();
		weaponBarsRight.SetComparedBars( weaponBarsLeft );
	}

	private function ApplyQualityModifier( multiplier : Float )
	{
		var itemData : weak< gameItemData >;
		var qualityOld : Float;
		var qualityNew : Float;
		var mod : gameStatModifierData;
		itemData = InventoryItemData.GetGameItemData( m_selectedItemData );
		qualityOld = itemData.GetStatValueByType( gamedataStatType.WasItemUpgraded );
		qualityNew = qualityOld + ( 1.0 * multiplier );
		m_StatsSystem.RemoveAllModifiers( itemData.GetStatsObjectID(), gamedataStatType.WasItemUpgraded, true );
		mod = RPGManager.CreateStatModifier( gamedataStatType.WasItemUpgraded, gameStatModifierType.Additive, qualityNew );
		m_StatsSystem.AddSavedModifier( itemData.GetStatsObjectID(), mod );
	}

	protected event OnItemTooltipSpawnedLeft( widget : inkWidget, userData : IScriptable )
	{
		var tooltipController : AGenericTooltipController;
		tooltipController = ( ( AGenericTooltipController )( widget.GetController() ) );
		tooltipController.Hide();
		m_itemTooltipControllerLeft = tooltipController;
	}

	protected event OnItemTooltipSpawnedRight( widget : inkWidget, userData : IScriptable )
	{
		var tooltipController : AGenericTooltipController;
		tooltipController = ( ( AGenericTooltipController )( widget.GetController() ) );
		tooltipController.Hide();
		m_itemTooltipControllerRight = tooltipController;
	}

	private function SetItemNames()
	{
		var itemQuality : gamedataQuality;
		var isShown : Bool;
		itemQuality = RPGManager.GetItemQuality( InventoryItemData.GetGameItemData( m_selectedItemData ) );
		isShown = IsQualityShown( itemQuality );
		inkTextRef.SetVisible( m_itemName, isShown );
		inkTextRef.SetVisible( m_itemNameUpgrade, false );
		inkTextRef.SetText( m_itemName, m_selectedItemData.Name );
		inkTextRef.SetText( m_itemNameUpgrade, m_selectedRecipe.label );
	}

	private function IsQualityShown( itemQuality : gamedataQuality ) : Bool
	{
		return ( ( ( ( ( ( ( ( itemQuality == gamedataQuality.CommonPlus || itemQuality == gamedataQuality.UncommonPlus ) || itemQuality == gamedataQuality.RarePlus ) || itemQuality == gamedataQuality.EpicPlus ) || itemQuality == gamedataQuality.Common ) || itemQuality == gamedataQuality.Uncommon ) || itemQuality == gamedataQuality.Rare ) || itemQuality == gamedataQuality.Epic ) || itemQuality == gamedataQuality.Legendary ) || itemQuality == gamedataQuality.LegendaryPlus;
	}

	private function IsItemMaxedLevel( itemQuality : gamedataQuality ) : Bool
	{
		return itemQuality == gamedataQuality.LegendaryPlusPlus;
	}

	private function IsLastUpgrade( itemQuality : gamedataQuality ) : Bool
	{
		return itemQuality == gamedataQuality.LegendaryPlus;
	}

	private function SetItemQualities()
	{
		var qualityUpgradeType : gamedataQuality;
		var qualityUpgradeName : CName;
		var qualityNormalName : CName;
		qualityUpgradeType = RPGManager.GetNextItemQuality( InventoryItemData.GetGameItemData( m_selectedItemData ) );
		qualityUpgradeName = UIItemsHelper.QualityEnumToName( qualityUpgradeType );
		qualityNormalName = m_selectedItemData.Quality;
		inkTextRef.SetState( m_itemName, qualityNormalName );
		inkTextRef.SetState( m_itemNameUpgrade, qualityUpgradeName );
	}

	protected event OnHoldFinished( evt : ProgressBarFinishedProccess )
	{
		if( !( m_isPanelOpen ) )
		{
			return false;
		}
		UpgradeItem( m_selectedItemData );
		PlaySound( 'Item', 'OnCrafted' );
		PlayRumble( RumbleStrength.Heavy, RumbleType.Pulse, RumblePosition.Right );
	}

	protected override function SetItemButtonHintsHoverOver( evt : inkPointerEvent )
	{
		if( m_isCraftable )
		{
			m_buttonHintsController.AddButtonHint( 'craft_item', GetLocalizedText( "UI-Crafting-hold_to_upgrade" ) );
		}
	}

	private function GetUpgradableList() : array< IScriptable >
	{
		var i : Int32;
		var itemArrayHolder : array< IScriptable >;
		m_inventoryManager.MarkToRebuild();
		for( i = 0; i < m_WeaponAreas.Size(); i += 1 )
		{
			FillInventoryData( m_inventoryManager.GetPlayerIconicWeaponsByType( m_WeaponAreas[ i ] ), itemArrayHolder );
		}
		return itemArrayHolder;
	}

	private function UpgradeItem( const selectedItemData : ref< InventoryItemData > )
	{
		var upgradeItemRequest : UpgradeItemRequest;
		var itemQuality : gamedataQuality;
		var isEmpty : Bool;
		var isLastUpgrade : Bool;
		itemQuality = RPGManager.GetItemTierForUpgrades( InventoryItemData.GetGameItemData( m_selectedItemData ) );
		isEmpty = IsEmptyData();
		isLastUpgrade = IsLastUpgrade( itemQuality );
		upgradeItemRequest = new UpgradeItemRequest;
		upgradeItemRequest.owner = m_craftingGameController.GetPlayer();
		upgradeItemRequest.itemID = selectedItemData.ID;
		m_craftingSystem.QueueRequest( upgradeItemRequest );
		if( isLastUpgrade && !( isEmpty ) )
		{
			DispatchSelectDelayed( 0 );
		}
	}

	public override function OnChangeTab( isCurrent : Bool )
	{
		super.OnChangeTab( isCurrent );
		m_selectedRecipe = NULL;
	}

	private function FillInventoryData( const itemDataHolder : ref< array< InventoryItemData > >, itemArrayHolder : ref< array< IScriptable > > )
	{
		var itemWrapper : ItemCraftingData;
		var itemData : gameItemData;
		var i : Int32;
		for( i = 0; i < itemDataHolder.Size(); i += 1 )
		{
			itemWrapper = new ItemCraftingData;
			itemWrapper.inventoryItem = itemDataHolder[ i ];
			itemData = InventoryItemData.GetGameItemData( itemDataHolder[ i ] );
			itemWrapper.isUpgradable = IsUpgradable( itemDataHolder[ i ], false );
			itemWrapper.isNew = m_craftingGameController.GetScriptableSystem().IsInventoryItemNew( itemDataHolder[ i ].ID );
			if( !( RPGManager.IsItemMaxTier( itemData ) ) )
			{
				itemArrayHolder.PushBack( itemWrapper );
			}
			m_inventoryManager.GetOrCreateInventoryItemSortData( itemWrapper.inventoryItem, m_craftingGameController.GetScriptableSystem() );
		}
	}

	private function IsUpgradable( const item : ref< InventoryItemData >, sendNotification : Bool ) : Bool
	{
		var canUpgrade : Bool;
		var pl_level, it_level : Int32;
		var playerDevelopmentData : PlayerDevelopmentData;
		var levelParams : inkTextParams;
		var isItemMaxTier : Bool;
		playerDevelopmentData = PlayerDevelopmentSystem.GetData( m_craftingGameController.GetPlayer() );
		pl_level = playerDevelopmentData.GetProficiencyLevel( gamedataProficiencyType.Level );
		it_level = 1;
		canUpgrade = m_craftingSystem.CanItemBeUpgraded( InventoryItemData.GetGameItemData( item ) ) && ( pl_level >= it_level );
		isItemMaxTier = RPGManager.IsItemMaxTier( InventoryItemData.GetGameItemData( item ) );
		if( sendNotification && !( canUpgrade ) )
		{
			if( pl_level < it_level )
			{
				levelParams = new inkTextParams;
				levelParams.AddNumber( "int_0", it_level );
				inkTextRef.SetText( m_blockedText, "LocKey#78455", levelParams );
				m_notificationType = UIMenuNotificationType.UpgradingLevelToLow;
			}
			else if( !( m_craftingSystem.EnoughIngredientsForUpgrading( InventoryItemData.GetGameItemData( item ) ) ) )
			{
				inkTextRef.SetText( m_blockedText, "LocKey#42797" );
				m_notificationType = UIMenuNotificationType.CraftingNotEnoughMaterial;
			}
			else if( isItemMaxTier )
			{
				m_notificationType = UIMenuNotificationType.InventoryActionBlocked;
			}
		}
		return canUpgrade;
	}

}

class DelayedTooltipCall extends DelayCallback
{
	var m_controller : weak< UpgradingScreenController >;

	public override function Call()
	{
		if( m_controller )
		{
			m_controller.UpdateTooltipRightAndShow();
		}
	}

}

