class VendorHubMenuGameController extends gameuiMenuGameController
{
	private editable var m_notificationRoot : inkWidgetRef;
	[ category = "Center" ]
	private editable var m_tabRootContainer : inkWidgetRef;
	[ category = "Center" ]
	private editable var m_tabRootRef : inkWidgetRef;
	[ category = "Right" ]
	private editable var m_playerCredits : inkWidgetRef;
	[ category = "Right" ]
	private editable var m_playerCreditsValue : inkTextRef;
	[ category = "Right" ]
	private editable var m_playerWeight : inkWidgetRef;
	[ category = "Right" ]
	private editable var m_playerWeightValue : inkTextRef;
	[ category = "Right" ]
	private editable var m_vendorShopLabel : inkTextRef;
	[ category = "Left" ]
	private editable var m_levelValue : inkTextRef;
	[ category = "Left" ]
	private editable var m_streetCredLabel : inkTextRef;
	[ category = "Left" ]
	private editable var m_levelBarProgress : inkWidgetRef;
	[ category = "Left" ]
	private editable var m_levelBarSpacer : inkWidgetRef;
	[ category = "Left" ]
	private editable var m_streetCredBarProgress : inkWidgetRef;
	[ category = "Left" ]
	private editable var m_streetCredBarSpacer : inkWidgetRef;
	private var m_VendorDataManager : VendorDataManager;
	private var m_vendorUserData : VendorUserData;
	private var m_vendorPanelData : VendorPanelData;
	private var m_storageUserData : StorageUserData;
	private var m_PDS : PlayerDevelopmentSystem;
	private var m_root : weak< inkWidget >;
	private var m_tabRoot : weak< TabRadioGroup >;
	private var m_playerMoneyAnimator : weak< MoneyLabelController >;
	private var m_isRipperdoc : Bool;
	private var m_isRipperdocViktorTutorial : Bool;
	private var m_statusEffectSystem : weak< StatusEffectSystem >;
	private var m_questSystem : weak< QuestsSystem >;
	private var m_ripperdocTimeDilationCallback : RipperdocTimeDilationCallback;
	private var m_timeDilationEnabling : Bool;
	private var m_equipAnimationCategories : array< RipperdocCyberwareEquipAnimationCategory >;
	var m_VendorBlackboard : weak< IBlackboard >;
	var m_playerStatsBlackboard : weak< IBlackboard >;
	var m_VendorBlackboardDef : UI_VendorDef;
	var m_VendorUpdatedCallbackID : CallbackHandle;
	var m_weightListener : CallbackHandle;
	var m_characterLevelListener : CallbackHandle;
	var m_characterCurrentXPListener : CallbackHandle;
	var m_characterCredListener : CallbackHandle;
	var m_characterCredPointsListener : CallbackHandle;
	var m_characterCurrentHealthListener : CallbackHandle;
	private var m_menuEventDispatcher : weak< inkMenuEventDispatcher >;
	private var m_player : weak< PlayerPuppet >;
	private var m_menuData : array< MenuData >;
	private var m_activeMenu : Int32;
	private var m_isChangedManually : Bool;
	private var m_cameFromRipperdoc : Bool;
	private var m_storageDef : StorageBlackboardDef;
	private var m_storageBlackboard : weak< IBlackboard >;

	protected event OnInitialize()
	{
		SpawnFromLocal( inkWidgetRef.Get( m_notificationRoot ), 'notification_layer' );
	}

	protected event OnUninitialize()
	{
		var vendorData : VendorData;
		if( m_isRipperdoc )
		{
			UninitializeExtraRipperdocData();
		}
		vendorData.isActive = false;
		m_VendorBlackboard.SetVariant( GetAllBlackboardDefs().UI_Vendor.VendorData, vendorData, true );
		RemoveBB();
		UnregisterFromGlobalInputCallback( 'OnPostOnRelease', this, 'OnButtonRelease' );
	}

