import struct PhotoModeOptionSelectorData
{
	import var optionText : String;
	import var optionData : Int32;
}

import struct PhotoModeOptionGridButtonData
{
	import var imagePart : CName;
	import var atlasResource : ResRef;
	import var optionData : Int32;
}

class PhotoModeMenuListItemData extends ListItemData
{
	var attributeKey : Uint32;
}

import class gameuiPhotoModeMenuController extends inkGameController
{
	public import function OnHoverStateChanged( hover : Bool );
	public import function OnAttributeUpdated( attributeKey : Uint32, attributeValue : Float, optional doApply : Bool );
	public import function OnAttributeSelected( attributeKey : Uint32 );
	public import function OnEditCategoryChanged( editCategory : Uint32 );
	public import function OnHoldComplete( attributeKey : Uint32, actionName : CName );
	public import function OnAnimationEnded( animationType : Uint32 );

	private editable var m_menuListRoot : inkWidgetRef;
	private editable var m_additionalListRoot : inkWidgetRef;
	private editable var m_radioButtons : inkCompoundRef;
	private editable var m_listContainerId : CName;
	private editable var m_menuArea : inkWidgetRef;
	private editable var m_additionalMenuArea : inkWidgetRef;
	private editable var m_inputCameraControlKbd : inkWidgetRef;
	private editable var m_inputCameraKbd : inkWidgetRef;
	private editable var m_inputCameraControlPad : inkWidgetRef;
	private editable var m_inputCameraPad : inkWidgetRef;
	private editable var m_inputStickersKbd : inkWidgetRef;
	private editable var m_inputStickersPad : inkWidgetRef;
	private editable var m_inputSaveLoadKbd : inkWidgetRef;
	private editable var m_inputSaveLoadPad : inkWidgetRef;
	private editable var m_inputExit : inkWidgetRef;
	private editable var m_inputScreenshot : inkWidgetRef;
	private editable var m_cameraLocation : inkWidgetRef;
	private editable var m_inputBottomRoot : inkHorizontalPanelRef;
	private editable var m_ps4InputLibraryId : CName;
	private editable var m_xboxInputLibraryId : CName;
	private editable var m_stadiaInputLibraryId : CName;
	private var ps4InputWidget : weak< inkWidget >;
	private var xboxInputWidget : weak< inkWidget >;
	private var stadiaInputWidget : weak< inkWidget >;
	private var m_menuPages : array< weak< inkWidget > >;
	private var m_topButtonsController : weak< PhotoModeTopBarController >;
	private var m_cameraLocationController : weak< PhotoModeCameraLocation >;
	private var m_currentPage : Uint32;
	private var m_IsHoverOver : Bool;
	private var m_holdSafeguard : Bool;
	private var m_notificationUserData : inkGameNotificationData;
	private var m_notificationToken : inkGameNotificationToken;
	private var loopAnimproxy : inkAnimProxy;
	private var m_uiVisiblityFadeAnim : inkAnimProxy;

	protected event OnInitialize()
	{
		m_IsHoverOver = false;
		m_holdSafeguard = false;
		if( !( m_topButtonsController ) )
		{
			m_topButtonsController = ( ( PhotoModeTopBarController )( inkCompoundRef.GetController( m_radioButtons ) ) );
			m_topButtonsController.RegisterToCallback( 'OnValueChanged', this, 'OnTopBarValueChanged' );
		}
		if( !( m_cameraLocationController ) )
		{
			m_cameraLocationController = ( ( PhotoModeCameraLocation )( inkWidgetRef.GetController( m_cameraLocation ) ) );
		}
		if( inkWidgetRef.IsValid( m_menuArea ) )
		{
			inkWidgetRef.RegisterToCallback( m_menuArea, 'OnHoverOver', this, 'OnMenuHovered' );
			inkWidgetRef.RegisterToCallback( m_menuArea, 'OnHoverOut', this, 'OnMenuHoverOut' );
			inkWidgetRef.RegisterToCallback( m_additionalMenuArea, 'OnHoverOver', this, 'OnMenuHovered' );
			inkWidgetRef.RegisterToCallback( m_additionalMenuArea, 'OnHoverOut', this, 'OnMenuHoverOut' );
		}
		RegisterToCallback( 'OnSetAttributeOptionEnabled', this, 'OnSetAttributeOptionEnabled' );
		RegisterToCallback( 'OnSetCategoryEnabled', this, 'OnSetCategoryEnabled' );
		RegisterToCallback( 'OnSetStickerImage', this, 'OnSetStickerImage' );
	}

	protected event OnUninitialize()
	{
		UnregisterFromCallback( 'OnSetAttributeOptionEnabled', this, 'OnSetAttributeOptionEnabled' );
		UnregisterFromCallback( 'OnSetCategoryEnabled', this, 'OnSetCategoryEnabled' );
		UnregisterFromCallback( 'OnSetStickerImage', this, 'OnSetStickerImage' );
		if( inkWidgetRef.IsValid( m_menuArea ) )
		{
			inkWidgetRef.UnregisterFromCallback( m_menuArea, 'OnHoverOver', this, 'OnMenuHovered' );
			inkWidgetRef.UnregisterFromCallback( m_menuArea, 'OnHoverOut', this, 'OnMenuHoverOut' );
			inkWidgetRef.UnregisterFromCallback( m_additionalMenuArea, 'OnHoverOver', this, 'OnMenuHovered' );
			inkWidgetRef.UnregisterFromCallback( m_additionalMenuArea, 'OnHoverOut', this, 'OnMenuHoverOut' );
		}
		if( m_topButtonsController )
		{
			m_topButtonsController.UnregisterFromCallback( 'OnValueChanged', this, 'OnTopBarValueChanged' );
		}
	}

	protected event OnIntroAnimEnded( e : inkAnimProxy )
	{
		var options : inkAnimOptions;
		RegisterToGlobalInputCallback( 'OnPostOnRelease', this, 'OnPMButtonRelease' );
		RegisterToGlobalInputCallback( 'OnPostOnHold', this, 'OnPMButtonHold' );
		RegisterToGlobalInputCallback( 'OnPostOnHold', this, 'OnOptionHold' );
		RegisterToGlobalInputCallback( 'OnPostOnRelease', this, 'OnOptionHoldRelease' );
		OnAnimationEnded( 0 );
		options.loopType = inkanimLoopType.Cycle;
		options.loopInfinite = true;
		loopAnimproxy = PlayLibraryAnimation( 'idle_loop', options );
	}

	protected event OnOutroAnimEnded( e : inkAnimProxy )
	{
		OnAnimationEnded( 1 );
	}

	protected event OnShow( reversedUI : Bool )
	{
		var i : Int32;
		var pageController : PhotoModeListController;
		var animproxy : inkAnimProxy;
		var widget : weak< inkWidget >;
		widget = GetRootWidget();
		widget.SetOpacity( 1.0 );
		if( m_topButtonsController.GetCurrentIndex() != 0 )
		{
			m_topButtonsController.Toggle( 0 );
		}
		for( i = 0; i < m_menuPages.Size(); i += 1 )
		{
			pageController = ( ( PhotoModeListController )( GetMenuPage( ( ( Uint32 )( i ) ) ) ) );
			pageController.SetReversedUI( reversedUI );
		}
		OnSetCurrentMenuPage( ( ( Uint32 )( 0 ) ) );
		animproxy = PlayLibraryAnimation( 'intro' );
		animproxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnIntroAnimEnded' );
		CloseWeaponsWheelAndStopEffects();
	}

	protected function CloseWeaponsWheelAndStopEffects()
	{
		var radialMenuCloseEvt : ForceRadialWheelShutdown;
		var requestStopPulse : PulseFinishedRequest;
		radialMenuCloseEvt = new ForceRadialWheelShutdown;
		requestStopPulse = new PulseFinishedRequest;
		GetPlayerControlledObject().QueueEvent( radialMenuCloseEvt );
		GetPlayerControlledObject().GetHudManager().QueueRequest( requestStopPulse );
		GameObjectEffectHelper.StopEffectEvent( GetPlayerControlledObject(), 'fx_health_low' );
	}

	protected event OnHide()
	{
		var animproxy : inkAnimProxy;
		var playerHelthState : Uint32;
		UnregisterFromGlobalInputCallback( 'OnPostOnRelease', this, 'OnPMButtonRelease' );
		UnregisterFromGlobalInputCallback( 'OnPostOnHold', this, 'OnPMButtonHold' );
		UnregisterFromGlobalInputCallback( 'OnPostOnHold', this, 'OnOptionHold' );
		UnregisterFromGlobalInputCallback( 'OnPostOnRelease', this, 'OnOptionHoldRelease' );
		if( loopAnimproxy )
		{
			loopAnimproxy.Stop();
			loopAnimproxy = NULL;
		}
		animproxy = PlayLibraryAnimation( 'outro' );
		animproxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnOutroAnimEnded' );
		playerHelthState = GetBlackboardSystem().Get( GetAllBlackboardDefs().PhotoMode ).GetUint( GetAllBlackboardDefs().PhotoMode.PlayerHealthState );
		if( playerHelthState == ( ( Uint32 )( 1 ) ) )
		{
			GameObjectEffectHelper.StartEffectEvent( GetPlayerControlledObject(), 'fx_health_low' );
		}
		m_uiVisiblityFadeAnim = NULL;
		if( m_cameraLocationController )
		{
			m_cameraLocationController.OnHide();
		}
	}

	protected event OnSetStickerImage( stickerIndex : Uint32, atlasPath : ResRef, imagePart : CName, imageIndex : Int32 )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		photoModeListItem = GetMenuItem( ( ( Uint32 )( 35 ) ) );
		if( photoModeListItem )
		{
			photoModeListItem.SetGridButtonImage( stickerIndex, atlasPath, imagePart, imageIndex );
		}
	}

	protected event OnSetScreenshotEnabled( screenshotVersion : Uint32 )
	{
		var displayController : inkInputDisplayController;
		displayController = ( ( inkInputDisplayController )( inkWidgetRef.GetController( m_inputScreenshot ) ) );
		if( screenshotVersion == ( ( Uint32 )( 0 ) ) )
		{
			displayController.SetVisible( true );
		}
		else
		{
			displayController.SetVisible( false );
			AddConsoleScreenshotInput( screenshotVersion );
		}
	}

	protected event OnHideScreenshotInputForGGP()
	{
		inkWidgetRef.SetVisible( m_inputScreenshot, false );
	}

	protected event OnUpdate( timeDelta : Float )
	{
		var i : Int32;
		var photoModeListItem : PhotoModeMenuListItem;
		var pageController : PhotoModeListController;
		var exitLocked : Bool;
		photoModeListItem = GetCurrentSelectedMenuListItem();
		if( photoModeListItem )
		{
			photoModeListItem.Update( timeDelta );
		}
		for( i = 0; i < m_menuPages.Size(); i += 1 )
		{
			pageController = ( ( PhotoModeListController )( GetMenuPage( ( ( Uint32 )( i ) ) ) ) );
			pageController.Update( timeDelta );
		}
		exitLocked = GameInstance.GetPhotoModeSystem( GetPlayerControlledObject().GetGame() ).IsExitLocked();
		if( exitLocked && inkWidgetRef.IsVisible( m_inputExit ) )
		{
			inkWidgetRef.SetVisible( m_inputExit, false );
		}
		else if( !( exitLocked ) && !( inkWidgetRef.IsVisible( m_inputExit ) ) )
		{
			inkWidgetRef.SetVisible( m_inputExit, true );
		}
		if( m_cameraLocationController )
		{
			m_cameraLocationController.RefreshValue( GameInstance.GetPhotoModeSystem( GetPlayerControlledObject().GetGame() ) );
		}
	}

	public function SetCurrentMenuPage( page : Uint32 )
	{
		var i : Int32;
		var newPage : PhotoModeListController;
		var pageController : PhotoModeListController;
		var photoModeListItem : PhotoModeMenuListItem;
		var data : PhotoModeMenuListItemData;
		var firstVisible : Int32;
		for( i = 0; i < m_menuPages.Size(); i += 1 )
		{
			pageController = ( ( PhotoModeListController )( GetMenuPage( ( ( Uint32 )( i ) ) ) ) );
			if( i == ( ( Int32 )( page ) ) )
			{
				pageController.ShowAnimated( 0.15000001 );
			}
			else if( i == ( ( Int32 )( m_currentPage ) ) )
			{
				pageController.HideAnimated( 0.0 );
			}
		}
		m_currentPage = page;
		newPage = ( ( PhotoModeListController )( GetMenuPage( page ) ) );
		firstVisible = newPage.GetFirstVisibleIndex();
		newPage.SetSelectedIndex( firstVisible );
		OnEditCategoryChanged( page );
		photoModeListItem = GetCurrentSelectedMenuListItem();
		data = ( ( PhotoModeMenuListItemData )( photoModeListItem.GetData() ) );
		OnAttributeSelected( data.attributeKey );
	}

	protected event OnSetCurrentMenuPage( page : Uint32 )
	{
		SetCurrentMenuPage( page );
	}

	protected event OnTopBarValueChanged( controller : weak< inkRadioGroupController >, selectedIndex : Int32 )
	{
		OnSetCurrentMenuPage( ( ( Uint32 )( selectedIndex ) ) );
	}

	protected event OnAddMenuItem( labelText : String, attributeKey : Uint32, page : Uint32 )
	{
		AddMenuItem( labelText, attributeKey, page, false );
	}

	protected event OnAddAdditionalMenuItem( labelText : String, attributeKey : Uint32, page : Uint32 )
	{
		AddMenuItem( labelText, attributeKey, page, true );
	}

	protected function AddConsoleScreenshotInput( screenshotVersion : Uint32 )
	{
		if( ( screenshotVersion == ( ( Uint32 )( 1 ) ) ) && ( ps4InputWidget == NULL ) )
		{
			ps4InputWidget = SpawnFromLocal( inkHorizontalPanelRef.Get( m_inputBottomRoot ), m_ps4InputLibraryId );
			ps4InputWidget.SetMargin( 50.0, 0.0, 0.0, 0.0 );
			inkHorizontalPanelRef.ReorderChild( m_inputBottomRoot, ps4InputWidget, 2 );
		}
		else if( ( screenshotVersion == ( ( Uint32 )( 2 ) ) ) && ( xboxInputWidget == NULL ) )
		{
			xboxInputWidget = SpawnFromLocal( inkHorizontalPanelRef.Get( m_inputBottomRoot ), m_xboxInputLibraryId );
			xboxInputWidget.SetMargin( 50.0, 0.0, 0.0, 0.0 );
			inkHorizontalPanelRef.ReorderChild( m_inputBottomRoot, xboxInputWidget, 2 );
		}
		else if( ( screenshotVersion == ( ( Uint32 )( 3 ) ) ) && ( stadiaInputWidget == NULL ) )
		{
			stadiaInputWidget = SpawnFromLocal( inkHorizontalPanelRef.Get( m_inputBottomRoot ), m_stadiaInputLibraryId );
			stadiaInputWidget.SetMargin( 50.0, 0.0, 0.0, 0.0 );
			inkHorizontalPanelRef.ReorderChild( m_inputBottomRoot, stadiaInputWidget, 2 );
		}
	}

	protected event OnAddingMenuItemsFinished()
	{
		var i : Int32;
		var pageController : PhotoModeListController;
		for( i = 0; i < m_menuPages.Size(); i += 1 )
		{
			pageController = ( ( PhotoModeListController )( GetMenuPage( ( ( Uint32 )( i ) ) ) ) );
			pageController.PostInitItems();
		}
	}

	protected event OnForceAttributeVaulue( attribute : Uint32, value : Float, doApply : Bool )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		photoModeListItem = GetMenuItem( attribute );
		if( photoModeListItem )
		{
			photoModeListItem.ForceValue( value, doApply );
		}
	}

	protected event OnFadeVisibility( opacity : Float )
	{
		var animDef : inkAnimDef;
		var animInterp : inkAnimTransparency;
		var widget : weak< inkWidget >;
		widget = GetRootWidget();
		if( widget.GetOpacity() != opacity )
		{
			animDef = new inkAnimDef;
			animInterp = new inkAnimTransparency;
			animInterp.SetStartTransparency( widget.GetOpacity() );
			animInterp.SetEndTransparency( opacity );
			animInterp.SetDuration( 0.30000001 );
			animInterp.SetDirection( inkanimInterpolationDirection.To );
			animInterp.SetUseRelativeDuration( true );
			animDef.AddInterpolator( animInterp );
			if( m_uiVisiblityFadeAnim != NULL )
			{
				m_uiVisiblityFadeAnim.Stop();
			}
			m_uiVisiblityFadeAnim = widget.PlayAnimation( animDef );
		}
	}

	protected event OnHideForScreenshot()
	{
		if( m_uiVisiblityFadeAnim != NULL )
		{
			m_uiVisiblityFadeAnim.Stop();
			m_uiVisiblityFadeAnim = NULL;
		}
	}

	protected event OnSetupGridSelector( attribute : Uint32, gridData : array< PhotoModeOptionGridButtonData >, elementsCount : Uint32, elementsInRow : Uint32 )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		photoModeListItem = GetMenuItem( attribute );
		if( photoModeListItem )
		{
			photoModeListItem.m_photoModeController = this;
			photoModeListItem.SetupGridSelector( gridData, elementsCount, elementsInRow );
			photoModeListItem.SetIsEnabled( true );
			OnAttributeUpdated( attribute, photoModeListItem.GetSliderValue() );
		}
	}

	protected event OnSetupScrollBar( attribute : Uint32, startValue : Float, minValue : Float, maxValue : Float, step : Float, showPercents : Bool )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		photoModeListItem = GetMenuItem( attribute );
		if( photoModeListItem )
		{
			photoModeListItem.m_photoModeController = this;
			photoModeListItem.SetupScrollBar( startValue, minValue, maxValue, step, showPercents );
			photoModeListItem.SetIsEnabled( true );
			OnAttributeUpdated( attribute, photoModeListItem.GetSliderValue() );
		}
	}

	protected event OnSetupOptionSelector( attribute : Uint32, values : array< PhotoModeOptionSelectorData >, startData : Int32, doApply : Bool )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		photoModeListItem = GetMenuItem( attribute );
		if( photoModeListItem )
		{
			photoModeListItem.m_photoModeController = this;
			photoModeListItem.SetupOptionSelector( values, startData );
			photoModeListItem.SetIsEnabled( true );
			OnAttributeUpdated( attribute, ( ( Float )( values[ photoModeListItem.GetSelectedOptionIndex() ].optionData ) ), doApply );
		}
	}

	protected event OnSetupOptionButton( attribute : Uint32, value : PhotoModeOptionSelectorData )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		photoModeListItem = GetMenuItem( attribute );
		if( photoModeListItem )
		{
			photoModeListItem.m_photoModeController = this;
			photoModeListItem.SetupOptionButton( value );
			photoModeListItem.SetIsEnabled( true );
			OnAttributeUpdated( attribute, ( ( Float )( photoModeListItem.GetSelectedOptionIndex() ) ) );
		}
	}

	protected event OnSetAttributeOptionEnabled( attributeKey : Uint32, enabled : Bool )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		var pageController : PhotoModeListController;
		photoModeListItem = GetMenuItem( attributeKey );
		if( photoModeListItem )
		{
			photoModeListItem.SetIsEnabled( enabled );
			if( !( enabled ) )
			{
				if( GetCurrentSelectedMenuListItem() == photoModeListItem )
				{
					pageController = ( ( PhotoModeListController )( GetMenuPage( ( ( Uint32 )( m_currentPage ) ) ) ) );
					pageController.SetSelectedIndex( pageController.GetFirstVisibleIndex() );
				}
			}
		}
	}

	protected event OnSetCategoryEnabled( category : Uint32, enabled : Bool )
	{
		m_topButtonsController.SetToggleEnabled( ( ( Int32 )( category ) ), enabled );
	}

	protected event OnPhotoModeFailedToOpenEvent()
	{
		var notificationEvent : UIInGameNotificationEvent;
		notificationEvent = new UIInGameNotificationEvent;
		notificationEvent.m_notificationType = UIInGameNotificationType.PhotoModeDisabledRestriction;
		GameInstance.GetUISystem( GetPlayerControlledObject().GetGame() ).QueueEvent( new UIInGameNotificationRemoveEvent );
		GameInstance.GetUISystem( GetPlayerControlledObject().GetGame() ).QueueEvent( notificationEvent );
	}

	protected event OnPhotoModeFailedToOpenComplete( data : inkGameNotificationData )
	{
		m_notificationToken = NULL;
		m_notificationUserData = NULL;
	}

	protected event OnPhotoModeLastInputDeviceEvent( wasKeyboardMouse : Bool )
	{
		var kbdWidget : inkWidgetRef;
		var padWidget : inkWidgetRef;
		inkWidgetRef.SetVisible( m_inputCameraKbd, false );
		inkWidgetRef.SetVisible( m_inputCameraPad, false );
		inkWidgetRef.SetVisible( m_inputStickersKbd, false );
		inkWidgetRef.SetVisible( m_inputStickersPad, false );
		inkWidgetRef.SetVisible( m_inputSaveLoadKbd, false );
		inkWidgetRef.SetVisible( m_inputSaveLoadPad, false );
		if( m_currentPage == ( ( Uint32 )( 4 ) ) )
		{
			kbdWidget = m_inputStickersKbd;
			padWidget = m_inputStickersPad;
		}
		else if( m_currentPage == ( ( Uint32 )( 5 ) ) )
		{
			kbdWidget = m_inputSaveLoadKbd;
			padWidget = m_inputSaveLoadPad;
		}
		else
		{
			kbdWidget = m_inputCameraKbd;
			padWidget = m_inputCameraPad;
		}
		if( wasKeyboardMouse )
		{
			inkWidgetRef.SetVisible( kbdWidget, true );
			inkWidgetRef.SetVisible( padWidget, false );
		}
		else
		{
			inkWidgetRef.SetVisible( kbdWidget, false );
			inkWidgetRef.SetVisible( padWidget, true );
		}
	}

	protected event OnSetInteractive( interactive : Bool )
	{
		var listItemWidget : weak< inkWidget >;
		var photoModeListItem : PhotoModeMenuListItem;
		var pageController : ListController;
		var i : Int32;
		var j : Int32;
		for( j = 0; j < m_menuPages.Size(); j += 1 )
		{
			pageController = GetMenuPage( ( ( Uint32 )( j ) ) );
			for( i = 0; i < pageController.Size(); i += 1 )
			{
				listItemWidget = pageController.GetItemAt( i );
				if( listItemWidget )
				{
					photoModeListItem = ( ( PhotoModeMenuListItem )( listItemWidget.GetControllerByType( 'PhotoModeMenuListItem' ) ) );
					photoModeListItem.SetInteractive( interactive );
				}
			}
		}
		m_topButtonsController.SetInteractive( interactive );
	}

	protected event OnChangeCameraControlHintVisibility( visible : Bool )
	{
		if( inkWidgetRef.IsValid( m_inputCameraControlKbd ) )
		{
			inkWidgetRef.SetVisible( m_inputCameraControlKbd, visible );
		}
		if( inkWidgetRef.IsValid( m_inputCameraControlPad ) )
		{
			inkWidgetRef.SetVisible( m_inputCameraControlPad, visible );
		}
	}

	public function GetMenuItem( attributeKey : Uint32 ) : PhotoModeMenuListItem
	{
		var listItemWidget : weak< inkWidget >;
		var photoModeListItem : PhotoModeMenuListItem;
		var data : PhotoModeMenuListItemData;
		var pageController : ListController;
		var i : Int32;
		var j : Int32;
		for( j = 0; j < m_menuPages.Size(); j += 1 )
		{
			pageController = GetMenuPage( ( ( Uint32 )( j ) ) );
			for( i = 0; i < pageController.Size(); i += 1 )
			{
				listItemWidget = pageController.GetItemAt( i );
				if( listItemWidget )
				{
					photoModeListItem = ( ( PhotoModeMenuListItem )( listItemWidget.GetControllerByType( 'PhotoModeMenuListItem' ) ) );
					data = ( ( PhotoModeMenuListItemData )( photoModeListItem.GetData() ) );
					if( data.attributeKey == attributeKey )
					{
						return photoModeListItem;
					}
				}
			}
		}
		return NULL;
	}

	protected function AddMenuPage( isAdditional : Bool ) : ListController
	{
		var newmenuList : weak< inkWidget >;
		var pageController : ListController;
		if( isAdditional )
		{
			newmenuList = SpawnFromLocal( inkWidgetRef.Get( m_additionalListRoot ), m_listContainerId );
		}
		else
		{
			newmenuList = SpawnFromLocal( inkWidgetRef.Get( m_menuListRoot ), m_listContainerId );
		}
		newmenuList.SetMargin( 0.0, 100.0, 0.0, 0.0 );
		m_menuPages.PushBack( newmenuList );
		pageController = ( ( ListController )( newmenuList.GetController() ) );
		pageController.RegisterToCallback( 'OnItemSelected', this, 'OnMenuItemSelected' );
		return pageController;
	}

	protected function GetMenuPage( pageIndex : Uint32 ) : ListController
	{
		return ( ( ListController )( m_menuPages[ ( ( Int32 )( pageIndex ) ) ].GetController() ) );
	}

	protected function AddMenuItem( const label : ref< String >, attributeKey : Uint32, page : Uint32, isAdditional : Bool )
	{
		var data : PhotoModeMenuListItemData;
		var pageController : ListController;
		if( ( ( Int32 )( page ) ) >= m_menuPages.Size() )
		{
			pageController = AddMenuPage( isAdditional );
		}
		else
		{
			pageController = GetMenuPage( page );
		}
		data = new PhotoModeMenuListItemData;
		data.label = label;
		data.attributeKey = attributeKey;
		pageController.PushData( data );
	}

	protected function GetCurrentSelectedMenuListItem() : PhotoModeMenuListItem
	{
		var itemIndex : Int32;
		var listItemWidget : weak< inkWidget >;
		var pageController : ListController;
		pageController = GetMenuPage( m_currentPage );
		itemIndex = pageController.GetSelectedIndex();
		if( itemIndex >= 0 )
		{
			listItemWidget = pageController.GetItemAt( itemIndex );
			if( listItemWidget )
			{
				return ( ( PhotoModeMenuListItem )( listItemWidget.GetControllerByType( 'PhotoModeMenuListItem' ) ) );
			}
		}
		return NULL;
	}

	protected event OnPMButtonRelease( evt : inkPointerEvent )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		var pageController : PhotoModeListController;
		pageController = ( ( PhotoModeListController )( GetMenuPage( m_currentPage ) ) );
		pageController.HandleInputWithVisibilityCheck( evt, NULL );
		m_topButtonsController.HandleInput( evt, this );
		photoModeListItem = GetCurrentSelectedMenuListItem();
		if( photoModeListItem )
		{
			photoModeListItem.HandleReleasedInput( evt, this );
		}
	}

	protected event OnPMButtonHold( evt : inkPointerEvent )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		photoModeListItem = GetCurrentSelectedMenuListItem();
		if( photoModeListItem )
		{
			photoModeListItem.HandleHoldInput( evt, this );
		}
	}

	protected event OnMenuItemSelected( index : Int32, target : ListItemController )
	{
		var data : PhotoModeMenuListItemData;
		var photoModeListItem : PhotoModeMenuListItem;
		photoModeListItem = ( ( PhotoModeMenuListItem )( target ) );
		data = ( ( PhotoModeMenuListItemData )( photoModeListItem.GetData() ) );
		OnAttributeSelected( data.attributeKey );
	}

	protected event OnMenuHovered( e : inkPointerEvent )
	{
		if( !( m_IsHoverOver ) )
		{
			OnHoverStateChanged( true );
			SetCursorContext( 'Hover' );
		}
		m_IsHoverOver = true;
	}

	protected event OnMenuHoverOut( e : inkPointerEvent )
	{
		if( m_IsHoverOver )
		{
			OnHoverStateChanged( false );
			SetCursorContext( 'Default' );
		}
		m_IsHoverOver = false;
	}

	protected event OnOptionHold( evt : inkPointerEvent )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		var data : PhotoModeMenuListItemData;
		var progress : Float;
		progress = evt.GetHoldProgress();
		if( evt.IsAction( 'PhotoMode_SaveSettings' ) || evt.IsAction( 'PhotoMode_LoadSettings' ) )
		{
			photoModeListItem = GetCurrentSelectedMenuListItem();
			if( photoModeListItem )
			{
				if( ( progress >= 1.0 ) && !( m_holdSafeguard ) )
				{
					m_holdSafeguard = true;
					photoModeListItem.SetHoldProgress( 1.0 );
					data = ( ( PhotoModeMenuListItemData )( photoModeListItem.GetData() ) );
					if( evt.IsAction( 'PhotoMode_SaveSettings' ) )
					{
						OnHoldComplete( data.attributeKey, 'PhotoMode_SaveSettings' );
					}
					else if( evt.IsAction( 'PhotoMode_LoadSettings' ) )
					{
						OnHoldComplete( data.attributeKey, 'PhotoMode_LoadSettings' );
					}
				}
				else
				{
					photoModeListItem.SetHoldProgress( progress );
				}
			}
		}
	}

	protected event OnOptionHoldRelease( evt : inkPointerEvent )
	{
		var photoModeListItem : PhotoModeMenuListItem;
		m_holdSafeguard = false;
		photoModeListItem = GetCurrentSelectedMenuListItem();
		if( photoModeListItem )
		{
			photoModeListItem.SetHoldProgress( 0.0 );
		}
	}

}

