class RipperdocTokenPopupData extends inkGameNotificationData
{
	var costData : CyberwareUpgradeCostData;
	var baseItemData : UIInventoryItem;
	var option1InventoryItem : UIInventoryItem;
	var option2InventoryItem : UIInventoryItem;
	var option3InventoryItem : UIInventoryItem;
	var cyberwareUpgradeData : InventoryTooltiData_CyberwareUpgradeData;
	var displayContext : ItemDisplayContextData;
	var option1GameItemData : gameItemData;
	var option2GameItemData : gameItemData;
	var option3GameItemData : gameItemData;
	var option1SideItemData : gameItemData;
	var option2SideItemData : gameItemData;
	var option3SideItemData : gameItemData;
}

class RipperdocTokenPopupCloseData extends inkGameNotificationData
{
	var confirm : Bool;
	var chosenOptionIndex : Int32;
	var chosenOptionData : gameItemData;
	var costData : CyberwareUpgradeCostData;
}

struct CyberwareUpgradeCostData
{
	var materialRecordID : TweakDBID;
	var materialCount : Int32;
	var moneyRequired : Int32;
}

class RipperdocTokenPopup extends inkGameController
{
	[ category = "Upgrade options" ]
	private editable var m_optionRef : inkWidgetRef[ 4 ];
	[ category = "Upgrade options" ]
	private editable var m_optionTooltipParent : inkWidgetRef[ 4 ];
	[ category = "Upgrade options" ]
	private editable var m_option1ProgressBarRef : inkWidgetRef;
	[ category = "Upgrade options" ]
	private editable var m_option2ProgressBarRef : inkWidgetRef;
	[ category = "Upgrade options" ]
	private editable var m_option3ProgressBarRef : inkWidgetRef;
	[ category = "Upgrade options" ]
	private editable var m_option1HoverZone : inkWidgetRef;
	[ category = "Upgrade options" ]
	private editable var m_option2HoverZone : inkWidgetRef;
	[ category = "Upgrade options" ]
	private editable var m_option3HoverZone : inkWidgetRef;
	[ category = "Upgrade options" ]
	private editable var m_progressEffectName : CName;
	default m_progressEffectName = 'progress';
	[ category = "Upgrade Button" ]
	private editable var m_option1UpgradeBtnAnchor : inkWidgetRef;
	[ category = "Upgrade Button" ]
	private editable var m_option2UpgradeBtnAnchor : inkWidgetRef;
	[ category = "Upgrade Button" ]
	private editable var m_option3UpgradeBtnAnchor : inkWidgetRef;
	[ category = "Upgrade Button" ]
	private editable var m_upgradeBtnContainerRef : inkWidgetRef;
	[ category = "Upgrade Button" ]
	private editable var m_upgradeButtonLabelKey : String;
	[ category = "Upgrade Button" ]
	private editable var m_upgradeButtonAnimDuration : Float;
	default m_upgradeButtonAnimDuration = 0.3f;
	[ category = "Upgrade Button" ]
	private editable var m_upgradeButtonResRef : ResRef;
	default m_upgradeButtonResRef = R"base\gameplay\gui\common\tooltip\cyberware_tooltip_modules.inkwidget";
	[ category = "Upgrade Button" ]
	private editable var m_upgradeButtonResName : CName;
	default m_upgradeButtonResName = 'itemCyberwareUpgrade';
	[ tooltip = "Intro animation without choices (no Connoisseur perk)" ][ category = "Animations" ]
	private editable var m_noChoiceIntroAnimName : CName;
	[ tooltip = "Intro animation with 2 choices (Connoisseur perk, low level CW)" ][ category = "Animations" ]
	private editable var m_twoChoiceIntroAnimName : CName;
	[ tooltip = "Intro animation with 3 choices (Connoisseur perk, high level CW)" ][ category = "Animations" ]
	private editable var m_threeChoiceIntroAnimName : CName;
	[ tooltip = "Outro animation without choices (no Connoisseur perk)" ][ category = "Animations" ]
	private editable var m_noChoiceOutroAnimName : CName;
	[ tooltip = "Outro animation for 1st choice with 2 choices (Connoisseur perk, low level CW)" ][ category = "Animations" ]
	private editable var m_twoChoice1OutroAnimName : CName;
	[ tooltip = "Outro animation for 2nd choice with 2 choices (Connoisseur perk, low level CW)" ][ category = "Animations" ]
	private editable var m_twoChoice2OutroAnimName : CName;
	[ tooltip = "Outro animation for 1st choice with 3 choices (Connoisseur perk, high level CW)" ][ category = "Animations" ]
	private editable var m_threeChoice1OutroAnimName : CName;
	[ tooltip = "Outro animation for 2nd choice with 3 choices (Connoisseur perk, high level CW)" ][ category = "Animations" ]
	private editable var m_threeChoice2OutroAnimName : CName;
	[ tooltip = "Outro animation for 3rd choice with 3 choices (Connoisseur perk, high level CW)" ][ category = "Animations" ]
	private editable var m_threeChoice3OutroAnimName : CName;
	[ category = "Input" ]
	private editable var m_holdInputName : CName;
	[ category = "Input" ]
	private editable var m_exitInputName : CName;
	default m_exitInputName = 'close_popup';
	[ category = "Input" ]
	private editable var m_buttonHintsRoot : inkWidgetRef;
	[ category = "Tooltip" ]
	private editable var m_itemToolitpResRef : ResRef;
	default m_itemToolitpResRef = R"base\gameplay\gui\common\tooltip\itemtooltip.inkwidget";
	[ category = "Tooltip" ]
	private editable var m_itemTooltipName : CName;
	default m_itemTooltipName = 'itemTooltip';
	[ category = "Tooltip" ]
	private editable var m_cyberdeckToolitpResRef : ResRef;
	default m_cyberdeckToolitpResRef = R"base\gameplay\gui\common\tooltip\cyberdecktooltip.inkwidget";
	[ category = "Tooltip" ]
	private editable var m_cyberdeckTooltipName : CName;
	default m_cyberdeckTooltipName = 'cyberdeckTooltip';
	private var m_toolitpWidgetRef : ResRef;
	private var m_tooltipName : CName;
	private var m_itemTooltipController0 : weak< AGenericTooltipController >;
	private var m_itemTooltipController1 : weak< AGenericTooltipController >;
	private var m_itemTooltipController2 : weak< AGenericTooltipController >;
	private var m_itemTooltipController3 : weak< AGenericTooltipController >;
	private var m_itemTooltipCyberwareUpgrade : weak< ItemTooltipCyberwareUpgradeController >;
	private var m_option1ProgressBar : weak< inkWidget >;
	private var m_option2ProgressBar : weak< inkWidget >;
	private var m_option3ProgressBar : weak< inkWidget >;
	private var m_audioSystem : weak< AudioSystem >;
	private var m_data : RipperdocTokenPopupData;
	private var m_multichoice : Bool;
	private var m_thirdChoiceAvailable : Bool;
	private var m_progressStarted : Bool;
	private var m_introAnimationPlaying : Bool;
	private var m_choicesAnimProxy : inkAnimProxy;
	private var m_buttonAnimProxy : inkAnimProxy;
	private var m_currentOption : Int32;
	private var m_choice : Int32;
	default m_choice = -1;
	private var m_result : Bool;
	private var m_inputListenersRegistered : Bool;

