class ItemQuantityPickerController extends inkGameController
{
	protected editable var m_quantityTextMin : inkTextRef;
	protected editable var m_quantityTextMax : inkTextRef;
	protected editable var m_quantityTextChoosen : inkTextRef;
	protected editable var m_priceText : inkTextRef;
	protected editable var m_priceWrapper : inkWidgetRef;
	protected editable var m_weightText : inkTextRef;
	protected editable var m_itemNameText : inkTextRef;
	protected editable var m_itemQuantityText : inkTextRef;
	protected editable var m_rairtyBar : inkWidgetRef;
	protected editable var m_root : inkWidgetRef;
	protected editable var m_background : inkWidgetRef;
	private editable var m_buttonHintsRoot : inkWidgetRef;
	protected editable var m_slider : inkWidgetRef;
	protected editable var m_buttonOk : inkWidgetRef;
	protected editable var m_buttonCancel : inkWidgetRef;
	protected editable var m_buttonOkText : inkTextRef;
	protected editable var m_buttonLess : inkWidgetRef;
	protected editable var m_buttonMore : inkWidgetRef;
	private editable var m_libraryPath : inkWidgetLibraryReference;
	protected var m_maxValue : Int32;
	protected var m_gameData : InventoryItemData;
	protected var m_inventoryItem : weak< UIInventoryItem >;
	protected var m_actionType : QuantityPickerActionType;
	protected var m_sliderController : weak< inkSliderController >;
	protected var m_choosenQuantity : Int32;
	protected var m_itemPrice : Int32;
	protected var m_itemWeight : Float;
	protected var m_isBuyback : Bool;
	protected var m_sendQuantityChangedEvent : Bool;
	private var m_data : QuantityPickerPopupData;
	private var m_isNegativeHovered : Bool;
	private var m_quantityChangedEvent : PickerChoosenQuantityChangedEvent;
	private var m_player : weak< GameObject >;

	protected event OnInitialize()
	{
		m_sliderController = ( ( inkSliderController )( inkWidgetRef.GetController( m_slider ) ) );
		m_player = GetPlayerControlledObject();
		m_player.RegisterInputListener( this, 'mouse_wheel' );
		inkWidgetRef.GetController( m_buttonOk ).RegisterToCallback( 'OnButtonClick', this, 'OnOkClick' );
		inkWidgetRef.GetController( m_buttonCancel ).RegisterToCallback( 'OnButtonClick', this, 'OnCancelClick' );
		inkWidgetRef.GetController( m_buttonCancel ).RegisterToCallback( 'OnHoverOver', this, 'OnNegativeHoverOver' );
		inkWidgetRef.GetController( m_buttonCancel ).RegisterToCallback( 'OnHoverOut', this, 'OnNegativeHoverOut' );
		inkWidgetRef.GetController( m_buttonLess ).RegisterToCallback( 'OnButtonClick', this, 'OnLessClick' );
		inkWidgetRef.GetController( m_buttonMore ).RegisterToCallback( 'OnButtonClick', this, 'OnMoreClick' );
		m_sliderController.GetController().RegisterToCallback( 'OnSliderValueChanged', this, 'OnSliderValueChanged' );
		RegisterToGlobalInputCallback( 'OnPostOnPress', this, 'OnHandlePressInput' );
		RegisterToGlobalInputCallback( 'OnPostOnAxis', this, 'OnAxisInput' );
		RegisterToGlobalInputCallback( 'OnPostOnRepeat', this, 'OnHandleRepeatInput' );
		m_data = ( ( QuantityPickerPopupData )( GetRootWidget().GetUserData( 'QuantityPickerPopupData' ) ) );
		inkWidgetRef.SetVisible( m_root, true );
		inkWidgetRef.SetVisible( m_background, true );
		SetData();
		SetButtonHints();
		PlayLibraryAnimation( 'vendor_quantity_popup_intro' );
	}

	protected event OnUninitialize()
	{
		m_player.UnregisterInputListener( this, 'mouse_wheel' );
		UnregisterFromGlobalInputCallback( 'OnPostOnPress', this, 'OnHandlePressInput' );
		UnregisterFromGlobalInputCallback( 'OnPostOnAxis', this, 'OnAxisInput' );
	}