	protected event OnSetUserData( userData : IScriptable )
	{
		var vendorPanelData : VendorPanelData;
		var storageUserData : StorageUserData;
		var vendorData : VendorData;
		var requestStatsEvent : RequestStatsBB;
		m_storageDef = GetAllBlackboardDefs().StorageBlackboard;
		m_storageBlackboard = GetBlackboardSystem().Get( m_storageDef );
		storageUserData = ( ( StorageUserData )( m_storageBlackboard.GetVariant( m_storageDef.StorageData ) ) );
		if( ( userData == NULL ) && ( storageUserData == NULL ) )
		{
			return false;
		}
		vendorPanelData = ( ( VendorPanelData )( userData ) );
		m_storageUserData = storageUserData;
		if( vendorPanelData )
		{
			vendorData = vendorPanelData.data;
			m_vendorUserData = new VendorUserData;
			m_vendorUserData.vendorData = vendorPanelData;
			m_player = ( ( weak< weak< PlayerPuppet > > )( GetPlayerControlledObject() ) );
			m_PDS = ( ( PlayerDevelopmentSystem )( GameInstance.GetScriptableSystemsContainer( ( ( GameObject )( m_player ) ).GetGame() ).Get( 'PlayerDevelopmentSystem' ) ) );
			m_VendorDataManager = new VendorDataManager;
			m_VendorDataManager.Initialize( GetPlayerControlledObject(), vendorData.entityID );
			requestStatsEvent = new RequestStatsBB;
			requestStatsEvent.Set( m_player );
			m_PDS.QueueRequest( requestStatsEvent );
			Init();
		}
		else if( storageUserData )
		{
			m_player = ( ( weak< weak< PlayerPuppet > > )( GetPlayerControlledObject() ) );
			m_PDS = ( ( PlayerDevelopmentSystem )( GameInstance.GetScriptableSystemsContainer( ( ( GameObject )( m_player ) ).GetGame() ).Get( 'PlayerDevelopmentSystem' ) ) );
			m_VendorDataManager = new VendorDataManager;
			m_VendorDataManager.Initialize( GetPlayerControlledObject(), vendorData.entityID );
			requestStatsEvent = new RequestStatsBB;
			requestStatsEvent.Set( m_player );
			m_PDS.QueueRequest( requestStatsEvent );
			Init();
		}
	}

	private function Init()
	{
		var vendorObject : NPCPuppet;
		RegisterToGlobalInputCallback( 'OnPostOnRelease', this, 'OnButtonRelease' );
		RegisterToGlobalInputCallback( 'OnPostOnAxis', this, 'OnButtonRelease' );
		m_root = GetRootWidget();
		m_playerMoneyAnimator = ( ( MoneyLabelController )( inkTextRef.GetController( m_playerCreditsValue ) ) );
		vendorObject = ( ( NPCPuppet )( m_VendorDataManager.GetVendorInstance() ) );
		m_isRipperdoc = vendorObject.IsRipperdoc();
		m_statusEffectSystem = GameInstance.GetStatusEffectSystem( m_player.GetGame() );
		m_questSystem = GameInstance.GetQuestsSystem( m_player.GetGame() );
		SetupMenuTabs( false );
		SetupTopBar();
		SetupBB();
		OnPlayerWeightUpdated( -1.0 );
		if( m_isRipperdoc )
		{
			InitializeExtraRipperdocData();
		}
	}

	private function InitializeExtraRipperdocData()
	{
		m_isRipperdocViktorTutorial = ( m_VendorDataManager.GetVendorID() == T"Vendors.wat_lch_ripperdoc_01" ) && ( m_questSystem.GetFact( 'q001_ripperdoc_done' ) == 0 );
		if( !( m_isRipperdocViktorTutorial ) )
		{
			m_statusEffectSystem.RemoveStatusEffect( m_player.GetEntityID(), T"BaseStatusEffect.CyberwareInstallationAnimationEnd" );
			m_statusEffectSystem.RemoveStatusEffect( m_player.GetEntityID(), T"BaseStatusEffect.CyberwareInstallationAnimationEndFast" );
			m_statusEffectSystem.ApplyStatusEffect( m_player.GetEntityID(), T"BaseStatusEffect.CyberwareInstallationAnimationBlackout" );
		}
		InitializeEquipAnimationData();
		m_ripperdocTimeDilationCallback = new RipperdocTimeDilationCallback;
		m_ripperdocTimeDilationCallback.m_controller = this;
		GameInstance.GetDelaySystem( m_player.GetGame() ).DelayCallback( m_ripperdocTimeDilationCallback, 1.0 );
		m_timeDilationEnabling = true;
	}

	private function UninitializeExtraRipperdocData()
	{
		FinalizeEquipAnimationData();
		SetTimeDilatation( false );
		m_equipAnimationCategories.Clear();
	}