	protected event OnInitialize()
	{
		var player : weak< GameObject >;
		player = GetPlayerControlledObject();
		m_audioSystem = GameInstance.GetAudioSystem( player.GetGame() );
		RegisterToGlobalInputCallback( 'OnPostOnPress', this, 'OnPressInput' );
		RegisterToGlobalInputCallback( 'OnPostOnRelease', this, 'OnInputRelease' );
		m_data = ( ( RipperdocTokenPopupData )( GetRootWidget().GetUserData( 'RipperdocTokenPopupData' ) ) );
		if( ( m_data.option1GameItemData.HasTag( 'Cyberdeck' ) || m_data.option2GameItemData.HasTag( 'Cyberdeck' ) ) || m_data.option3GameItemData.HasTag( 'Cyberdeck' ) )
		{
			m_toolitpWidgetRef = m_cyberdeckToolitpResRef;
			m_tooltipName = m_cyberdeckTooltipName;
		}
		else
		{
			m_toolitpWidgetRef = m_itemToolitpResRef;
			m_tooltipName = m_itemTooltipName;
		}
		m_itemTooltipController0 = ( ( AGenericTooltipController )( SpawnFromExternal( inkWidgetRef.Get( m_optionTooltipParent[ 0 ] ), m_toolitpWidgetRef, m_tooltipName ).GetController() ) );
		m_itemTooltipController1 = ( ( AGenericTooltipController )( SpawnFromExternal( inkWidgetRef.Get( m_optionTooltipParent[ 1 ] ), m_toolitpWidgetRef, m_tooltipName ).GetController() ) );
		inkWidgetRef.SetVisible( m_upgradeBtnContainerRef, false );
		m_itemTooltipCyberwareUpgrade = ( ( ItemTooltipCyberwareUpgradeController )( SpawnFromExternal( inkWidgetRef.Get( m_upgradeBtnContainerRef ), m_upgradeButtonResRef, m_upgradeButtonResName ).GetController() ) );
		m_itemTooltipCyberwareUpgrade.UpdateData( m_data.cyberwareUpgradeData );
		m_itemTooltipCyberwareUpgrade.ReplaceLabelText( GetLocalizedText( m_upgradeButtonLabelKey ) );
		m_option1ProgressBar = inkWidgetRef.Get( m_option1ProgressBarRef );
		if( m_data.option2GameItemData )
		{
			m_itemTooltipController2 = ( ( AGenericTooltipController )( SpawnFromExternal( inkWidgetRef.Get( m_optionTooltipParent[ 2 ] ), m_toolitpWidgetRef, m_tooltipName ).GetController() ) );
			m_option2ProgressBar = inkWidgetRef.Get( m_option2ProgressBarRef );
			m_multichoice = true;
		}
		else
		{
			inkWidgetRef.SetVisible( m_optionRef[ 2 ], false );
			inkWidgetRef.SetVisible( m_option2HoverZone, false );
		}
		if( m_data.option3GameItemData )
		{
			m_itemTooltipController3 = ( ( AGenericTooltipController )( SpawnFromExternal( inkWidgetRef.Get( m_optionTooltipParent[ 3 ] ), m_toolitpWidgetRef, m_tooltipName ).GetController() ) );
			m_option3ProgressBar = inkWidgetRef.Get( m_option3ProgressBarRef );
			m_multichoice = true;
			m_thirdChoiceAvailable = true;
			inkWidgetRef.SetSize( m_option1HoverZone, 1965.0, 400.0 );
			inkWidgetRef.SetSize( m_option2HoverZone, 805.0, 400.0 );
		}
		else
		{
			inkWidgetRef.SetVisible( m_optionRef[ 3 ], false );
			inkWidgetRef.SetVisible( m_option3HoverZone, false );
			m_thirdChoiceAvailable = false;
			inkWidgetRef.SetSize( m_option1HoverZone, 2365.0, 400.0 );
			inkWidgetRef.SetSize( m_option2HoverZone, 1495.0, 400.0 );
		}
		SetTooltipsData();
		if( m_multichoice )
		{
			inkWidgetRef.RegisterToCallback( m_option1HoverZone, 'OnHoverOver', this, 'OnOption1HoverOver' );
			inkWidgetRef.RegisterToCallback( m_option2HoverZone, 'OnHoverOver', this, 'OnOption2HoverOver' );
			inkWidgetRef.RegisterToCallback( m_option3HoverZone, 'OnHoverOver', this, 'OnOption3HoverOver' );
			inkWidgetRef.RegisterToCallback( m_option1HoverZone, 'OnHoverOut', this, 'OnOptionOnHoverOut' );
			inkWidgetRef.RegisterToCallback( m_option2HoverZone, 'OnHoverOut', this, 'OnOptionOnHoverOut' );
			inkWidgetRef.RegisterToCallback( m_option3HoverZone, 'OnHoverOut', this, 'OnOptionOnHoverOut' );
			inkWidgetRef.RegisterToCallback( m_option1HoverZone, 'OnPress', this, 'OnOption1Press' );
			inkWidgetRef.RegisterToCallback( m_option2HoverZone, 'OnPress', this, 'OnOption2Press' );
			inkWidgetRef.RegisterToCallback( m_option3HoverZone, 'OnPress', this, 'OnOption3Press' );
			inkWidgetRef.RegisterToCallback( m_option1HoverZone, 'OnHold', this, 'OnOption1Hold' );
			inkWidgetRef.RegisterToCallback( m_option2HoverZone, 'OnHold', this, 'OnOption2Hold' );
			inkWidgetRef.RegisterToCallback( m_option3HoverZone, 'OnHold', this, 'OnOption3Hold' );
			m_choicesAnimProxy = PlayLibraryAnimation( ( ( m_thirdChoiceAvailable ) ? ( m_threeChoiceIntroAnimName ) : ( m_twoChoiceIntroAnimName ) ) );
		}
		else
		{
			RegisterToGlobalInputCallback( 'OnPostOnPress', this, 'OnOption1Press' );
			RegisterToGlobalInputCallback( 'OnPostOnHold', this, 'OnOption1Hold' );
			inkWidgetRef.SetState( m_optionRef[ 1 ], 'Hover' );
			inkWidgetRef.SetVisible( m_option1HoverZone, false );
			m_choicesAnimProxy = PlayLibraryAnimation( m_noChoiceIntroAnimName );
		}
		m_choicesAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnIntroFinished' );
		m_currentOption = 1;
		m_introAnimationPlaying = true;
		m_inputListenersRegistered = true;
		m_progressStarted = false;
	}