	protected event OnAction( action : ListenerAction, consumer : ListenerActionConsumer )
	{
		var isPressed, isAxis, isRelative : Bool;
		var delta : Float;
		isPressed = ListenerAction.GetType( action ) == gameinputActionType.BUTTON_PRESSED;
		isAxis = ListenerAction.GetType( action ) == gameinputActionType.AXIS_CHANGE;
		isRelative = ListenerAction.GetType( action ) == gameinputActionType.RELATIVE_CHANGE;
		if( ( isPressed || isAxis ) || isRelative )
		{
			delta = ListenerAction.GetValue( action ) * MaxF( 0.03, 1.29999995 / MaxF( ( ( Float )( m_maxValue ) ), 1.0 ) );
			if( ListenerAction.GetName( action ) == 'mouse_wheel' )
			{
				m_sliderController.ChangeProgress( m_sliderController.GetProgress() + delta );
			}
		}
	}

	private function SetButtonHints()
	{
		AddButtonHints( 'UI_MoveLeft', "UI-PopupNotification-decrease_quantity" );
		AddButtonHints( 'UI_MoveRight', "UI-PopupNotification-increase_quantity" );
		AddButtonHints( 'popup_maxQuantity', "UI-PopupNotification-maximize_quantity" );
		AddButtonHints( 'popup_halveQuantity', "UI-PopupNotification-halve_quantity" );
	}

	private function AddButtonHints( actionName : CName, const label : ref< String > )
	{
		var buttonHint : LabelInputDisplayController;
		buttonHint = ( ( LabelInputDisplayController )( SpawnFromExternal( inkWidgetRef.Get( m_buttonHintsRoot ), inkWidgetLibraryResource.GetPath( m_libraryPath.widgetLibrary ), m_libraryPath.widgetItem ).GetController() ) );
		buttonHint.SetInputActionLabel( actionName, label );
	}