class PhotoModeMenuListItem extends ListItemController
{
	private editable var m_ScrollBarRef : inkWidgetRef;
	private editable var m_CounterLabelRef : inkTextRef;
	private editable var m_TextLabelRef : inkTextRef;
	private editable var m_OptionSelectorRef : inkWidgetRef;
	private editable var m_LeftArrow : inkWidgetRef;
	private editable var m_RightArrow : inkWidgetRef;
	private editable var m_LeftButton : inkWidgetRef;
	private editable var m_RightButton : inkWidgetRef;
	private editable var m_OptionLabelRef : inkTextRef;
	private editable var m_SelectedWidgetRef : inkWidgetRef;
	private editable var m_TextRootWidgetRef : inkWidgetRef;
	private editable var m_SliderRootWidgetRef : inkWidgetRef;
	private editable var m_OptionSelectorRootWidgetRef : inkWidgetRef;
	private editable var m_HoldButtonRootWidgetRef : inkWidgetRef;
	private editable var m_ScrollBarLineRef : inkWidgetRef;
	private editable var m_ScrollBarHandleRef : inkWidgetRef;
	private editable var m_ScrollSlidingAreaRef : inkWidgetRef;
	private editable var m_HoldProgressRef : inkWidgetRef;
	private editable var m_GridRoot : inkWidgetRef;
	private editable var m_GridTopRow : inkWidgetRef;
	private editable var m_GridBottomRow : inkWidgetRef;
	private var m_ScrollBar : weak< inkSliderController >;
	private var m_OptionSelector : weak< SelectorController >;
	private var m_OptionSelectorValues : array< PhotoModeOptionSelectorData >;
	private var m_GridSelector : weak< PhotoModeGridList >;
	private var m_SliderValue : Float;
	private var m_StepValue : Float;
	private var m_SliderShowPercents : Bool;
	var m_photoModeController : weak< gameuiPhotoModeMenuController >;
	private var m_doApply : Bool;
	private var m_holdBgInitMargin : inkMargin;
	private var m_allowHold : Bool;
	private var m_inputDirection : Int32;
	private var m_inputStepTime : Float;
	private var m_inputHoldTime : Float;
	private var m_arrowClickedTime : Float;
	private var m_isSelected : Bool;
	private var m_fadeAnim : inkAnimProxy;
	private var m_RightArrowInitOpacity : Float;
	private var m_LeftArrowInitOpacity : Float;
	private var m_ScrollBarHandleInitOpacity : Float;
	private var m_ScrollBarLineInitOpacity : Float;

