class TvDeviceWidgetCustomData extends WidgetCustomData
{
	var videoPath : ResRef;
	var channelID : TweakDBID;
	var messageRecordID : TweakDBID;
	var looped : Bool;
}

class TvDeviceWidgetController extends DeviceWidgetControllerBase
{
	[ category = "Widget Refs" ]
	protected editable var m_videoWidget : inkVideoRef;
	[ category = "Widget Refs" ]
	protected editable var m_globalTVChannelSlot : inkBasePanelRef;
	[ category = "Widget Refs" ]
	protected editable var m_messegeWidget : inkTextRef;
	[ category = "Widget Refs" ]
	protected editable var m_messageBackgroundWidget : inkLeafRef;
	private var m_globalTVChannel : weak< inkWidget >;
	private var m_activeVideo : ResRef;

	public override function Initialize( gameController : DeviceInkGameControllerBase, widgetData : SDeviceWidgetPackage )
	{
		var customData : TvDeviceWidgetCustomData;
		HideGlobalTVChannel();
		customData = ( ( TvDeviceWidgetCustomData )( widgetData.customData ) );
		if( customData != NULL )
		{
			ResolveChannelData( customData, widgetData, gameController );
		}
		else
		{
			ResolveMessegeRecord( NULL );
			if( ResRef.IsValid( m_activeVideo ) )
			{
				StopVideo();
			}
		}
		super.Initialize( gameController, widgetData );
	}

	private function ResolveChannelData( data : TvDeviceWidgetCustomData, const widgetData : ref< SDeviceWidgetPackage >, gameController : DeviceInkGameControllerBase )
	{
		var channelRecord : weak< ChannelData_Record >;
		if( TDBID.IsValid( data.channelID ) )
		{
			channelRecord = TweakDBInterface.GetChannelDataRecord( data.channelID );
		}
		ResolveMessegeRecord( GetMessageRecord( data.messageRecordID ) );
		if( channelRecord )
		{
			StopVideo();
			inkBasePanelRef.SetVisible( m_globalTVChannelSlot, true );
			if( !( m_globalTVChannel ) || ( m_globalTVChannel && m_globalTVChannel.GetName() != channelRecord.ChannelWidget() ) )
			{
				if( m_globalTVChannel != NULL )
				{
					RegisterTvChannel( -1, gameController );
					inkBasePanelRef.RemoveChild( m_globalTVChannelSlot, m_globalTVChannel );
					m_globalTVChannel = NULL;
				}
				SpawnGlobalTVChannelWidget( gameController, channelRecord, widgetData.libraryPath );
			}
			else if( m_globalTVChannel )
			{
				RegisterTvChannel( channelRecord.OrderID(), gameController );
				ShowGlobalTVChannel();
			}
			inkVideoRef.SetVisible( m_videoWidget, false );
		}
		else
		{
			if( ( m_activeVideo != data.videoPath || widgetData.deviceState != EDeviceStatus.ON ) || !( ResRef.IsValid( data.videoPath ) ) )
			{
				StopVideo();
			}
			inkBasePanelRef.SetVisible( m_globalTVChannelSlot, false );
			inkVideoRef.SetVisible( m_videoWidget, true );
			m_activeVideo = data.videoPath;
			PlayVideo( data.videoPath, data.looped );
			RegisterTvChannel( -1, gameController );
		}
	}

	private function SpawnGlobalTVChannelWidget( gameController : DeviceInkGameControllerBase, channelRecord : weak< ChannelData_Record >, optional libraryPath : ResRef )
	{
		var tvWidgetData : TvChannelSpawnData;
		var spawnData : AsyncSpawnData;
		tvWidgetData = new TvChannelSpawnData;
		tvWidgetData.Initialize( channelRecord.ChannelWidget(), channelRecord.LocalizedName(), channelRecord.OrderID() );
		spawnData = new AsyncSpawnData;
		spawnData.Initialize( this, 'OnGLobalChannelSpawned', tvWidgetData, gameController );
		CreateWidgetAsync( inkBasePanelRef.Get( m_globalTVChannelSlot ), channelRecord.ChannelWidget(), libraryPath, spawnData );
	}