	private function SetData()
	{
		var itemRecord : Item_Record;
		var itemData : gameItemData;
		m_maxValue = m_data.maxValue;
		m_gameData = m_data.gameItemData;
		m_inventoryItem = m_data.inventoryItem;
		m_actionType = m_data.actionType;
		m_isBuyback = m_data.isBuyback;
		m_sendQuantityChangedEvent = m_data.sendQuantityChangedEvent;
		if( m_sendQuantityChangedEvent )
		{
			m_quantityChangedEvent = new PickerChoosenQuantityChangedEvent;
		}
		m_choosenQuantity = 1;
		m_sliderController.Setup( 1.0, ( ( Float )( m_maxValue ) ), ( ( Float )( m_choosenQuantity ) ), 1.0 );
		if( m_inventoryItem )
		{
			itemRecord = m_inventoryItem.GetItemRecord();
			itemData = m_inventoryItem.GetItemData();
		}
		else
		{
			itemRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( InventoryItemData.GetID( m_gameData ) ) );
			itemData = InventoryItemData.GetGameItemData( m_gameData );
		}
		inkTextRef.SetText( m_itemNameText, UIItemsHelper.GetItemName( itemRecord, itemData ) );
		inkTextRef.SetText( m_quantityTextMax, IntToString( m_maxValue ) );
		inkTextRef.SetText( m_quantityTextMin, "1" );
		inkTextRef.SetText( m_quantityTextChoosen, IntToString( m_choosenQuantity ) );
		inkTextRef.SetVisible( m_priceText, ( ( Bool )( m_data.vendor ) ) );
		if( m_data.vendor )
		{
			m_itemPrice = ( ( m_actionType == QuantityPickerActionType.Buy && !( m_isBuyback ) ) ? ( MarketSystem.GetBuyPrice( m_data.vendor, itemData.GetID() ) ) : ( RPGManager.CalculateSellPrice( m_data.vendor.GetGame(), m_data.vendor, itemData.GetID() ) ) );
		}
		m_itemWeight = itemData.GetStatValueByType( gamedataStatType.Weight );
		switch( m_actionType )
		{
			case QuantityPickerActionType.Drop:
				inkTextRef.SetText( m_buttonOkText, "UI-ScriptExports-Drop0" );
			inkWidgetRef.SetVisible( m_priceWrapper, false );
			break;
			case QuantityPickerActionType.Disassembly:
				inkTextRef.SetText( m_buttonOkText, "Gameplay-Devices-DisplayNames-DisassemblableItem" );
			inkWidgetRef.SetVisible( m_priceWrapper, false );
			break;
			case QuantityPickerActionType.Craft:
				inkTextRef.SetText( m_buttonOkText, "UI-Crafting-CraftItem" );
			inkWidgetRef.SetVisible( m_priceWrapper, false );
			break;
			case QuantityPickerActionType.TransferToPlayer:
			case QuantityPickerActionType.TransferToStorage:
				inkWidgetRef.SetVisible( m_priceWrapper, false );
			break;
			default:
				inkTextRef.SetText( m_buttonOkText, "LocKey#22269" );
			inkWidgetRef.SetVisible( m_priceWrapper, true );
		}
		if( m_inventoryItem )
		{
			inkWidgetRef.SetState( m_rairtyBar, m_inventoryItem.GetQualityName() );
		}
		else if( !( InventoryItemData.IsEmpty( m_gameData ) ) )
		{
			inkWidgetRef.SetState( m_rairtyBar, InventoryItemData.GetQuality( m_gameData ) );
		}
		else
		{
			inkWidgetRef.SetState( m_rairtyBar, 'Common' );
		}
		UpdatePriceText();
		UpdateWeight();
		GetRootWidget().SetVisible( true );
	}

	protected function UpdatePriceText()
	{
		if( inkTextRef.IsVisible( m_priceText ) )
		{
			inkTextRef.SetText( m_priceText, IntToString( m_itemPrice * m_choosenQuantity ) );
		}
	}

	protected function UpdateWeight()
	{
		var weight : Float;
		weight = m_itemWeight * ( ( Float )( m_choosenQuantity ) );
		inkTextRef.SetText( m_weightText, FloatToStringPrec( weight, 0 ) );
	}

	protected event OnLessClick( controller : weak< inkButtonController > )
	{
		if( m_choosenQuantity > 1 )
		{
			m_choosenQuantity -= 1;
			UpdateProgress();
		}
	}

	protected event OnMoreClick( controller : weak< inkButtonController > )
	{
		if( m_choosenQuantity < m_maxValue )
		{
			m_choosenQuantity += 1;
			UpdateProgress();
		}
	}

	protected event OnHandlePressInput( evt : inkPointerEvent )
	{
		if( ( evt.IsAction( 'popup_moveRight' ) || evt.IsAction( 'option_switch_next_settings' ) ) && ( m_choosenQuantity < m_maxValue ) )
		{
			m_choosenQuantity += 1;
			UpdateProgress();
		}
		else if( ( evt.IsAction( 'popup_moveLeft' ) || evt.IsAction( 'option_switch_prev_settings' ) ) && ( m_choosenQuantity > 1 ) )
		{
			m_choosenQuantity -= 1;
			UpdateProgress();
		}
		else if( evt.IsAction( 'popup_maxQuantity' ) && ( m_choosenQuantity < m_maxValue ) )
		{
			m_choosenQuantity = m_maxValue;
			UpdateProgress();
		}
		else if( evt.IsAction( 'popup_halveQuantity' ) && ( m_choosenQuantity > 1 ) )
		{
			m_choosenQuantity = ( ( Int32 )( m_choosenQuantity / 2 ) );
			UpdateProgress();
		}
		else if( evt.IsAction( 'one_click_confirm' ) && !( m_isNegativeHovered ) )
		{
			Close( true );
		}
		else if( evt.IsAction( 'cancel' ) )
		{
			Close( false );
		}
	}

	protected event OnNegativeHoverOver( evt : inkPointerEvent )
	{
		m_isNegativeHovered = true;
	}

	protected event OnNegativeHoverOut( evt : inkPointerEvent )
	{
		m_isNegativeHovered = false;
	}

	protected event OnHandleRepeatInput( evt : inkPointerEvent )
	{
		if( ( evt.IsAction( 'popup_moveRight' ) || evt.IsAction( 'option_switch_next_settings' ) ) && ( m_choosenQuantity < m_maxValue ) )
		{
			m_choosenQuantity += 1;
			UpdateProgress();
		}
		else if( ( evt.IsAction( 'popup_moveLeft' ) || evt.IsAction( 'option_switch_prev_settings' ) ) && ( m_choosenQuantity > 1 ) )
		{
			m_choosenQuantity -= 1;
			UpdateProgress();
		}
	}

	protected event OnAxisInput( evt : inkPointerEvent )
	{
		var delta : Float;
		delta = evt.GetAxisData() * MaxF( 0.03, 1.29999995 / MaxF( ( ( Float )( m_maxValue ) ), 1.0 ) );
		if( evt.IsAction( 'popup_axisX_right' ) )
		{
			m_sliderController.ChangeProgress( m_sliderController.GetProgress() + delta );
		}
	}

	protected function UpdateProgress()
	{
		m_sliderController.ChangeProgress( ( ( Float )( ( m_choosenQuantity - 1 ) ) ) / ( ( Float )( ( m_maxValue - 1 ) ) ) );
		inkTextRef.SetText( m_quantityTextChoosen, IntToString( m_choosenQuantity ) );
		UpdatePriceText();
		UpdateWeight();
		if( m_sendQuantityChangedEvent )
		{
			m_quantityChangedEvent.choosenQuantity = m_choosenQuantity;
			m_data.token.TriggerCallback( m_quantityChangedEvent );
		}
	}

	protected event OnOkClick( controller : weak< inkButtonController > )
	{
		Close( true );
	}

	protected event OnCancelClick( controller : weak< inkButtonController > )
	{
		Close( false );
	}

	protected event OnSliderValueChanged( controller : weak< inkSliderController >, progress : Float, value : Float )
	{
		m_choosenQuantity = RoundF( ( ( Float )( ( m_maxValue - 1 ) ) ) * progress ) + 1;
		inkTextRef.SetText( m_quantityTextChoosen, IntToString( m_choosenQuantity ) );
		UpdatePriceText();
		UpdateWeight();
		if( m_sendQuantityChangedEvent )
		{
			m_quantityChangedEvent.choosenQuantity = m_choosenQuantity;
			m_data.token.TriggerCallback( m_quantityChangedEvent );
		}
	}


	private var m_closeData : QuantityPickerPopupCloseData;

	private function Close( success : Bool )
	{
		var closeAnimProxy : inkAnimProxy;
		m_closeData = new QuantityPickerPopupCloseData;
		m_closeData.choosenQuantity = ( ( success ) ? ( m_choosenQuantity ) : ( -1 ) );
		m_closeData.itemData = m_gameData;
		m_closeData.inventoryItem = m_inventoryItem;
		m_closeData.actionType = m_actionType;
		m_closeData.isBuyback = m_isBuyback;
		closeAnimProxy = PlayLibraryAnimation( 'vendor_quantity_popup_outro' );
		closeAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnCloseAnimationFinished' );
	}

	protected event OnCloseAnimationFinished( proxy : inkAnimProxy )
	{
		m_data.token.TriggerCallback( m_closeData );
	}

}

class QuantityPickerPopupData extends inkGameNotificationData
{
	var maxValue : Int32;
	var gameItemData : InventoryItemData;
	var inventoryItem : weak< UIInventoryItem >;
	var actionType : QuantityPickerActionType;
	var vendor : weak< GameObject >;
	var isBuyback : Bool;
	var sendQuantityChangedEvent : Bool;
}

class QuantityPickerPopupCloseData extends inkGameNotificationData
{
	var choosenQuantity : Int32;
	var itemData : InventoryItemData;
	var inventoryItem : weak< UIInventoryItem >;
	var actionType : QuantityPickerActionType;
	var isBuyback : Bool;
}

class PickerChoosenQuantityChangedEvent extends inkGameNotificationData
{
	var choosenQuantity : Int32;
}

enum QuantityPickerActionType
{
	Buy = 0,
	Sell = 1,
	TransferToStorage = 2,
	TransferToPlayer = 3,
	Drop = 4,
	Disassembly = 5,
	Craft = 6,
}