	protected event OnIntroFinished( anim : inkAnimProxy )
	{
		var targetBtnAnchor : inkWidgetRef;
		switch( m_currentOption )
		{
			case 1:
				targetBtnAnchor = m_option1UpgradeBtnAnchor;
			break;
			case 2:
				targetBtnAnchor = m_option2UpgradeBtnAnchor;
			break;
			case 3:
				targetBtnAnchor = m_option3UpgradeBtnAnchor;
			break;
			default:
				targetBtnAnchor = m_option1UpgradeBtnAnchor;
			break;
		}
		MoveButtonToOption( m_upgradeBtnContainerRef, targetBtnAnchor, true );
		inkWidgetRef.SetState( m_optionRef[ Clamp( m_currentOption, 1, 3 ) ], 'Hover' );
		inkWidgetRef.SetVisible( m_upgradeBtnContainerRef, true );
		SetButtonHints();
		m_choicesAnimProxy.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnIntorFinished' );
		m_introAnimationPlaying = false;
	}

	protected event OnUninitialize()
	{
		UnregisterInputListeners();
	}

	private function UnregisterInputListeners()
	{
		if( m_inputListenersRegistered )
		{
			UnregisterFromGlobalInputCallback( 'OnPostOnPress', this, 'OnPressInput' );
			UnregisterFromGlobalInputCallback( 'OnPostOnRelease', this, 'OnInputRelease' );
			if( m_multichoice )
			{
				inkWidgetRef.UnregisterFromCallback( m_option1HoverZone, 'OnHoverOver', this, 'OnOption1HoverOver' );
				inkWidgetRef.UnregisterFromCallback( m_option2HoverZone, 'OnHoverOver', this, 'OnOption2HoverOver' );
				inkWidgetRef.UnregisterFromCallback( m_option3HoverZone, 'OnHoverOver', this, 'OnOption3HoverOver' );
				inkWidgetRef.UnregisterFromCallback( m_option1HoverZone, 'OnHoverOut', this, 'OnOptionOnHoverOut' );
				inkWidgetRef.UnregisterFromCallback( m_option2HoverZone, 'OnHoverOut', this, 'OnOptionOnHoverOut' );
				inkWidgetRef.UnregisterFromCallback( m_option3HoverZone, 'OnHoverOut', this, 'OnOptionOnHoverOut' );
				inkWidgetRef.UnregisterFromCallback( m_option1HoverZone, 'OnPress', this, 'OnOption1Press' );
				inkWidgetRef.UnregisterFromCallback( m_option2HoverZone, 'OnPress', this, 'OnOption2Press' );
				inkWidgetRef.UnregisterFromCallback( m_option3HoverZone, 'OnPress', this, 'OnOption3Press' );
				inkWidgetRef.UnregisterFromCallback( m_option1HoverZone, 'OnHold', this, 'OnOption1Hold' );
				inkWidgetRef.UnregisterFromCallback( m_option2HoverZone, 'OnHold', this, 'OnOption2Hold' );
				inkWidgetRef.UnregisterFromCallback( m_option3HoverZone, 'OnHold', this, 'OnOption3Hold' );
			}
			else
			{
				UnregisterFromGlobalInputCallback( 'OnPostOnPress', this, 'OnOption1Press' );
				UnregisterFromGlobalInputCallback( 'OnPostOnHold', this, 'OnOption1Hold' );
			}
			m_inputListenersRegistered = false;
			inkWidgetRef.SetVisible( m_buttonHintsRoot, false );
		}
	}