	protected event OnInitialize()
	{
		m_RightArrowInitOpacity = inkWidgetRef.GetOpacity( m_RightArrow );
		m_LeftArrowInitOpacity = inkWidgetRef.GetOpacity( m_LeftArrow );
		m_ScrollBarHandleInitOpacity = inkWidgetRef.GetOpacity( m_ScrollBarHandleRef );
		m_ScrollBarLineInitOpacity = inkWidgetRef.GetOpacity( m_ScrollBarLineRef );
		if( inkWidgetRef.IsValid( m_ScrollBarRef ) )
		{
			m_ScrollBar = ( ( inkSliderController )( inkWidgetRef.GetControllerByType( m_ScrollBarRef, 'inkSliderController' ) ) );
		}
		if( m_ScrollBar )
		{
			m_ScrollBar.RegisterToCallback( 'OnSliderValueChanged', this, 'OnScrollBarValueChanged' );
			m_ScrollBar.RegisterToCallback( 'OnSliderHandleReleased', this, 'OnSliderHandleReleased' );
		}
		if( inkWidgetRef.IsValid( m_OptionSelectorRef ) )
		{
			m_OptionSelector = ( ( SelectorController )( inkWidgetRef.GetController( m_OptionSelectorRef ) ) );
		}
		inkWidgetRef.SetVisible( m_SelectedWidgetRef, false );
		inkWidgetRef.SetOpacity( m_SelectedWidgetRef, 0.0 );
		RegisterToCallback( 'OnSelected', this, 'OnSelected' );
		RegisterToCallback( 'OnDeselected', this, 'OnDeselected' );
		RegisterToCallback( 'OnAddedToList', this, 'OnAddedToList' );
		RegisterToCallback( 'OnHoverOver', this, 'OnHoverOver' );
		RegisterToCallback( 'OnHoverOut', this, 'OnHoverOut' );
		if( inkWidgetRef.IsValid( m_LeftArrow ) )
		{
			inkWidgetRef.RegisterToCallback( m_LeftButton, 'OnRelease', this, 'OnOptionLeft' );
			inkWidgetRef.SetOpacity( m_LeftArrow, 0.004 );
		}
		if( inkWidgetRef.IsValid( m_RightArrow ) )
		{
			inkWidgetRef.RegisterToCallback( m_RightButton, 'OnRelease', this, 'OnOptionRight' );
			inkWidgetRef.SetOpacity( m_RightArrow, 0.004 );
		}
		if( inkWidgetRef.IsValid( m_HoldProgressRef ) )
		{
			m_holdBgInitMargin = inkWidgetRef.GetMargin( m_HoldProgressRef );
		}
		inkWidgetRef.SetOpacity( m_ScrollBarHandleRef, m_ScrollBarLineInitOpacity );
		inkWidgetRef.SetOpacity( m_ScrollBarLineRef, 0.015 );
		inkWidgetRef.Get( m_ScrollBarHandleRef ).BindProperty( 'tintColor', 'MainColors.Red' );
		inkTextRef.Get( m_CounterLabelRef ).BindProperty( 'tintColor', 'MainColors.Red' );
		m_allowHold = false;
		m_arrowClickedTime = 0.0;
		m_isSelected = false;
		m_doApply = true;
		ResetInputHold();
		super.OnInitialize();
	}

