class MasterDeviceInkGameControllerBase extends DeviceInkGameControllerBase
{
	protected var m_thumbnailWidgetsData : array< SThumbnailWidgetPackage >;
	private var m_onThumbnailWidgetsUpdateListener : CallbackHandle;
	private var m_onCleanPasswordListener : CallbackHandle;
	private var m_keypadController : weak< KeypadDeviceController >;

	protected event OnInitialize()
	{
		super.OnInitialize();
	}

	protected event OnUninitialize()
	{
		super.OnUninitialize();
	}

	protected event OnDeviceWidgetSpawned( widget : inkWidget, userData : IScriptable )
	{
		super.OnDeviceWidgetSpawned( widget, userData );
		TrySaveKeypadController( widget );
	}

	private function TrySaveKeypadController( widget : inkWidget )
	{
		var keypadController : KeypadDeviceController;
		keypadController = ( ( KeypadDeviceController )( widget.GetController() ) );
		if( keypadController )
		{
			m_keypadController = keypadController;
		}
	}

	protected function CreateThumbnailWidgetAsync( parentWidget : weak< inkWidget >, widgetData : SThumbnailWidgetPackage )
	{
		var screenDef : ScreenDefinitionPackage;
		var spawnData : AsyncSpawnData;
		if( HasThumbnailWidgetData( widgetData ) )
		{
			return;
		}
		screenDef = GetScreenDefinition();
		spawnData = new AsyncSpawnData;
		spawnData.Initialize( this, 'OnThumbnailWidgetSpawned', widgetData, this );
		widgetData.libraryID = RequestWidgetFromLibrary( parentWidget, TweakDBInterface.GetWidgetDefinitionRecord( widgetData.widgetTweakDBID ), screenDef.screenDefinition.TerminalScreenType(), screenDef.style, widgetData.libraryID, widgetData.libraryPath, spawnData );
		AddThumbnailWidgetData( widgetData );
	}

	protected event OnThumbnailWidgetSpawned( widget : inkWidget, userData : IScriptable )
	{
		var spawnData : AsyncSpawnData;
		var widgetData : SThumbnailWidgetPackage;
		if( widget != NULL )
		{
			widget.SetSizeRule( inkESizeRule.Stretch );
		}
		spawnData = ( ( AsyncSpawnData )( userData ) );
		if( spawnData != NULL )
		{
			widgetData = ( ( SThumbnailWidgetPackage )spawnData.m_widgetData );
			widgetData.widget = widget;
			widgetData.libraryID = spawnData.m_libraryID;
			UpdateThumbnailWidgetData( widgetData, GetThumbnailWidgetDataIndex( widgetData ) );
			InitializeThumbnailWidget( widget, widgetData );
		}
	}

	protected function CreateThumbnailWidget( parentWidget : weak< inkWidget >, const widgetData : ref< SThumbnailWidgetPackage > ) : weak< inkWidget >
	{
		var widget : inkWidget;
		var screenDef : ScreenDefinitionPackage;
		screenDef = GetScreenDefinition();
		widget = FindWidgetInLibrary( parentWidget, TweakDBInterface.GetWidgetDefinitionRecord( widgetData.widgetTweakDBID ), screenDef.screenDefinition.TerminalScreenType(), screenDef.style, widgetData.libraryID, widgetData.libraryPath );
		if( widget != NULL )
		{
			widget.SetSizeRule( inkESizeRule.Stretch );
		}
		return widget;
	}

	protected function UpdateThumbnailWidgetData( const widgetData : ref< SThumbnailWidgetPackage >, index : Int32 )
	{
		if( ( index >= 0 ) && ( index < m_thumbnailWidgetsData.Size() ) )
		{
			m_thumbnailWidgetsData[ index ] = widgetData;
		}
	}