	private function InitializeEquipAnimationData()
	{
		var category : RipperdocCyberwareEquipAnimationCategory;
		var equipAreas : array< gamedataEquipmentArea >;
		m_equipAnimationCategories.Clear();
		category = new RipperdocCyberwareEquipAnimationCategory;
		equipAreas.PushBack( gamedataEquipmentArea.ArmsCW );
		equipAreas.PushBack( gamedataEquipmentArea.HandsCW );
		equipAreas.PushBack( gamedataEquipmentArea.NervousSystemCW );
		equipAreas.PushBack( gamedataEquipmentArea.IntegumentarySystemCW );
		equipAreas.PushBack( gamedataEquipmentArea.CardiovascularSystemCW );
		category.SetData( 'ripperdoc_cw_equip_animation_category_hands', equipAreas, 1.0 );
		m_equipAnimationCategories.PushBack( category );
		category = new RipperdocCyberwareEquipAnimationCategory;
		equipAreas.PushBack( gamedataEquipmentArea.FrontalCortexCW );
		equipAreas.PushBack( gamedataEquipmentArea.SystemReplacementCW );
		equipAreas.PushBack( gamedataEquipmentArea.EyesCW );
		category.SetData( 'ripperdoc_cw_equip_animation_category_vanilla', equipAreas, 2.0 );
		m_equipAnimationCategories.PushBack( category );
		category = new RipperdocCyberwareEquipAnimationCategory;
		equipAreas.PushBack( gamedataEquipmentArea.LegsCW );
		equipAreas.PushBack( gamedataEquipmentArea.MusculoskeletalSystemCW );
		category.SetData( 'ripperdoc_cw_equip_animation_category_legs', equipAreas, 1.5 );
		m_equipAnimationCategories.PushBack( category );
		category = new RipperdocCyberwareEquipAnimationCategory;
		category.SetData( 'ripperdoc_cw_equip_animation_category_generic', equipAreas, 0.2 );
		m_equipAnimationCategories.PushBack( category );
	}

	private function ResetEquipAnimationData()
	{
		var i : Int32;
		if( !( m_questSystem ) )
		{
			return;
		}
		for( i = 0; i < m_equipAnimationCategories.Size(); i += 1 )
		{
			m_questSystem.SetFact( m_equipAnimationCategories[ i ].m_factName, 0 );
			m_equipAnimationCategories[ i ].m_equipCount = 0;
		}
	}

	private function UpdateEquipAnimationData( equipArea : gamedataEquipmentArea, isEquip : Bool )
	{
		var i : Int32;
		for( i = 0; i < m_equipAnimationCategories.Size(); i += 1 )
		{
			if( ( m_equipAnimationCategories[ i ].m_equipAreas.Size() == 0 ) || m_equipAnimationCategories[ i ].m_equipAreas.Contains( equipArea ) )
			{
				if( isEquip )
				{
					m_equipAnimationCategories[ i ].m_equipCount += 1;
				}
				else if( m_equipAnimationCategories[ i ].m_equipCount > 0 )
				{
					m_equipAnimationCategories[ i ].m_equipCount -= 1;
				}
				break;
			}
		}
	}

	private function FinalizeEquipAnimationData()
	{
		var thresholds : array< Float >;
		var i, pickedCategory : Int32;
		var sum, randomFloat : Float;
		if( !( m_questSystem ) )
		{
			return;
		}
		if( m_isRipperdocViktorTutorial )
		{
			return;
		}
		for( i = 0; i < m_equipAnimationCategories.Size(); i += 1 )
		{
			sum += ( ( ( Float )( m_equipAnimationCategories[ i ].m_equipCount ) ) * m_equipAnimationCategories[ i ].m_weight );
			thresholds.PushBack( sum );
		}
		ResetEquipAnimationData();
		if( sum <= 0.0 )
		{
			m_statusEffectSystem.RemoveStatusEffect( m_player.GetEntityID(), T"BaseStatusEffect.CyberwareInstallationAnimationBlackout" );
			m_statusEffectSystem.ApplyStatusEffect( m_player.GetEntityID(), T"BaseStatusEffect.CyberwareInstallationAnimationEndFast" );
			return;
		}
		randomFloat = RandRangeF( 0.0, sum );
		for( i = 0; i < thresholds.Size(); i += 1 )
		{
			if( randomFloat <= thresholds[ i ] )
			{
				pickedCategory = i;
				break;
			}
		}
		m_questSystem.SetFact( m_equipAnimationCategories[ pickedCategory ].m_factName, 1 );
		m_statusEffectSystem.ApplyStatusEffect( m_player.GetEntityID(), T"BaseStatusEffect.CyberwareInstallationAnimation" );
	}

