class SubtitlesGameController extends BaseSubtitlesGameController
{
	private var m_sceneComment : weak< inkText >;
	private var m_subtitlesPanel : weak< inkVerticalPanel >;
	private var m_bbCbShowSceneComment : CallbackHandle;
	private var m_bbCbHideSceneComment : CallbackHandle;
	private var m_uiSceneCommentsBlackboard : weak< IBlackboard >;

	protected event OnInitialize()
	{
		m_sceneComment = ( ( inkText )( GetWidget( 'mainPanel/sceneComment' ) ) );
		m_subtitlesPanel = ( ( inkVerticalPanel )( GetWidget( 'mainPanel/subtitlesPanel' ) ) );
		super.OnInitialize();
		if( m_sceneComment )
		{
			m_sceneComment.SetVisible( false );
		}
		m_uiSceneCommentsBlackboard = GetUIBlackboard();
		m_bbCbShowSceneComment = m_uiSceneCommentsBlackboard.RegisterDelayedListenerString( GetAllBlackboardDefs().UIGameData.ShowSceneComment, this, 'OnShowSceneComment' );
		m_bbCbHideSceneComment = m_uiSceneCommentsBlackboard.RegisterDelayedListenerBool( GetAllBlackboardDefs().UIGameData.HideSceneComment, this, 'OnHideSceneComment' );
	}

	protected event OnUninitialize()
	{
		m_uiSceneCommentsBlackboard.UnregisterDelayedListener( GetAllBlackboardDefs().UIGameData.ShowSceneComment, m_bbCbShowSceneComment );
		m_uiSceneCommentsBlackboard.UnregisterDelayedListener( GetAllBlackboardDefs().UIGameData.HideSceneComment, m_bbCbHideSceneComment );
		super.OnUninitialize();
	}

	protected override function OnSubCreated( controller : weak< BaseSubtitleLineLogicController > )
	{
		super.OnSubCreated( controller );
	}

	protected override function SetSubsVisibilitySetting( value : Bool )
	{
		DisableBySettings( !( value ) );
	}

	protected override function SetRadioSubsVisibilitySetting( value : Bool )
	{
		EnableRadioSubtilesBySettings( value );
	}

	protected override function SetSubsForeignLinesVisibilitySetting( value : Bool )
	{
		ForceForeignLinesBySettings( value );
	}

	protected override function ShowKiroshiSettings( value : Bool )
	{
		var configVar : ConfigVarBool;
		configVar = ( ( ConfigVarBool )( m_settings.GetVar( m_groupPath, 'CinematicForceKiroshiTexts' ) ) );
		configVar.SetVisible( value );
	}

	protected override function ShouldDisplayLine( const lineData : ref< scnDialogLineData > ) : Bool
	{
		if( lineData.type == scnDialogLineType.AlwaysCinematicNoSpeaker || lineData.type == scnDialogLineType.GlobalTVAlwaysVisible )
		{
			return true;
		}
		return IsMainDialogLine( lineData );
	}

	protected override function CreateLine( lineSpawnData : LineSpawnData )
	{
		AsyncSpawnFromLocal( m_subtitlesPanel, 'Line', this, 'OnLineSpawned', lineSpawnData );
	}

	protected override function OnHideLine( const lineData : ref< subtitleLineMapEntry > )
	{
		super.OnHideLine( lineData );
		m_subtitlesPanel.RemoveChild( lineData.widget );
	}

	protected override function OnHideLineByData( const lineData : ref< subtitleLineMapEntry > )
	{
		super.OnHideLineByData( lineData );
		m_subtitlesPanel.RemoveChild( lineData.widget );
	}

	protected event OnShowSceneComment( value : String )
	{
		m_sceneComment.SetText( value );
		m_sceneComment.SetVisible( true );
	}

	protected event OnHideSceneComment( value : Bool )
	{
		m_sceneComment.SetVisible( false );
	}

}