	protected event OnSliderHandleReleased()
	{
		GameInstance.GetTelemetrySystem( m_photoModeController.GetPlayerControlledObject().GetGame() ).LogPhotomodeAttributeChanged();
	}

	public function SetReversedUI( isRevesed : Bool )
	{
		if( isRevesed )
		{
			inkWidgetRef.SetMargin( m_TextRootWidgetRef, 1040.0, 0.0, 0.0, 0.0 );
			inkTextRef.SetAnchor( m_TextLabelRef, inkEAnchor.CenterRight );
			inkTextRef.SetAnchorPoint( m_TextLabelRef, 1.0, 0.5 );
			inkTextRef.SetMargin( m_TextLabelRef, 0.0, 0.0, 100.0, 0.0 );
			inkWidgetRef.SetMargin( m_SliderRootWidgetRef, 80.0, 0.0, 0.0, 0.0 );
			inkWidgetRef.SetMargin( m_OptionSelectorRootWidgetRef, 80.0, 0.0, 0.0, 0.0 );
			inkWidgetRef.SetMargin( m_HoldButtonRootWidgetRef, 0.0, 0.0, 0.0, 0.0 );
		}
		else
		{
			inkWidgetRef.SetMargin( m_TextRootWidgetRef, 0.0, 0.0, 0.0, 0.0 );
			inkTextRef.SetAnchor( m_TextLabelRef, inkEAnchor.CenterLeft );
			inkTextRef.SetAnchorPoint( m_TextLabelRef, 0.0, 0.5 );
			inkTextRef.SetMargin( m_TextLabelRef, 30.0, 0.0, 0.0, 0.0 );
			inkWidgetRef.SetMargin( m_SliderRootWidgetRef, 530.0, 0.0, 0.0, 0.0 );
			inkWidgetRef.SetMargin( m_OptionSelectorRootWidgetRef, 530.0, 0.0, 0.0, 0.0 );
			inkWidgetRef.SetMargin( m_HoldButtonRootWidgetRef, 450.0, 0.0, 0.0, 0.0 );
		}
	}