	public function SetTimeDilatation( enable : Bool )
	{
		var timeSystem : TimeSystem;
		var timeDilationReason : CName;
		timeDilationReason = 'VendorStash';
		timeSystem = GameInstance.GetTimeSystem( m_player.GetGame() );
		if( timeSystem )
		{
			if( enable && m_timeDilationEnabling )
			{
				timeSystem.SetTimeDilation( timeDilationReason, 0.0, , 'Linear', 'Linear' );
				timeSystem.SetTimeDilationOnLocalPlayerZero( timeDilationReason, 0.0, , 'Linear', 'Linear' );
			}
			else if( !( enable ) )
			{
				timeSystem.UnsetTimeDilation( timeDilationReason );
				timeSystem.UnsetTimeDilationOnLocalPlayerZero( timeDilationReason );
			}
			m_timeDilationEnabling = false;
		}
	}

	private function SetupBB()
	{
		var vendorData : VendorData;
		vendorData.isActive = true;
		m_VendorBlackboardDef = GetAllBlackboardDefs().UI_Vendor;
		m_VendorBlackboard = GetBlackboardSystem().Get( m_VendorBlackboardDef );
		m_VendorBlackboard.SetVariant( GetAllBlackboardDefs().UI_Vendor.VendorData, vendorData, true );
		m_playerStatsBlackboard = GetBlackboardSystem().Get( GetAllBlackboardDefs().UI_PlayerStats );
		m_weightListener = m_playerStatsBlackboard.RegisterDelayedListenerFloat( GetAllBlackboardDefs().UI_PlayerStats.currentInventoryWeight, this, 'OnPlayerWeightUpdated' );
		m_characterLevelListener = m_playerStatsBlackboard.RegisterDelayedListenerInt( GetAllBlackboardDefs().UI_PlayerStats.Level, this, 'OnCharacterLevelUpdated' );
		m_characterCurrentXPListener = m_playerStatsBlackboard.RegisterDelayedListenerInt( GetAllBlackboardDefs().UI_PlayerStats.CurrentXP, this, 'OnCharacterLevelCurrentXPUpdated' );
		m_playerStatsBlackboard.SignalInt( GetAllBlackboardDefs().UI_PlayerStats.CurrentXP );
		m_characterCredListener = m_playerStatsBlackboard.RegisterDelayedListenerInt( GetAllBlackboardDefs().UI_PlayerStats.StreetCredLevel, this, 'OnCharacterStreetCredLevelUpdated' );
		m_playerStatsBlackboard.SignalInt( GetAllBlackboardDefs().UI_PlayerStats.StreetCredLevel );
		m_characterCredPointsListener = m_playerStatsBlackboard.RegisterDelayedListenerInt( GetAllBlackboardDefs().UI_PlayerStats.StreetCredPoints, this, 'OnCharacterStreetCredPointsUpdated' );
		m_playerStatsBlackboard.SignalInt( GetAllBlackboardDefs().UI_PlayerStats.StreetCredPoints );
		m_playerStatsBlackboard.SignalInt( GetAllBlackboardDefs().UI_PlayerStats.weightMax );
		m_playerStatsBlackboard.SignalInt( GetAllBlackboardDefs().UI_PlayerStats.Level );
		m_characterCurrentHealthListener = m_playerStatsBlackboard.RegisterDelayedListenerInt( GetAllBlackboardDefs().UI_PlayerStats.CurrentHealth, this, 'OnCharacterCurrentHealthUpdated' );
		if( m_VendorBlackboard )
		{
			m_VendorUpdatedCallbackID = m_VendorBlackboard.RegisterDelayedListenerVariant( m_VendorBlackboardDef.VendorData, this, 'OnVendorUpdated' );
		}
	}