	private function SetTooltipsData()
	{
		var tooltipWrapper : UIInventoryItemTooltipWrapper;
		if( m_itemTooltipController0 != NULL )
		{
			m_itemTooltipController0.GetRootWidget().SetVisible( true );
			m_itemTooltipController0.SetData( UIInventoryItemTooltipWrapper.Make( m_data.baseItemData, m_data.displayContext ) );
		}
		if( m_itemTooltipController1 != NULL )
		{
			m_itemTooltipController1.GetRootWidget().SetVisible( true );
			tooltipWrapper = UIInventoryItemTooltipWrapper.Make( m_data.option1InventoryItem, m_data.displayContext );
			tooltipWrapper.m_comparisonData = UIInventoryItemComparisonManager.Make( m_data.baseItemData, m_data.option1InventoryItem );
			m_itemTooltipController1.SetData( tooltipWrapper );
		}
		if( m_itemTooltipController2 != NULL )
		{
			m_itemTooltipController2.GetRootWidget().SetVisible( true );
			tooltipWrapper = UIInventoryItemTooltipWrapper.Make( m_data.option2InventoryItem, m_data.displayContext );
			tooltipWrapper.m_comparisonData = UIInventoryItemComparisonManager.Make( m_data.baseItemData, m_data.option1InventoryItem );
			m_itemTooltipController2.SetData( tooltipWrapper );
		}
		if( m_itemTooltipController3 != NULL )
		{
			m_itemTooltipController3.GetRootWidget().SetVisible( true );
			tooltipWrapper = UIInventoryItemTooltipWrapper.Make( m_data.option3InventoryItem, m_data.displayContext );
			tooltipWrapper.m_comparisonData = UIInventoryItemComparisonManager.Make( m_data.baseItemData, m_data.option1InventoryItem );
			m_itemTooltipController3.SetData( tooltipWrapper );
		}
		if( m_itemTooltipController0 != NULL )
		{
			m_data.baseItemData.GetStatsManager().GetWeaponBars().SetComparedBars( NULL );
		}
	}