	private function PlayFadeAnimation( widget : inkWidgetRef, opacity : Float )
	{
		var animDef : inkAnimDef;
		var animInterp : inkAnimTransparency;
		if( inkWidgetRef.GetOpacity( widget ) == opacity )
		{
			return;
		}
		animDef = new inkAnimDef;
		animInterp = new inkAnimTransparency;
		animInterp.SetStartTransparency( inkWidgetRef.GetOpacity( widget ) );
		animInterp.SetEndTransparency( opacity );
		animInterp.SetDuration( 0.30000001 );
		animInterp.SetDirection( inkanimInterpolationDirection.To );
		animInterp.SetUseRelativeDuration( true );
		animDef.AddInterpolator( animInterp );
		if( m_fadeAnim != NULL )
		{
			m_fadeAnim.Stop();
		}
		m_fadeAnim = inkWidgetRef.PlayAnimation( widget, animDef );
	}

	private function SetSelectedVisualState( isSelected : Bool )
	{
		inkWidgetRef.SetVisible( m_SelectedWidgetRef, true );
		if( isSelected )
		{
			if( m_OptionSelector.GetValuesCount() > 1 )
			{
				inkWidgetRef.SetOpacity( m_RightArrow, m_RightArrowInitOpacity );
				inkWidgetRef.SetOpacity( m_LeftArrow, m_LeftArrowInitOpacity );
			}
			else
			{
				inkWidgetRef.SetOpacity( m_RightArrow, 0.004 );
				inkWidgetRef.SetOpacity( m_LeftArrow, 0.004 );
			}
			inkWidgetRef.SetOpacity( m_ScrollBarHandleRef, m_ScrollBarHandleInitOpacity );
			inkWidgetRef.SetOpacity( m_ScrollBarLineRef, m_ScrollBarLineInitOpacity );
			inkWidgetRef.Get( m_ScrollBarHandleRef ).BindProperty( 'tintColor', 'MainColors.Blue' );
			inkTextRef.Get( m_CounterLabelRef ).BindProperty( 'tintColor', 'MainColors.DarkRed' );
			inkTextRef.Get( m_OptionLabelRef ).BindProperty( 'tintColor', 'MainColors.Blue' );
			if( !( m_isSelected ) )
			{
				inkWidgetRef.SetOpacity( m_SelectedWidgetRef, 0.0 );
			}
			if( m_GridSelector )
			{
				m_GridSelector.OnSelected();
			}
		}
		else
		{
			inkWidgetRef.SetOpacity( m_RightArrow, 0.004 );
			inkWidgetRef.SetOpacity( m_LeftArrow, 0.004 );
			inkWidgetRef.SetOpacity( m_ScrollBarHandleRef, m_ScrollBarLineInitOpacity );
			inkWidgetRef.SetOpacity( m_ScrollBarLineRef, 0.015 );
			inkWidgetRef.Get( m_ScrollBarHandleRef ).BindProperty( 'tintColor', 'MainColors.Red' );
			inkTextRef.Get( m_CounterLabelRef ).BindProperty( 'tintColor', 'MainColors.Red' );
			inkTextRef.Get( m_OptionLabelRef ).BindProperty( 'tintColor', 'MainColors.Red' );
			if( m_GridSelector )
			{
				m_GridSelector.OnDeSelected();
			}
		}
	}