	protected function GetThumbnailWidgetDataIndex( widgetData : SThumbnailWidgetPackage ) : Int32
	{
		var i : Int32;
		var screenDef : ScreenDefinitionPackage;
		screenDef = GetScreenDefinition();
		widgetData.libraryID = GetCurrentFullLibraryID( TweakDBInterface.GetWidgetDefinitionRecord( widgetData.widgetTweakDBID ), screenDef.screenDefinition.TerminalScreenType(), screenDef.style );
		for( i = 0; i < m_thumbnailWidgetsData.Size(); i += 1 )
		{
			if( ( ( ( m_thumbnailWidgetsData[ i ].ownerID == widgetData.ownerID && m_thumbnailWidgetsData[ i ].widgetName == widgetData.widgetName ) && ( m_thumbnailWidgetsData[ i ].widgetTweakDBID == widgetData.widgetTweakDBID ) ) && m_thumbnailWidgetsData[ i ].libraryPath == widgetData.libraryPath ) && m_thumbnailWidgetsData[ i ].libraryID == widgetData.libraryID )
			{
				return i;
			}
		}
		return -1;
	}

	protected function GetThumbnailWidget( const widgetData : ref< SThumbnailWidgetPackage > ) : weak< inkWidget >
	{
		var index : Int32;
		index = GetThumbnailWidgetDataIndex( widgetData );
		if( ( index >= 0 ) && ( index < m_thumbnailWidgetsData.Size() ) )
		{
			return m_thumbnailWidgetsData[ index ].widget;
		}
		return NULL;
	}

	protected function HasThumbnailWidgetData( const widgetData : ref< SThumbnailWidgetPackage > ) : Bool
	{
		return GetThumbnailWidgetDataIndex( widgetData ) >= 0;
	}

	protected function HasThumbnailWidget( const widgetData : ref< SThumbnailWidgetPackage > ) : Bool
	{
		return GetThumbnailWidget( widgetData ) != NULL;
	}

	protected function AddThumbnailWidgetData( const widgetData : ref< SThumbnailWidgetPackage > )
	{
		m_thumbnailWidgetsData.PushBack( widgetData );
	}

	protected function AddThumbnailWidget( widget : inkWidget, widgetData : SThumbnailWidgetPackage ) : weak< inkWidget >
	{
		var screenDef : ScreenDefinitionPackage;
		screenDef = GetScreenDefinition();
		widgetData.libraryID = GetCurrentFullLibraryID( TweakDBInterface.GetWidgetDefinitionRecord( widgetData.widgetTweakDBID ), screenDef.screenDefinition.TerminalScreenType(), screenDef.style );
		widgetData.widget = widget;
		m_thumbnailWidgetsData.PushBack( widgetData );
		return widgetData.widget;
	}

	protected function InitializeThumbnailWidget( widget : inkWidget, const widgetData : ref< SThumbnailWidgetPackage > )
	{
		var controller : DeviceThumbnailWidgetControllerBase;
		controller = ( ( DeviceThumbnailWidgetControllerBase )( widget.GetController() ) );
		if( controller != NULL )
		{
			controller.Initialize( this, widgetData );
		}
		widget.SetVisible( true );
	}

	protected function HideThumbnailWidgets()
	{
		var i : Int32;
		for( i = 0; i < m_thumbnailWidgetsData.Size(); i += 1 )
		{
			if( m_thumbnailWidgetsData[ i ].widget != NULL )
			{
				m_thumbnailWidgetsData[ i ].widget.SetVisible( false );
			}
		}
	}

	protected override function UpdateActionWidgets( const widgetsData : ref< array< SActionWidgetPackage > > )
	{
		super.UpdateActionWidgets( widgetsData );
	}

	protected virtual function UpdateThumbnailWidgets( const widgetsData : ref< array< SThumbnailWidgetPackage > > )
	{
		HideThumbnailWidgets();
	}

	protected override function UpdateDeviceWidgets( const widgetsData : ref< array< SDeviceWidgetPackage > > )
	{
		super.UpdateDeviceWidgets( widgetsData );
	}