	private function SetButtonHints()
	{
		AddButtonHints( m_exitInputName, "UI-ResourceExports-Cancel", false );
	}

	private function AddButtonHints( actionName : CName, const label : ref< String >, isHold : Bool )
	{
		var buttonHint : LabelInputDisplayController;
		buttonHint = ( ( LabelInputDisplayController )( SpawnFromExternal( inkWidgetRef.Get( m_buttonHintsRoot ), R"base\gameplay\gui\common\buttons\base_buttons.inkwidget", 'inputDisplayLabelFlex' ).GetController() ) );
		buttonHint.SetInputActionLabel( actionName, label );
		if( isHold )
		{
			buttonHint.SetHoldIndicatorType( inkInputHintHoldIndicationType.Hold );
		}
	}

	private function SetCursorVisible( visible : Bool )
	{
		var cursorEvt : inkGameNotificationLayer_SetCursorVisibility;
		cursorEvt = new inkGameNotificationLayer_SetCursorVisibility;
		cursorEvt.Init( visible );
		QueueEvent( cursorEvt );
	}

	private function ForceResetCursor()
	{
		var cursorEvt : inkMenuLayer_SetCursorType;
		cursorEvt = new inkMenuLayer_SetCursorType;
		cursorEvt.Init( 'default', true );
		QueueBroadcastEvent( cursorEvt );
	}