	protected event OnGLobalChannelSpawned( widget : inkWidget, userData : IScriptable )
	{
		var spawnData : AsyncSpawnData;
		var tvWidgetData : TvChannelSpawnData;
		var gameController : DeviceInkGameControllerBase;
		spawnData = ( ( AsyncSpawnData )( userData ) );
		if( spawnData )
		{
			tvWidgetData = ( ( TvChannelSpawnData )spawnData.m_widgetData );
		}
		if( widget )
		{
			widget.SetAnchor( inkEAnchor.Fill );
			widget.SetSizeRule( inkESizeRule.Stretch );
			widget.SetVisible( false );
			if( tvWidgetData )
			{
				widget.SetName( tvWidgetData.m_channelName );
			}
			gameController = ( ( DeviceInkGameControllerBase )( spawnData.m_controller ) );
			if( gameController )
			{
				m_globalTVChannel = widget;
				RegisterTvChannel( tvWidgetData.m_order, gameController );
				ShowGlobalTVChannel();
			}
		}
	}

	private function HideGlobalTVChannel()
	{
		if( m_globalTVChannel )
		{
			m_globalTVChannel.SetVisible( false );
		}
	}

	private function ShowGlobalTVChannel()
	{
		if( m_globalTVChannel )
		{
			m_globalTVChannel.SetVisible( true );
		}
	}

	private function RegisterTvChannel( index : Int32, gameController : DeviceInkGameControllerBase )
	{
		var owner : GameObject;
		if( gameController )
		{
			owner = ( ( GameObject )( gameController.GetOwnerEntity() ) );
		}
		if( owner && gameController )
		{
			GameInstance.GetGlobalTVSystem( owner.GetGame() ).RegisterTVChannelOnController( gameController, -1, index );
		}
	}

	private function StopVideo()
	{
		var invalidPath : ResRef;
		inkVideoRef.Stop( m_videoWidget );
		inkVideoRef.SetVideoPath( m_videoWidget, invalidPath );
	}

	private function PlayVideo( videoPath : ResRef, looped : Bool )
	{
		inkVideoRef.SetVideoPath( m_videoWidget, videoPath );
		inkVideoRef.SetLoop( m_videoWidget, looped );
		inkVideoRef.Play( m_videoWidget );
	}

	protected virtual function ResolveMessegeRecord( record : weak< ScreenMessageData_Record > )
	{
		var fontPath : String;
		var fontstyle : CName;
		var verticalAlignment : CName;
		var horizontalAlignment : CName;
		if( record != NULL )
		{
			fontPath = record.FontPath();
			fontstyle = record.FontStyle();
			verticalAlignment = record.TextVerticalAlignment();
			horizontalAlignment = record.TextHorizontalAlignment();
			if( IsStringValid( fontPath ) )
			{
				inkTextRef.SetFontFamily( m_messegeWidget, fontPath, fontstyle );
			}
			else if( IsNameValid( fontstyle ) )
			{
				inkTextRef.SetFontStyle( m_messegeWidget, fontstyle );
			}
			if( IsNameValid( verticalAlignment ) )
			{
				inkTextRef.SetVerticalAlignment( m_messegeWidget, inkTextRef.GetVerticalAlignmentEnumValue( m_messegeWidget, verticalAlignment ) );
			}
			if( IsNameValid( horizontalAlignment ) )
			{
				inkTextRef.SetHorizontalAlignment( m_messegeWidget, inkTextRef.GetHorizontalAlignmentEnumValue( m_messegeWidget, horizontalAlignment ) );
			}
			inkTextRef.UpdateMargin( m_messegeWidget, record.LeftMargin(), record.TopMargin(), record.RightMargin(), record.BottomMargin() );
			inkTextRef.EnableAutoScroll( m_messegeWidget, record.AutoScroll() );
			inkTextRef.SetFontSize( m_messegeWidget, record.FontSize() );
			( ( inkText )( inkTextRef.Get( m_messegeWidget ) ) ).SetLocalizedTextScript( record.LocalizedDescription() );
			inkTextRef.SetScrollTextSpeed( m_messegeWidget, record.ScrollSpeed() );
			inkTextRef.SetTintColor( m_messegeWidget, GetColorFromArray( record.TextColor() ) );
			inkLeafRef.SetTintColor( m_messageBackgroundWidget, GetColorFromArray( record.BackgroundColor() ) );
			inkLeafRef.SetOpacity( m_messageBackgroundWidget, record.BackgroundOpacity() );
			SetBackgroundTexture( ( ( inkImage )( inkLeafRef.Get( m_messageBackgroundWidget ) ) ), record.BackgroundTextureID() );
		}
		else
		{
			inkTextRef.SetText( m_messegeWidget, "" );
			inkLeafRef.SetOpacity( m_messageBackgroundWidget, 0.0 );
		}
	}