class SubtitleLineLogicController extends BaseSubtitleLineLogicController
{
	private editable var m_speakerNameWidget : inkTextRef;
	private editable var m_subtitleWidget : inkTextRef;
	private editable var m_radioSpeaker : inkTextRef;
	private editable var m_radioSubtitle : inkTextRef;
	private editable var m_background : inkWidgetRef;
	private editable var m_backgroundSpeaker : inkWidgetRef;
	private editable var m_kiroshiAnimationContainer : inkWidgetRef;
	private editable var m_motherTongueContainter : inkWidgetRef;
	private var m_targetTextWidgetRef : inkTextRef;
	private var m_lineData : scnDialogLineData;
	private var m_spekerNameParams : inkTextParams;

	protected event OnInitialize()
	{
		GetRootWidget().SetHAlign( inkEHorizontalAlign.Center );
		inkWidgetRef.SetVisible( m_background, true );
		inkWidgetRef.SetVisible( m_backgroundSpeaker, true );
		m_spekerNameParams = new inkTextParams;
		m_spekerNameParams.SetAsyncFormat( false );
		m_spekerNameParams.AddLocalizedString( "NAME", "" );
	}

	public override function SetupSettings( textSize : Int32, backgroundOpacity : Float )
	{
		var kiroshiAnimationCtrl : inkTextKiroshiAnimController;
		inkTextRef.SetFontSize( m_speakerNameWidget, textSize );
		inkTextRef.SetFontSize( m_subtitleWidget, textSize );
		inkTextRef.SetFontSize( m_radioSpeaker, textSize );
		inkTextRef.SetFontSize( m_radioSubtitle, textSize );
		kiroshiAnimationCtrl = ( ( inkTextKiroshiAnimController )( inkWidgetRef.GetController( m_kiroshiAnimationContainer ) ) );
		kiroshiAnimationCtrl.SetupFontSettings( textSize );
		inkWidgetRef.SetOpacity( m_background, backgroundOpacity / 100.0 );
		inkWidgetRef.SetOpacity( m_backgroundSpeaker, backgroundOpacity / 100.0 );
	}

	public override function ShowBackground( value : Bool ) {}