	private function Close()
	{
		var closeData : RipperdocTokenPopupCloseData;
		closeData = new RipperdocTokenPopupCloseData;
		closeData.confirm = m_result;
		closeData.chosenOptionIndex = m_choice;
		if( m_result )
		{
			m_audioSystem.Play( 'ui_menu_item_crafting_done' );
		}
		switch( m_choice )
		{
			case 0:
				closeData.chosenOptionData = m_data.option1GameItemData;
			break;
			case 1:
				closeData.chosenOptionData = m_data.option2GameItemData;
			break;
			default:
				closeData.chosenOptionData = m_data.option3GameItemData;
			break;
		}
		closeData.costData = m_data.costData;
		SetCursorVisible( true );
		ForceResetCursor();
		m_data.token.TriggerCallback( closeData );
	}

	private function NavigateOptions( navDirection : ECustomFilterDPadNavigationOption )
	{
		var lastOption : Int32;
		lastOption = ( ( m_thirdChoiceAvailable ) ? ( 3 ) : ( 2 ) );
		switch( navDirection )
		{
			case ECustomFilterDPadNavigationOption.SelectNext:
				m_currentOption = ( ( m_currentOption < lastOption ) ? ( m_currentOption + 1 ) : ( 1 ) );
			break;
			case ECustomFilterDPadNavigationOption.SelectPrev:
				m_currentOption = ( ( m_currentOption > 1 ) ? ( m_currentOption - 1 ) : ( lastOption ) );
			break;
		}
		SetCursorOverWidget( inkWidgetRef.Get( m_optionTooltipParent[ m_currentOption ] ), 0.0, true );
	}

	private function ResetProgress()
	{
		m_progressStarted = false;
		if( m_option1ProgressBar )
		{
			m_option1ProgressBar.SetEffectParamValue( inkEffectType.LinearWipe, m_progressEffectName, 'transition', 1.0 );
			m_option1ProgressBar.SetEffectEnabled( inkEffectType.LinearWipe, m_progressEffectName, false );
			inkWidgetRef.SetVisible( m_option1ProgressBarRef, false );
		}
		if( m_option2ProgressBar )
		{
			m_option2ProgressBar.SetEffectParamValue( inkEffectType.LinearWipe, m_progressEffectName, 'transition', 1.0 );
			m_option2ProgressBar.SetEffectEnabled( inkEffectType.LinearWipe, m_progressEffectName, false );
			inkWidgetRef.SetVisible( m_option2ProgressBarRef, false );
		}
		if( m_option3ProgressBar )
		{
			m_option3ProgressBar.SetEffectParamValue( inkEffectType.LinearWipe, m_progressEffectName, 'transition', 1.0 );
			m_option3ProgressBar.SetEffectEnabled( inkEffectType.LinearWipe, m_progressEffectName, false );
			inkWidgetRef.SetVisible( m_option3ProgressBarRef, false );
		}
		m_itemTooltipCyberwareUpgrade.ResetProgress();
	}

	protected function MoveButtonToOption( button : inkWidgetRef, anchor : inkWidgetRef, instant : Bool )
	{
		var distance : Vector2;
		var horizontalDelta : Float;
		var verticalDelta : Float;
		var oldMargin : inkMargin;
		var newMargin : inkMargin;
		var newTopMargin : Float;
		var newLeftMargin : Float;
		var animation : inkAnimDef;
		var marginInterpolator : inkAnimMargin;
		distance = WidgetUtils.WidgetToWidget( inkWidgetRef.Get( button ), inkWidgetRef.Get( anchor ) );
		if( m_buttonAnimProxy != NULL )
		{
			m_buttonAnimProxy.GotoEndAndStop();
		}
		oldMargin = inkWidgetRef.GetMargin( button );
		newLeftMargin = distance.X;
		newTopMargin = distance.Y;
		newMargin = inkMargin( newLeftMargin, newTopMargin, oldMargin.right, oldMargin.bottom );
		if( instant )
		{
			inkWidgetRef.SetMargin( button, newMargin );
		}
		else
		{
			horizontalDelta = AbsF( oldMargin.left - distance.X );
			verticalDelta = AbsF( oldMargin.top - distance.Y );
			if( ( horizontalDelta != 0.0 ) || ( verticalDelta != 0.0 ) )
			{
				marginInterpolator = new inkAnimMargin;
				marginInterpolator.SetDuration( m_upgradeButtonAnimDuration );
				marginInterpolator.SetStartMargin( oldMargin );
				marginInterpolator.SetEndMargin( newMargin );
				marginInterpolator.SetType( inkanimInterpolationType.Sinusoidal );
				marginInterpolator.SetMode( inkanimInterpolationMode.EasyOut );
				animation = new inkAnimDef;
				animation.AddInterpolator( marginInterpolator );
				m_buttonAnimProxy = inkWidgetRef.PlayAnimation( button, animation );
			}
		}
	}