	private function RemoveBB()
	{
		if( m_VendorBlackboard )
		{
			m_VendorBlackboard.UnregisterDelayedListener( m_VendorBlackboardDef.VendorData, m_VendorUpdatedCallbackID );
		}
		if( m_playerStatsBlackboard )
		{
			m_playerStatsBlackboard.UnregisterDelayedListener( GetAllBlackboardDefs().UI_PlayerStats.Level, m_characterLevelListener );
			m_playerStatsBlackboard.UnregisterDelayedListener( GetAllBlackboardDefs().UI_PlayerStats.CurrentXP, m_characterCurrentXPListener );
			m_playerStatsBlackboard.UnregisterDelayedListener( GetAllBlackboardDefs().UI_PlayerStats.StreetCredLevel, m_characterCredListener );
			m_playerStatsBlackboard.UnregisterDelayedListener( GetAllBlackboardDefs().UI_PlayerStats.StreetCredPoints, m_characterCredPointsListener );
			m_playerStatsBlackboard.UnregisterDelayedListener( GetAllBlackboardDefs().UI_PlayerStats.CurrentXP, m_characterCurrentHealthListener );
		}
		m_VendorBlackboard = NULL;
	}

	private function SetupTopBar()
	{
		UpdateMoney();
		inkTextRef.SetText( m_vendorShopLabel, m_VendorDataManager.GetVendorName() );
	}

	protected event OnPlayerWeightUpdated( value : Float )
	{
		var carryCapacity : Int32;
		var gameInstance : GameInstance;
		gameInstance = ( ( weak< weak< GameObject > > )( m_player ) ).GetGame();
		carryCapacity = ( ( Int32 )( GameInstance.GetStatsSystem( gameInstance ).GetStatValue( m_player.GetEntityID(), gamedataStatType.CarryCapacity ) ) );
		inkTextRef.SetText( m_playerWeightValue, ( IntToString( RoundF( m_player.m_curInventoryWeight ) ) + "/" ) + carryCapacity );
	}

	protected event OnCharacterLevelUpdated( value : Int32 )
	{
		inkTextRef.SetText( m_levelValue, IntToString( value ) );
	}

	protected event OnCharacterLevelCurrentXPUpdated( value : Int32 )
	{
		var remainingXP : Int32;
		var percentageValue : Float;
		remainingXP = m_PDS.GetRemainingExpForLevelUp( m_player, gamedataProficiencyType.Level );
		percentageValue = ( ( Float )( value ) ) / ( ( Float )( ( remainingXP + value ) ) );
		inkWidgetRef.SetSizeCoefficient( m_levelBarProgress, percentageValue );
		inkWidgetRef.SetSizeCoefficient( m_levelBarSpacer, 1.0 - percentageValue );
	}

	protected event OnCharacterStreetCredLevelUpdated( value : Int32 )
	{
		inkTextRef.SetText( m_streetCredLabel, ( ( String )( value ) ) );
	}

	protected event OnCharacterStreetCredPointsUpdated( value : Int32 )
	{
		var remainingXP : Int32;
		var percentageValue : Float;
		remainingXP = m_PDS.GetRemainingExpForLevelUp( m_player, gamedataProficiencyType.StreetCred );
		percentageValue = ( ( Float )( value ) ) / ( ( Float )( ( remainingXP + value ) ) );
		inkWidgetRef.SetSizeCoefficient( m_streetCredBarProgress, percentageValue );
		inkWidgetRef.SetSizeCoefficient( m_streetCredBarSpacer, 1.0 - percentageValue );
	}

	protected event OnCharacterCurrentHealthUpdated( value : Int32 )
	{
		if( value <= 0 )
		{
			CloseVendor();
		}
	}