	protected override function Refresh( state : EDeviceStatus )
	{
		super.Refresh( state );
	}

	protected override function GetOwner() : InteractiveMasterDevice
	{
		return ( ( InteractiveMasterDevice )( GetOwnerEntity() ) );
	}

	protected override function RegisterBlackboardCallbacks( blackboard : IBlackboard )
	{
		super.RegisterBlackboardCallbacks( blackboard );
		if( blackboard )
		{
			m_onThumbnailWidgetsUpdateListener = blackboard.RegisterListenerVariant( GetOwner().GetBlackboardDef().ThumbnailWidgetsData, this, 'OnThumbnailWidgetsUpdate' );
			m_onCleanPasswordListener = blackboard.RegisterListenerBool( GetOwner().GetBlackboardDef().CleanPassword, this, 'OnCleanPassword' );
		}
	}

	protected override function UnRegisterBlackboardCallbacks( blackboard : IBlackboard )
	{
		super.UnRegisterBlackboardCallbacks( blackboard );
		if( blackboard )
		{
			blackboard.UnregisterListenerVariant( GetOwner().GetBlackboardDef().ThumbnailWidgetsData, m_onThumbnailWidgetsUpdateListener );
			blackboard.UnregisterListenerBool( GetOwner().GetBlackboardDef().CleanPassword, m_onCleanPasswordListener );
		}
	}

	protected event OnThumbnailWidgetsUpdate( value : Variant )
	{
		var widgetsData : array< SThumbnailWidgetPackage >;
		widgetsData = ( ( array< SThumbnailWidgetPackage > )value );
		UpdateThumbnailWidgets( widgetsData );
	}

	protected event OnCleanPassword( value : Bool )
	{
		if( m_keypadController )
		{
			m_keypadController.ClearPassword();
		}
	}

	protected event OnThumbnailActionCallback( e : inkPointerEvent )
	{
		var controller : DeviceThumbnailWidgetControllerBase;
		var executor : PlayerPuppet;
		var action : ScriptableDeviceAction;
		if( e.IsAction( 'click' ) )
		{
			controller = ( ( DeviceThumbnailWidgetControllerBase )( e.GetCurrentTarget().GetController() ) );
			if( controller != NULL )
			{
				action = controller.GetAction();
			}
			executor = GetPlayer( GetOwner().GetGame() );
			ExecuteAction( action, executor );
		}
	}

	protected function RequestDeviceWidgetsUpdate( const devices : ref< array< PersistentID > > )
	{
		var deviceWidgetsEvent : RequestDeviceWidgetsUpdateEvent;
		deviceWidgetsEvent = new RequestDeviceWidgetsUpdateEvent;
		deviceWidgetsEvent.requesters = devices;
		deviceWidgetsEvent.screenDefinition = GetOwner().GetScreenDefinition();
		GetOwner().QueueEvent( deviceWidgetsEvent );
	}

	protected function RequestDeviceWidgetsUpdate( device : PersistentID )
	{
		var deviceWidgetEvent : RequestDeviceWidgetUpdateEvent;
		deviceWidgetEvent = new RequestDeviceWidgetUpdateEvent;
		deviceWidgetEvent.requester = device;
		deviceWidgetEvent.screenDefinition = GetOwner().GetScreenDefinition();
		GetOwner().QueueEvent( deviceWidgetEvent );
	}

	protected function RequestThumbnailWidgetsUpdate()
	{
		var thumbnailWidgetsEvent : RequestThumbnailWidgetsUpdateEvent;
		thumbnailWidgetsEvent = new RequestThumbnailWidgetsUpdateEvent;
		thumbnailWidgetsEvent.screenDefinition = GetOwner().GetScreenDefinition();
		GetOwner().QueueEvent( thumbnailWidgetsEvent );
	}

	protected function IsOwner( deviceID : PersistentID ) : Bool
	{
		return deviceID == GetOwner().GetDevicePS().GetID();
	}

}