	private function PlayOutro()
	{
		UnregisterInputListeners();
		inkWidgetRef.SetVisible( m_upgradeBtnContainerRef, false );
		SetCursorVisible( false );
		if( !( m_multichoice ) )
		{
			PlayRumble( RumbleStrength.Heavy, RumbleType.Fast, RumblePosition.Both );
			m_choicesAnimProxy = PlayLibraryAnimation( m_noChoiceOutroAnimName );
			m_choicesAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnOutroFinished' );
		}
		else if( m_choice == 0 )
		{
			PlayRumble( RumbleStrength.Heavy, RumbleType.Fast, RumblePosition.Both );
			m_choicesAnimProxy = PlayLibraryAnimation( ( ( m_thirdChoiceAvailable ) ? ( m_threeChoice1OutroAnimName ) : ( m_twoChoice1OutroAnimName ) ) );
			m_choicesAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnOutroFinished' );
		}
		else if( m_choice == 1 )
		{
			PlayRumble( RumbleStrength.Heavy, RumbleType.Fast, RumblePosition.Both );
			m_choicesAnimProxy = PlayLibraryAnimation( ( ( m_thirdChoiceAvailable ) ? ( m_threeChoice2OutroAnimName ) : ( m_twoChoice2OutroAnimName ) ) );
			m_choicesAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnOutroFinished' );
		}
		else if( m_choice == 2 )
		{
			PlayRumble( RumbleStrength.Heavy, RumbleType.Fast, RumblePosition.Both );
			m_choicesAnimProxy = PlayLibraryAnimation( m_threeChoice3OutroAnimName );
			m_choicesAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnOutroFinished' );
		}
		else
		{
			Close();
		}
	}

	protected event OnOutroFinished( anim : inkAnimProxy )
	{
		m_choicesAnimProxy.UnregisterFromAllCallbacks( inkanimEventType.OnFinish );
		Close();
	}

	protected event OnPressInput( evt : inkPointerEvent )
	{
		if( evt.IsAction( m_exitInputName ) )
		{
			m_choice = -1;
			m_result = false;
			Close();
		}
		if( evt.IsAction( m_holdInputName ) || evt.IsAction( 'click_hold' ) )
		{
			m_audioSystem.Play( 'ui_menu_item_crafting_start' );
		}
		if( m_multichoice && evt.IsAction( 'popup_moveRight' ) )
		{
			NavigateOptions( ECustomFilterDPadNavigationOption.SelectNext );
		}
		else if( m_multichoice && evt.IsAction( 'popup_moveLeft' ) )
		{
			NavigateOptions( ECustomFilterDPadNavigationOption.SelectPrev );
		}
	}

	protected event OnInputRelease( evt : inkPointerEvent )
	{
		if( evt.IsAction( m_holdInputName ) || evt.IsAction( 'click_hold' ) )
		{
			m_audioSystem.Play( 'ui_menu_item_crafting_fail' );
			ResetProgress();
		}
	}

	protected event OnOption1HoverOver( evt : inkPointerEvent )
	{
		if( m_introAnimationPlaying )
		{
			m_currentOption = 1;
		}
		else
		{
			MoveButtonToOption( m_upgradeBtnContainerRef, m_option1UpgradeBtnAnchor, false );
			inkWidgetRef.SetState( m_optionRef[ 1 ], 'Hover' );
		}
	}

	protected event OnOption2HoverOver( evt : inkPointerEvent )
	{
		if( m_introAnimationPlaying )
		{
			m_currentOption = 2;
		}
		else
		{
			MoveButtonToOption( m_upgradeBtnContainerRef, m_option2UpgradeBtnAnchor, false );
			inkWidgetRef.SetState( m_optionRef[ 2 ], 'Hover' );
		}
	}