	private function GetColorFromArray( const colorArray : ref< array< Int32 > > ) : Color
	{
		var i : Int32;
		var color : Color;
		for( i = 0; i < colorArray.Size(); i += 1 )
		{
			if( i == 0 )
			{
				color.Red = ( ( Uint8 )( colorArray[ i ] ) );
			}
			else if( i == 1 )
			{
				color.Green = ( ( Uint8 )( colorArray[ i ] ) );
			}
			else if( i == 2 )
			{
				color.Blue = ( ( Uint8 )( colorArray[ i ] ) );
			}
			else if( i == 3 )
			{
				color.Alpha = ( ( Uint8 )( colorArray[ i ] ) );
			}
		}
		return color;
	}

	private const function GetMessageRecord( messageID : TweakDBID ) : ScreenMessageData_Record
	{
		var messageRecord : weak< ScreenMessageData_Record >;
		var groupRecord : weak< ScreenMessagesList_Record >;
		var count : Int32;
		var rand : Int32;
		if( !( TDBID.IsValid( messageID ) ) )
		{
			return NULL;
		}
		messageRecord = TweakDBInterface.GetScreenMessageDataRecord( messageID );
		if( messageRecord != NULL )
		{
			groupRecord = messageRecord.MessageGroup();
			if( groupRecord != NULL )
			{
				count = groupRecord.GetMessagesCount();
				if( count > 0 )
				{
					rand = RandRange( 0, count );
					messageRecord = groupRecord.GetMessagesItem( rand );
				}
			}
		}
		return messageRecord;
	}

	private function SetBackgroundTexture( imageWidget : weak< inkImage >, textureID : TweakDBID )
	{
		if( imageWidget != NULL )
		{
			InkImageUtils.RequestSetImage( this, imageWidget, textureID );
			imageWidget.SetAnchor( inkEAnchor.Fill );
		}
	}

	private function SetBackgroundTexture( imageWidget : weak< inkImage >, textureRecord : weak< UIIcon_Record > )
	{
		if( ( imageWidget != NULL ) && ( textureRecord != NULL ) )
		{
			imageWidget.SetAtlasResource( textureRecord.AtlasResourcePath() );
			imageWidget.SetTexturePart( textureRecord.AtlasPartName() );
		}
	}

	private function SetBackgroundTexture( imageWidgetRef : inkImageRef, textureRecord : weak< UIIcon_Record > )
	{
		if( inkImageRef.IsValid( imageWidgetRef ) && ( textureRecord != NULL ) )
		{
			inkImageRef.SetAtlasResource( imageWidgetRef, textureRecord.AtlasResourcePath() );
			inkImageRef.SetTexturePart( imageWidgetRef, textureRecord.AtlasPartName() );
		}
	}

}