	protected event OnSelected( target : weak< ListItemController > )
	{
		SetSelectedVisualState( true );
		PlayFadeAnimation( m_SelectedWidgetRef, 1.0 );
		SetHoldProgress( 0.0 );
		ResetInputHold();
		m_isSelected = true;
	}

	protected event OnDeselected( parent : weak< ListItemController > )
	{
		SetSelectedVisualState( false );
		PlayFadeAnimation( m_SelectedWidgetRef, 0.0 );
		inkWidgetRef.SetMargin( m_HoldProgressRef, m_holdBgInitMargin );
		SetHoldProgress( 0.0 );
		ResetInputHold();
		m_isSelected = false;
	}

	protected event OnAddedToList( target : weak< ListItemController > ) {}

	public function OnVisbilityChanged( visible : Bool )
	{
		if( m_GridSelector )
		{
			m_GridSelector.OnVisbilityChanged( visible );
		}
	}

	public function SetInteractive( interactive : Bool )
	{
		GetRootWidget().SetInteractive( interactive );
		inkWidgetRef.SetInteractive( m_TextRootWidgetRef, interactive );
		inkTextRef.SetInteractive( m_OptionLabelRef, interactive );
		if( m_ScrollBar.GetRootWidget().IsVisible() )
		{
			inkWidgetRef.SetInteractive( m_ScrollSlidingAreaRef, interactive );
		}
		if( m_OptionSelector.GetRootWidget().IsVisible() )
		{
			inkWidgetRef.SetInteractive( m_LeftButton, interactive );
			inkWidgetRef.SetInteractive( m_RightButton, interactive );
		}
	}

	public function SetIsEnabled( enabled : Bool )
	{
		GetRootWidget().SetVisible( enabled );
	}

	public function ForceValue( value : Float, doApply : Bool )
	{
		var data : PhotoModeMenuListItemData;
		var setIndex : Int32;
		var i : Int32;
		data = ( ( PhotoModeMenuListItemData )( GetData() ) );
		if( m_ScrollBar.GetRootWidget().IsVisible() )
		{
			m_doApply = doApply;
			m_ScrollBar.ChangeValue( value );
			m_photoModeController.OnAttributeUpdated( data.attributeKey, value, doApply );
			m_doApply = true;
		}
		if( m_OptionSelector.GetRootWidget().IsVisible() )
		{
			setIndex = 0;
			for( i = 0; i < m_OptionSelectorValues.Size(); i += 1 )
			{
				if( m_OptionSelectorValues[ i ].optionData == ( ( Int32 )( value ) ) )
				{
					setIndex = i;
				}
			}
			m_OptionSelector.SetCurrIndex( setIndex );
			m_photoModeController.OnAttributeUpdated( data.attributeKey, ( ( Float )( m_OptionSelectorValues[ setIndex ].optionData ) ), doApply );
		}
	}