	protected event OnOption3HoverOver( evt : inkPointerEvent )
	{
		if( m_introAnimationPlaying )
		{
			m_currentOption = 3;
		}
		else
		{
			MoveButtonToOption( m_upgradeBtnContainerRef, m_option3UpgradeBtnAnchor, false );
			inkWidgetRef.SetState( m_optionRef[ 3 ], 'Hover' );
		}
	}

	protected event OnOptionOnHoverOut( evt : inkPointerEvent )
	{
		m_audioSystem.Play( 'ui_menu_item_crafting_fail' );
		inkWidgetRef.SetState( m_optionRef[ 1 ], 'Default' );
		inkWidgetRef.SetState( m_optionRef[ 2 ], 'Default' );
		inkWidgetRef.SetState( m_optionRef[ 3 ], 'Default' );
		ResetProgress();
	}

	protected event OnOption1Press( evt : inkPointerEvent )
	{
		if( evt.IsAction( m_holdInputName ) || evt.IsAction( 'click_hold' ) )
		{
			if( m_option1ProgressBar )
			{
				inkWidgetRef.SetVisible( m_option1ProgressBarRef, true );
				m_option1ProgressBar.SetEffectEnabled( inkEffectType.LinearWipe, m_progressEffectName, true );
			}
			m_progressStarted = true;
		}
	}

	protected event OnOption2Press( evt : inkPointerEvent )
	{
		if( evt.IsAction( m_holdInputName ) || evt.IsAction( 'click_hold' ) )
		{
			if( m_option2ProgressBar )
			{
				inkWidgetRef.SetVisible( m_option2ProgressBarRef, true );
				m_option2ProgressBar.SetEffectEnabled( inkEffectType.LinearWipe, m_progressEffectName, true );
			}
			m_progressStarted = true;
		}
	}

	protected event OnOption3Press( evt : inkPointerEvent )
	{
		if( evt.IsAction( m_holdInputName ) || evt.IsAction( 'click_hold' ) )
		{
			if( m_option3ProgressBar )
			{
				inkWidgetRef.SetVisible( m_option3ProgressBarRef, true );
				m_option3ProgressBar.SetEffectEnabled( inkEffectType.LinearWipe, m_progressEffectName, true );
			}
			m_progressStarted = true;
		}
	}

	protected event OnOption1Hold( evt : inkPointerEvent )
	{
		var progress : Float;
		if( ( evt.IsAction( m_holdInputName ) || evt.IsAction( 'click_hold' ) ) && m_progressStarted )
		{
			progress = MinF( evt.GetHoldProgress(), 1.0 );
			if( m_option1ProgressBar )
			{
				m_option1ProgressBar.SetEffectParamValue( inkEffectType.LinearWipe, m_progressEffectName, 'transition', AbsF( 1.0 - progress ) );
			}
			if( progress >= 1.0 )
			{
				m_choice = 0;
				m_result = true;
				PlayOutro();
			}
		}
	}

	protected event OnOption2Hold( evt : inkPointerEvent )
	{
		var progress : Float;
		if( ( evt.IsAction( m_holdInputName ) || evt.IsAction( 'click_hold' ) ) && m_progressStarted )
		{
			progress = MinF( evt.GetHoldProgress(), 1.0 );
			if( m_option2ProgressBar )
			{
				m_option2ProgressBar.SetEffectParamValue( inkEffectType.LinearWipe, m_progressEffectName, 'transition', AbsF( 1.0 - progress ) );
			}
			if( progress >= 1.0 )
			{
				m_choice = 1;
				m_result = true;
				PlayOutro();
			}
		}
	}

	protected event OnOption3Hold( evt : inkPointerEvent )
	{
		var progress : Float;
		if( ( evt.IsAction( m_holdInputName ) || evt.IsAction( 'click_hold' ) ) && m_progressStarted )
		{
			progress = MinF( evt.GetHoldProgress(), 1.0 );
			if( m_option3ProgressBar )
			{
				m_option3ProgressBar.SetEffectParamValue( inkEffectType.LinearWipe, m_progressEffectName, 'transition', AbsF( 1.0 - progress ) );
			}
			if( progress >= 1.0 )
			{
				m_choice = 2;
				m_result = true;
				PlayOutro();
			}
		}
	}

}