	public override function SetLineData( const lineData : ref< scnDialogLineData > )
	{
		var kiroshiAnimationCtrl : inkTextKiroshiAnimController;
		var motherTongueCtrl : inkTextMotherTongueController;
		var displayData : scnDialogDisplayString;
		var speakerName : String;
		var speakerNameDisplayText : String;
		var isValidName : Bool;
		var characterRecordID : TweakDBID;
		var playerPuppet : gamePuppetBase;
		var speakerNameWidgetStateName : CName;
		m_lineData = lineData;
		if( IsStringValid( lineData.speakerName ) )
		{
			speakerName = lineData.speakerName;
		}
		else
		{
			speakerName = lineData.speaker.GetDisplayName();
		}
		isValidName = IsStringValid( speakerName );
		speakerNameDisplayText = ( ( isValidName ) ? ( "LocKey#76968" ) : ( "" ) );
		if( isValidName )
		{
			m_spekerNameParams.UpdateLocalizedString( "NAME", speakerName );
		}
		if( IsMultiplayer() )
		{
			speakerNameWidgetStateName = 'Default';
			playerPuppet = ( ( gamePuppetBase )( lineData.speaker ) );
			if( playerPuppet != NULL )
			{
				characterRecordID = playerPuppet.GetRecordID();
				speakerNameWidgetStateName = TweakDBInterface.GetCharacterRecord( characterRecordID ).CpoClassName();
			}
			inkTextRef.SetState( m_speakerNameWidget, speakerNameWidgetStateName );
		}
		if( lineData.type == scnDialogLineType.Radio )
		{
			m_targetTextWidgetRef = m_radioSubtitle;
			inkTextRef.SetLocalizedTextScript( m_radioSpeaker, speakerNameDisplayText, m_spekerNameParams );
			inkTextRef.SetVisible( m_speakerNameWidget, false );
			inkTextRef.SetVisible( m_subtitleWidget, false );
			inkTextRef.SetVisible( m_radioSpeaker, true );
			inkTextRef.SetVisible( m_radioSubtitle, true );
		}
		else if( lineData.type == scnDialogLineType.AlwaysCinematicNoSpeaker )
		{
			m_targetTextWidgetRef = m_radioSubtitle;
			inkTextRef.SetVisible( m_speakerNameWidget, false );
			inkTextRef.SetVisible( m_subtitleWidget, false );
			inkTextRef.SetVisible( m_radioSpeaker, false );
			inkTextRef.SetVisible( m_radioSubtitle, true );
		}
		else if( lineData.type == scnDialogLineType.GlobalTVAlwaysVisible )
		{
			m_targetTextWidgetRef = m_subtitleWidget;
			inkTextRef.SetVisible( m_speakerNameWidget, false );
			inkTextRef.SetVisible( m_subtitleWidget, true );
			inkTextRef.SetVisible( m_radioSpeaker, false );
			inkTextRef.SetVisible( m_radioSubtitle, false );
		}
		else
		{
			m_targetTextWidgetRef = m_subtitleWidget;
			inkTextRef.SetLocalizedTextScript( m_speakerNameWidget, speakerNameDisplayText, m_spekerNameParams );
			inkTextRef.SetVisible( m_speakerNameWidget, true );
			inkTextRef.SetVisible( m_subtitleWidget, true );
			inkTextRef.SetVisible( m_radioSpeaker, false );
			inkTextRef.SetVisible( m_radioSubtitle, false );
		}
		if( lineData.type == scnDialogLineType.Narrator )
		{
			inkTextRef.SetState( m_speakerNameWidget, 'MainNarrator' );
			inkTextRef.SetState( m_subtitleWidget, 'MainNarrator' );
			inkWidgetRef.SetState( m_motherTongueContainter, 'MainNarrator' );
		}
		if( scnDialogLineData.HasKiroshiTag( lineData ) )
		{
			displayData = scnDialogLineData.GetDisplayText( lineData );
			if( IsKiroshiEnabled() )
			{
				kiroshiAnimationCtrl = ( ( inkTextKiroshiAnimController )( inkWidgetRef.GetController( m_kiroshiAnimationContainer ) ) );
				kiroshiAnimationCtrl.SetPreTranslatedText( displayData.preTranslatedText );
				kiroshiAnimationCtrl.SetPostTranslatedText( displayData.postTranslatedText );
				kiroshiAnimationCtrl.SetNativeText( displayData.text, displayData.language );
				kiroshiAnimationCtrl.SetTargetText( displayData.translation );
				SetupAnimation( m_lineData.duration, kiroshiAnimationCtrl );
				kiroshiAnimationCtrl.PlaySetAnimation();
			}
			else
			{
				motherTongueCtrl = ( ( inkTextMotherTongueController )( inkWidgetRef.GetControllerByType( m_motherTongueContainter, 'inkTextMotherTongueController' ) ) );
				motherTongueCtrl.SetPreTranslatedText( "" );
				motherTongueCtrl.SetNativeText( displayData.text, displayData.language );
				motherTongueCtrl.SetTranslatedText( "" );
				motherTongueCtrl.SetPostTranslatedText( "" );
				motherTongueCtrl.ApplyTexts();
			}
		}
		else if( scnDialogLineData.HasMothertongueTag( lineData ) )
		{
			displayData = scnDialogLineData.GetDisplayText( lineData );
			motherTongueCtrl = ( ( inkTextMotherTongueController )( inkWidgetRef.GetControllerByType( m_motherTongueContainter, 'inkTextMotherTongueController' ) ) );
			motherTongueCtrl.SetPreTranslatedText( displayData.preTranslatedText );
			motherTongueCtrl.SetNativeText( displayData.text, displayData.language );
			motherTongueCtrl.SetTranslatedText( displayData.translation );
			motherTongueCtrl.SetPostTranslatedText( displayData.postTranslatedText );
			motherTongueCtrl.ApplyTexts();
		}
		else
		{
			inkTextRef.SetText( m_targetTextWidgetRef, m_lineData.text );
			PlayLibraryAnimation( 'intro' );
		}
	}

}