	public function SetupGridSelector( const gridData : ref< array< PhotoModeOptionGridButtonData > >, elementsCount : Uint32, elementsInRow : Uint32 )
	{
		var widgetToHide : weak< inkWidget >;
		var rows : Int32;
		var visibleSize : Float;
		var rootSize : Vector2;
		rootSize = GetRootWidget().GetSize();
		rows = ( ( Int32 )( elementsCount ) ) / ( ( Int32 )( elementsInRow ) );
		if( ( ( ( Int32 )( elementsCount ) ) % ( ( Int32 )( elementsInRow ) ) ) != 0 )
		{
			rows += 1;
		}
		if( m_ScrollBar )
		{
			widgetToHide = m_ScrollBar.GetRootWidget();
			widgetToHide.SetVisible( false );
			( ( weak< weak< inkCompoundWidget > > )( widgetToHide ) ).RemoveAllChildren();
			inkTextRef.SetVisible( m_CounterLabelRef, false );
			inkWidgetRef.SetInteractive( m_ScrollSlidingAreaRef, false );
		}
		if( m_OptionSelector )
		{
			widgetToHide = m_OptionSelector.GetRootWidget();
			widgetToHide.SetVisible( false );
			( ( weak< weak< inkCompoundWidget > > )( widgetToHide ) ).RemoveAllChildren();
		}
		if( inkWidgetRef.IsValid( m_GridRoot ) )
		{
			m_GridSelector = ( ( PhotoModeGridList )( inkWidgetRef.GetControllerByType( m_GridRoot, 'PhotoModeGridList' ) ) );
			if( ( ( Int32 )( elementsInRow ) ) > 5 )
			{
				inkWidgetRef.SetMargin( m_GridRoot, 30.0, 0.0, 0.0, 0.0 );
				inkWidgetRef.SetSize( m_GridRoot, 1475.0, 80.0 );
				rootSize.X += 50.0;
			}
			visibleSize = m_GridSelector.Setup( this, rows, ( ( Int32 )( elementsInRow ) ) );
			m_GridSelector.SetGridData( gridData );
			GetRootWidget().SetSize( rootSize.X, visibleSize );
		}
	}

	public function SetupScrollBar( startValue : Float, minValue : Float, maxValue : Float, step : Float, showPercents : Bool )
	{
		var widgetToHide : weak< inkWidget >;
		m_StepValue = step;
		m_SliderShowPercents = showPercents;
		if( m_ScrollBar )
		{
			m_ScrollBar.Setup( minValue, maxValue, startValue, step );
		}
		if( m_OptionSelector )
		{
			widgetToHide = m_OptionSelector.GetRootWidget();
			widgetToHide.SetVisible( false );
			( ( weak< weak< inkCompoundWidget > > )( widgetToHide ) ).RemoveAllChildren();
		}
		if( inkWidgetRef.IsValid( m_GridRoot ) )
		{
			inkWidgetRef.SetVisible( m_GridRoot, false );
		}
	}

	public function SetupOptionSelector( const values : ref< array< PhotoModeOptionSelectorData > >, startData : Int32 )
	{
		var widgetToHide : weak< inkWidget >;
		var i : Int32;
		var startIndex : Int32;
		m_StepValue = 1.0;
		if( m_ScrollBar )
		{
			widgetToHide = m_ScrollBar.GetRootWidget();
			widgetToHide.SetVisible( false );
			( ( weak< weak< inkCompoundWidget > > )( widgetToHide ) ).RemoveAllChildren();
			inkTextRef.SetVisible( m_CounterLabelRef, false );
			inkWidgetRef.SetInteractive( m_ScrollSlidingAreaRef, false );
		}
		if( m_OptionSelector )
		{
			startIndex = 0;
			m_OptionSelectorValues = values;
			m_OptionSelector.Clear();
			for( i = 0; i < m_OptionSelectorValues.Size(); i += 1 )
			{
				if( m_OptionSelectorValues[ i ].optionData == startData )
				{
					startIndex = i;
				}
				m_OptionSelector.AddValue( m_OptionSelectorValues[ i ].optionText );
			}
			m_OptionSelector.SetCurrIndex( startIndex );
			if( inkWidgetRef.IsVisible( m_SelectedWidgetRef ) )
			{
				OnSelected( NULL );
			}
		}
		if( inkWidgetRef.IsValid( m_GridRoot ) )
		{
			inkWidgetRef.SetVisible( m_GridRoot, false );
		}
	}

	public function SetupOptionButton( const value : ref< PhotoModeOptionSelectorData > )
	{
		var values : array< PhotoModeOptionSelectorData >;
		values.PushBack( value );
		SetupOptionSelector( values, 0 );
		inkWidgetRef.SetVisible( m_LeftArrow, false );
		inkWidgetRef.SetVisible( m_RightArrow, false );
		inkWidgetRef.SetVisible( m_LeftButton, false );
		inkWidgetRef.SetVisible( m_RightButton, false );
		m_allowHold = true;
	}

	public function GetSliderValue() : Float
	{
		return m_SliderValue;
	}

	public function GetSelectedOptionIndex() : Int32
	{
		if( m_OptionSelector )
		{
			return m_OptionSelector.GetCurrIndex();
		}
		return -1;
	}

	public function GetGridSelector() : weak< PhotoModeGridList >
	{
		return m_GridSelector;
	}

	public function SetGridButtonImage( buttonIndex : Uint32, atlasPath : ResRef, imagePart : CName, buttonData : Int32 )
	{
		if( m_GridSelector )
		{
			m_GridSelector.SetGridButtonImage( buttonIndex, atlasPath, imagePart, buttonData );
		}
	}

	public function SetSelectedGridButton( index : Int32 )
	{
		if( m_GridSelector )
		{
			m_GridSelector.SelectButton( index );
		}
	}

	public function SetHoldProgress( progress : Float )
	{
		var margin : inkMargin;
		if( m_allowHold )
		{
			margin = m_holdBgInitMargin;
			margin.right = m_holdBgInitMargin.right * ( 1.0 - progress );
			inkWidgetRef.SetMargin( m_HoldProgressRef, margin );
		}
	}

	public function HandleHoldInput( e : inkPointerEvent, optional gameCtrl : weak< inkGameController > )
	{
		if( m_ScrollBar.GetRootWidget().IsVisible() )
		{
			if( e.IsAction( 'PhotoMode_Left_Button' ) )
			{
				m_inputDirection = -1;
			}
			else if( e.IsAction( 'PhotoMode_Right_Button' ) )
			{
				m_inputDirection = 1;
			}
		}
	}

	public function HandleReleasedInput( e : inkPointerEvent, optional gameCtrl : weak< inkGameController > )
	{
		var data : PhotoModeMenuListItemData;
		var optionValue : Int32;
		data = ( ( PhotoModeMenuListItemData )( GetData() ) );
		if( m_OptionSelector.GetRootWidget().IsVisible() )
		{
			if( e.IsAction( 'PhotoMode_Left_Button' ) )
			{
				m_OptionSelector.Prior();
				StartArrowClickedEffect( m_LeftArrow );
				optionValue = m_OptionSelectorValues[ m_OptionSelector.GetCurrIndex() ].optionData;
				m_photoModeController.OnAttributeUpdated( data.attributeKey, ( ( Float )( optionValue ) ) );
				GameInstance.GetTelemetrySystem( m_photoModeController.GetPlayerControlledObject().GetGame() ).LogPhotomodeAttributeChanged();
			}
			else if( e.IsAction( 'PhotoMode_Right_Button' ) )
			{
				m_OptionSelector.Next();
				StartArrowClickedEffect( m_RightArrow );
				optionValue = m_OptionSelectorValues[ m_OptionSelector.GetCurrIndex() ].optionData;
				m_photoModeController.OnAttributeUpdated( data.attributeKey, ( ( Float )( optionValue ) ) );
				GameInstance.GetTelemetrySystem( m_photoModeController.GetPlayerControlledObject().GetGame() ).LogPhotomodeAttributeChanged();
			}
		}
		if( m_ScrollBar.GetRootWidget().IsVisible() )
		{
			if( e.IsAction( 'PhotoMode_Left_Button' ) || e.IsAction( 'PhotoMode_Right_Button' ) )
			{
				ResetInputHold();
				GameInstance.GetTelemetrySystem( m_photoModeController.GetPlayerControlledObject().GetGame() ).LogPhotomodeAttributeChanged();
			}
		}
		if( m_GridSelector )
		{
			m_GridSelector.HandleReleasedInput( e, gameCtrl );
		}
	}