	private function SetupMenuTabs( tutorialFinished : Bool )
	{
		var labels : array< String >;
		var icons : array< String >;
		var selectedIdentifier : Int32;
		var cyberwareTutorial : Bool;
		var psmBlackboard : IBlackboard;
		var isCarftingAvailable : Bool;
		isCarftingAvailable = true;
		psmBlackboard = m_player.GetPlayerStateMachineBlackboard();
		isCarftingAvailable = ( psmBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Combat ) != ( ( Int32 )( gamePSMCombat.InCombat ) ) ) && !( StatusEffectSystem.ObjectHasStatusEffectWithTag( m_player, 'NoCrafting' ) );
		inkWidgetRef.SetVisible( m_tabRootContainer, false );
		if( m_vendorUserData && m_isRipperdoc )
		{
			cyberwareTutorial = ( m_VendorDataManager.GetVendorID() == T"Vendors.wat_lch_ripperdoc_01" ) && ( m_questSystem.GetFact( 'q001_ripperdoc_done' ) == 0 );
			cyberwareTutorial = cyberwareTutorial || ( ( ( ( m_questSystem.GetFact( 'mq048_active' ) > 0 ) && ( m_questSystem.GetFact( 'mq048_done' ) == 0 ) ) || ( m_questSystem.GetFact( 'ep1_standalone' ) > 0 ) ) && ( m_questSystem.GetFact( 'ep1_ripperdoc_tutorial_seen' ) == 0 ) );
			cyberwareTutorial = cyberwareTutorial && !( tutorialFinished );
			m_tabRoot = ( ( TabRadioGroup )( inkWidgetRef.GetController( m_tabRootRef ) ) );
			if( !( cyberwareTutorial ) )
			{
				labels.PushBack( "UI-PanelNames-TRADE" );
			}
			labels.PushBack( "UI-PanelNames-CYBERWARE" );
			if( !( cyberwareTutorial ) )
			{
				labels.PushBack( "UI-PanelNames-CHARACTER" );
			}
			if( !( cyberwareTutorial ) && isCarftingAvailable )
			{
				labels.PushBack( "Gameplay-RPG-Skills-CraftingName" );
			}
			if( !( cyberwareTutorial ) )
			{
				icons.PushBack( "ico_cyberware" );
				icons.PushBack( "ico_cyberware" );
				icons.PushBack( "ico_cyberware" );
			}
			icons.PushBack( "ico_cyberware" );
			m_tabRoot.SetData( ( ( cyberwareTutorial ) ? ( 1 ) : ( 4 ) ), NULL, labels, icons );
			inkWidgetRef.SetVisible( m_tabRootContainer, true );
			m_tabRoot.RegisterToCallback( 'OnValueChanged', this, 'OnValueChanged' );
			selectedIdentifier = ( ( m_isRipperdoc ) ? ( ( ( Int32 )( HubVendorMenuItems.Cyberware ) ) ) : ( ( ( Int32 )( HubVendorMenuItems.Trade ) ) ) );
			m_activeMenu = selectedIdentifier;
			m_tabRoot.Toggle( selectedIdentifier );
			OnValueChanged( m_tabRoot, selectedIdentifier );
		}
		else
		{
			m_activeMenu = 0;
			m_vendorUserData.menu = "TRADE";
			m_menuEventDispatcher.SpawnEvent( 'OnSwitchToVendor', m_vendorUserData );
		}
	}

	protected event OnCyberwareModsRequest( evt : CyberwareTabModsRequest )
	{
		m_menuEventDispatcher.SpawnEvent( 'OnSwitchToInventory', evt.wrapper );
	}

	protected event OnValueChanged( controller : weak< inkRadioGroupController >, selectedIndex : Int32 )
	{
		inkWidgetRef.SetVisible( m_playerWeight, true );
		if( m_isChangedManually )
		{
			m_isChangedManually = false;
			return false;
		}
		switch( selectedIndex )
		{
			case 0:
				m_vendorUserData.menu = "TRADE";
			m_menuEventDispatcher.SpawnEvent( 'OnSwitchToVendor', m_vendorUserData );
			break;
			case 1:
				m_vendorUserData.menu = "CYBERWARE";
			inkWidgetRef.SetVisible( m_playerWeight, false );
			m_menuEventDispatcher.SpawnEvent( 'OnSwitchToRipperDoc', m_vendorUserData );
			break;
			case 2:
				m_vendorUserData.menu = "CHARACTER";
			m_menuEventDispatcher.SpawnEvent( 'OnSwitchToCharacter', m_vendorUserData );
			break;
			case 3:
				m_vendorUserData.menu = "CRAFTING";
			m_menuEventDispatcher.SpawnEvent( 'OnSwitchToCrafting', m_vendorUserData );
			break;
		}
		m_activeMenu = selectedIndex;
		NotifyActivePanel( ( ( HubVendorMenuItems )( selectedIndex ) ) );
		ForceResetCursorType();
	}

	protected event OnRefreshCurrentTab( userData : IScriptable )
	{
		if( m_cameFromRipperdoc )
		{
			m_cameFromRipperdoc = false;
			m_activeMenu = 1;
			m_tabRoot.Toggle( m_activeMenu );
		}
		else if( m_activeMenu == 1 )
		{
			OnValueChanged( m_tabRoot, m_activeMenu );
		}
		else
		{
			m_tabRoot.Toggle( m_activeMenu );
		}
	}

	protected event OnTutorialComplete( userData : IScriptable )
	{
		SetupMenuTabs( true );
	}

	protected event OnSwitchToCharacterFromRipperdoc( userData : IScriptable )
	{
		m_isChangedManually = true;
		m_activeMenu = 2;
		m_tabRoot.Toggle( m_activeMenu );
		m_cameFromRipperdoc = true;
	}

	protected event OnEquipAnimationDataUpdate( userData : IScriptable )
	{
		var equipAnimationUpdateData : EquipAnimationUpdateData;
		equipAnimationUpdateData = ( ( EquipAnimationUpdateData )( userData ) );
		UpdateEquipAnimationData( equipAnimationUpdateData.equipArea, true );
	}

	protected event OnButtonRelease( evt : inkPointerEvent )
	{
		if( evt.IsHandled() )
		{
			return false;
		}
		if( evt.IsAction( 'prior_menu' ) )
		{
			PlayRumble( RumbleStrength.SuperLight, RumbleType.Pulse, RumblePosition.Left );
			m_activeMenu -= 1;
			if( m_activeMenu < 0 )
			{
				m_activeMenu = 3;
			}
			m_tabRoot.Toggle( m_activeMenu );
		}
		else if( evt.IsAction( 'next_menu' ) )
		{
			PlayRumble( RumbleStrength.SuperLight, RumbleType.Pulse, RumblePosition.Right );
			m_activeMenu += 1;
			if( m_activeMenu > 3 )
			{
				m_activeMenu = 0;
			}
			m_tabRoot.Toggle( m_activeMenu );
		}
		else if( evt.IsAction( 'back' ) )
		{
			if( StatusEffectSystem.ObjectHasStatusEffectWithTag( GetPlayerControlledObject(), 'LockInHubMenu' ) )
			{
				return false;
			}
			else if( m_vendorUserData.menu == "CHARACTER" )
			{
				return false;
			}
			else if( m_vendorUserData.menu != "CYBERWARE" )
			{
				CloseVendor();
			}
		}
	}

	protected event OnVendorUpdated( value : Variant )
	{
		UpdateMoney();
	}

	private function UpdateMoney()
	{
		var playerMoney : Int32;
		playerMoney = VendorDataManager.GetLocalPlayerCurrencyAmount( VendorDataManager.GetLocalPlayer( m_player.GetGame() ) );
		if( playerMoney != StringToInt( inkTextRef.GetText( m_playerCreditsValue ) ) )
		{
			m_playerMoneyAnimator.SetMoney( playerMoney, 0.1, 0.25 );
		}
	}

	private function NotifyActivePanel( item : HubVendorMenuItems )
	{
		var evt : VendorHubMenuChanged;
		evt = new VendorHubMenuChanged;
		evt.item = item;
		QueueEvent( evt );
	}

	protected event OnSetMenuEventDispatcher( menuEventDispatcher : weak< inkMenuEventDispatcher > )
	{
		m_menuEventDispatcher = menuEventDispatcher;
		m_menuEventDispatcher.RegisterToEvent( 'RefreshCurrentTab', this, 'OnRefreshCurrentTab' );
		m_menuEventDispatcher.RegisterToEvent( 'SwitchToCharacterFromRipperdoc', this, 'OnSwitchToCharacterFromRipperdoc' );
		m_menuEventDispatcher.RegisterToEvent( 'TutorialComplete', this, 'OnTutorialComplete' );
		m_menuEventDispatcher.RegisterToEvent( 'EquipAnimationDataUpdate', this, 'OnEquipAnimationDataUpdate' );
	}

	private function CloseVendor()
	{
		var menuEvent : inkMenuInstance_SpawnEvent;
		menuEvent = new inkMenuInstance_SpawnEvent;
		menuEvent.Init( 'OnVendorClose' );
		QueueEvent( menuEvent );
	}

}

class VendorHubMenuChanged extends Event
{
	var item : HubVendorMenuItems;
}

class RipperdocTimeDilationCallback extends DelayCallback
{
	var m_controller : weak< VendorHubMenuGameController >;

	public override function Call()
	{
		var strongController : VendorHubMenuGameController;
		strongController = m_controller;
		if( strongController )
		{
			strongController.SetTimeDilatation( true );
		}
	}

}

class EquipAnimationUpdateData extends IScriptable
{
	var equipArea : gamedataEquipmentArea;
	var isEquip : Bool;
}