	protected event OnScrollBarValueChanged( controller : weak< inkSliderController >, progress : Float, newValue : Float )
	{
		var intNewValue : Int32;
		var intFractionValue : Int32;
		var stepDigits : Int32;
		var minusSign : String;
		var data : PhotoModeMenuListItemData;
		var scrollBarRange : Float;
		var newValuePercent : Float;
		if( m_SliderShowPercents )
		{
			scrollBarRange = MaxF( AbsF( m_ScrollBar.GetMaxValue() ), AbsF( m_ScrollBar.GetMinValue() ) );
			newValuePercent = ( 100.00099945 * newValue ) / scrollBarRange;
			intNewValue = RoundMath( newValuePercent );
			if( ( intNewValue == 0 ) && ( newValue < 0.0 ) )
			{
				minusSign = "-";
			}
			inkTextRef.SetText( m_CounterLabelRef, minusSign + IntToString( intNewValue ) );
		}
		else
		{
			intNewValue = ( ( Int32 )( newValue ) );
			intFractionValue = ( ( Int32 )( 100.00099945 * ( AbsF( newValue ) % 1.0 ) ) );
			stepDigits = ( ( ( ( ( Int32 )( ( m_StepValue * 100.0 ) ) ) % 10 ) == 0 ) ? ( 10 ) : ( 1 ) );
			if( ( intNewValue == 0 ) && ( newValue < 0.0 ) )
			{
				minusSign = "-";
			}
			if( ( m_StepValue % 1.0 ) == 0.0 )
			{
				inkTextRef.SetText( m_CounterLabelRef, minusSign + IntToString( intNewValue ) );
			}
			else
			{
				if( ( intFractionValue < 10 ) && ( intFractionValue != 0 ) )
				{
					inkTextRef.SetText( m_CounterLabelRef, ( ( minusSign + IntToString( intNewValue ) ) + ".0" ) + IntToString( intFractionValue ) );
				}
				else
				{
					intFractionValue = intFractionValue / stepDigits;
					inkTextRef.SetText( m_CounterLabelRef, ( ( minusSign + IntToString( intNewValue ) ) + "." ) + IntToString( intFractionValue ) );
				}
			}
		}
		m_SliderValue = newValue;
		data = ( ( PhotoModeMenuListItemData )( GetData() ) );
		m_photoModeController.OnAttributeUpdated( data.attributeKey, m_SliderValue, m_doApply );
	}

	protected event OnOptionLeft( e : inkPointerEvent )
	{
		var data : PhotoModeMenuListItemData;
		var optionValue : Int32;
		data = ( ( PhotoModeMenuListItemData )( GetData() ) );
		if( e.IsAction( 'click' ) && m_OptionSelector.GetRootWidget().IsVisible() )
		{
			StartArrowClickedEffect( m_LeftArrow );
			optionValue = m_OptionSelectorValues[ m_OptionSelector.GetCurrIndex() ].optionData;
			m_photoModeController.OnAttributeUpdated( data.attributeKey, ( ( Float )( optionValue ) ) );
			GameInstance.GetTelemetrySystem( m_photoModeController.GetPlayerControlledObject().GetGame() ).LogPhotomodeAttributeChanged();
		}
	}

	protected event OnOptionRight( e : inkPointerEvent )
	{
		var data : PhotoModeMenuListItemData;
		var optionValue : Int32;
		data = ( ( PhotoModeMenuListItemData )( GetData() ) );
		if( e.IsAction( 'click' ) && m_OptionSelector.GetRootWidget().IsVisible() )
		{
			StartArrowClickedEffect( m_RightArrow );
			optionValue = m_OptionSelectorValues[ m_OptionSelector.GetCurrIndex() ].optionData;
			m_photoModeController.OnAttributeUpdated( data.attributeKey, ( ( Float )( optionValue ) ) );
			GameInstance.GetTelemetrySystem( m_photoModeController.GetPlayerControlledObject().GetGame() ).LogPhotomodeAttributeChanged();
		}
	}

	public function GridElementAction( elementIndex : Int32, buttonData : Int32 )
	{
		var data : PhotoModeMenuListItemData;
		var photoModeListItem : PhotoModeMenuListItem;
		data = ( ( PhotoModeMenuListItemData )( GetData() ) );
		if( data.attributeKey == ( ( Uint32 )( 35 ) ) )
		{
			m_photoModeController.SetCurrentMenuPage( ( ( Uint32 )( 6 ) ) );
			m_photoModeController.OnAttributeUpdated( data.attributeKey, ( ( Float )( elementIndex ) ) );
			photoModeListItem = m_photoModeController.GetMenuItem( ( ( Uint32 )( 36 ) ) );
			photoModeListItem.SetSelectedGridButton( buttonData + 1 );
		}
		else if( data.attributeKey == ( ( Uint32 )( 36 ) ) )
		{
			m_photoModeController.SetCurrentMenuPage( ( ( Uint32 )( 4 ) ) );
			m_photoModeController.OnAttributeUpdated( data.attributeKey, ( ( Float )( buttonData ) ) );
			GameInstance.GetTelemetrySystem( m_photoModeController.GetPlayerControlledObject().GetGame() ).LogPhotomodeAttributeChanged();
		}
	}

	public function GridElementSelected( elementIndex : Int32 )
	{
		var data : PhotoModeMenuListItemData;
		data = ( ( PhotoModeMenuListItemData )( GetData() ) );
		if( data.attributeKey == ( ( Uint32 )( 35 ) ) )
		{
			m_photoModeController.OnAttributeUpdated( data.attributeKey, ( ( Float )( elementIndex ) ) );
		}
	}

	private function StartArrowClickedEffect( widget : inkWidgetRef )
	{
		inkWidgetRef.SetOpacity( widget, 0.004 );
		m_arrowClickedTime = 0.1;
	}

	public function ResetInputHold()
	{
		m_inputDirection = 0;
		m_inputHoldTime = 0.0;
		m_inputStepTime = 0.0;
	}

	public function Update( timeDelta : Float )
	{
		if( m_GridSelector )
		{
			m_GridSelector.Update( timeDelta );
		}
		if( m_arrowClickedTime > 0.0 )
		{
			m_arrowClickedTime -= timeDelta;
			if( m_arrowClickedTime <= 0.0 )
			{
				SetSelectedVisualState( m_isSelected );
				m_arrowClickedTime = 0.0;
			}
		}
		if( m_inputDirection != 0 )
		{
			m_inputHoldTime += timeDelta;
			m_inputStepTime -= timeDelta;
			if( m_inputStepTime <= 0.0 )
			{
				if( m_inputHoldTime > 0.40000001 )
				{
					m_inputStepTime = 0.015;
				}
				else if( m_inputHoldTime > 0.2 )
				{
					m_inputStepTime = 0.07;
				}
				else
				{
					m_inputStepTime = 0.2;
				}
				if( m_inputDirection == -1 )
				{
					m_ScrollBar.Prior();
				}
				else if( m_inputDirection == 1 )
				{
					m_ScrollBar.Next();
				}
			}
		}
	}

}

