import class LevelUpNotificationViewData extends GenericNotificationViewData
{
	import var canBeMerged : Bool;
	import var levelupdata : LevelUpData;
	import var proficiencyRecord : Proficiency_Record;
	import var profString : String;

	public export override function CanMerge( data : GenericNotificationViewData ) : Bool
	{
		return canBeMerged;
	}

}

class LevelUpNotificationQueue extends gameuiGenericNotificationGameController
{
	private editable var m_duration : Float;
	default m_duration = 2.0f;
	private var m_levelUpBlackboard : weak< IBlackboard >;
	private var m_playerLevelUpListener : CallbackHandle;
	private var m_playerObject : weak< GameObject >;
	private var m_combatModePSM : gamePSMCombat;
	private var m_combatModeListener : CallbackHandle;
	private var m_lastEspionageLevel : Int32;
	private var m_warningBlackboard : weak< IBlackboard >;
	private var m_warningBlackboardDef : UI_NotificationsDef;
	private var m_warningMessageCallbackId : CallbackHandle;

	public export override function GetShouldSaveState() : Bool
	{
		return true;
	}

	public export override function GetID() : Int32
	{
		return ( ( Int32 )( GenericNotificationType.LevelUpNotification ) );
	}

	protected event OnPlayerAttach( playerPuppet : GameObject )
	{
		m_playerObject = ( ( GameObject )( GetPlayerControlledObject() ) );
		RegisterPSMListeners( m_playerObject );
	}

	protected event OnPlayerDetach( playerGameObject : GameObject )
	{
		UnregisterPSMListeners( m_playerObject );
	}

	protected event OnInitialize()
	{
		m_warningBlackboardDef = GetAllBlackboardDefs().UI_Notifications;
		m_warningBlackboard = GetBlackboardSystem().Get( m_warningBlackboardDef );
		m_warningMessageCallbackId = m_warningBlackboard.RegisterDelayedListenerVariant( m_warningBlackboardDef.WarningMessage, this, 'OnWarningMessageAppeared' );
		m_levelUpBlackboard = GetBlackboardSystem().Get( GetAllBlackboardDefs().UI_LevelUp );
		m_playerLevelUpListener = m_levelUpBlackboard.RegisterListenerVariant( GetAllBlackboardDefs().UI_LevelUp.level, this, 'OnCharacterLevelUpdated' );
		SetNotificationPauseWhenHidden( true );
		SetLastRelicLevel();
	}

	protected event OnUninitialize()
	{
		if( m_levelUpBlackboard )
		{
			m_levelUpBlackboard.UnregisterListenerVariant( GetAllBlackboardDefs().UI_LevelUp.level, m_playerLevelUpListener );
		}
		if( m_warningBlackboard )
		{
			m_warningBlackboard.UnregisterDelayedListener( m_warningBlackboardDef.WarningMessage, m_warningMessageCallbackId );
		}
	}

	protected event OnWarningMessageAppeared( value : Variant )
	{
		var warningMessage : SimpleScreenMessage;
		warningMessage = ( ( SimpleScreenMessage )value );
		if( warningMessage.isShown )
		{
			SetNotificationPaused( true );
			GetRootWidget().SetVisible( false );
		}
		else
		{
			SetNotificationPaused( false );
			GetRootWidget().SetVisible( true );
		}
	}

	private function SetLastRelicLevel()
	{
		var gameInstance : GameInstance;
		var playerDevelopmentSystem : PlayerDevelopmentSystem;
		gameInstance = ( ( GameObject )( GetOwnerEntity() ) ).GetGame();
		playerDevelopmentSystem = ( ( PlayerDevelopmentSystem )( GameInstance.GetScriptableSystemsContainer( gameInstance ).Get( 'PlayerDevelopmentSystem' ) ) );
		m_lastEspionageLevel = playerDevelopmentSystem.GetProficiencyLevel( GetPlayerControlledObject(), gamedataProficiencyType.Espionage );
	}

	protected function RegisterPSMListeners( playerObject : GameObject )
	{
		var playerStateMachineBlackboard : IBlackboard;
		var playerSMDef : PlayerStateMachineDef;
		playerSMDef = GetAllBlackboardDefs().PlayerStateMachine;
		if( playerSMDef )
		{
			playerStateMachineBlackboard = GetPSMBlackboard( playerObject );
			if( playerStateMachineBlackboard )
			{
				m_combatModeListener = playerStateMachineBlackboard.RegisterListenerInt( playerSMDef.Combat, this, 'OnCombatStateChanged' );
			}
		}
	}

	protected function UnregisterPSMListeners( playerObject : GameObject )
	{
		var playerStateMachineBlackboard : IBlackboard;
		var playerSMDef : PlayerStateMachineDef;
		playerSMDef = GetAllBlackboardDefs().PlayerStateMachine;
		if( playerSMDef )
		{
			playerStateMachineBlackboard = GetPSMBlackboard( playerObject );
			if( playerStateMachineBlackboard )
			{
				playerStateMachineBlackboard.UnregisterDelayedListener( playerSMDef.Combat, m_combatModeListener );
			}
		}
	}

	protected event OnCombatStateChanged( value : Int32 )
	{
		m_combatModePSM = ( ( gamePSMCombat )( value ) );
		if( m_combatModePSM == gamePSMCombat.InCombat )
		{
			SetNotificationPaused( true );
			GetRootWidget().SetVisible( false );
		}
		else
		{
			SetNotificationPaused( false );
			GetRootWidget().SetVisible( true );
		}
	}

	private function OnCharacterLevelUpdated( value : Variant )
	{
		var notificationData : gameuiGenericNotificationData;
		var userData : LevelUpNotificationViewData;
		var levelUpData : LevelUpData;
		var proficiencyRecord : Proficiency_Record;
		var profString : String;
		var action : OpenPerksNotificationAction;
		var skillAction : OpenSkillsNotificationAction;
		levelUpData = ( ( LevelUpData )value );
		profString = EnumValueToString( "gamedataProficiencyType", ( ( Int32 )( levelUpData.type ) ) );
		proficiencyRecord = TweakDBInterface.GetProficiencyRecord( TDBID.Create( "Proficiencies." + profString ) );
		userData = new LevelUpNotificationViewData;
		userData.canBeMerged = false;
		userData.levelupdata = levelUpData;
		userData.profString = proficiencyRecord.Loc_name_key();
		userData.proficiencyRecord = proficiencyRecord;
		notificationData.time = m_duration;
		if( levelUpData.type == gamedataProficiencyType.Espionage )
		{
			notificationData.widgetLibraryItemName = 'RelicUp';
			userData.soundEvent = 'RelicPopup';
			userData.soundAction = 'OnLevelUp';
			userData.levelupdata.lvl = levelUpData.lvl - m_lastEspionageLevel;
			m_lastEspionageLevel = levelUpData.lvl;
			if( !( levelUpData.disableAction ) )
			{
				action = new OpenPerksNotificationAction;
				action.m_eventDispatcher = this;
				userData.action = action;
			}
		}
		else if( levelUpData.type == gamedataProficiencyType.Level )
		{
			notificationData.widgetLibraryItemName = 'LevelUp_';
			userData.soundEvent = 'PlayerLevelUpPopup';
			userData.soundAction = 'OnOpen';
			if( !( levelUpData.disableAction ) )
			{
				action = new OpenPerksNotificationAction;
				action.m_eventDispatcher = this;
				userData.action = action;
			}
		}
		else if( levelUpData.type == gamedataProficiencyType.StreetCred )
		{
			notificationData.widgetLibraryItemName = 'StreetCredUp_';
			userData.soundEvent = 'PlayerLevelUpPopup';
			userData.soundAction = 'OnOpen';
			if( !( levelUpData.disableAction ) )
			{
				action = NULL;
				action.m_eventDispatcher = this;
				userData.action = action;
			}
		}
		else
		{
			notificationData.widgetLibraryItemName = 'SkillUp_';
			userData.soundEvent = 'SkillLevelUpPopup';
			userData.soundAction = 'OnOpen';
			if( !( levelUpData.disableAction ) )
			{
				skillAction = new OpenSkillsNotificationAction;
				skillAction.m_eventDispatcher = this;
				userData.action = skillAction;
			}
		}
		notificationData.notificationData = userData;
		AddNewNotificationData( notificationData );
	}

}

class LevelUpNotification extends GenericNotificationController
{
	private var m_levelupData : LevelUpNotificationViewData;
	private var m_animation : inkAnimProxy;
	private var bonusRecord : PassiveProficiencyBonus_Record;
	private editable var m_LevelUpLabelText : inkTextRef;
	private editable var m_LevelUpValue : inkTextRef;
	private editable var m_LevelUpHolder : inkWidgetRef;
	private editable var m_LevelUpPreviousValue : inkTextRef;
	private editable var m_AttributePointsValue : inkTextRef;
	private editable var m_AttributePointsPreviousValue : inkTextRef;
	private editable var m_AttributePointsHolder : inkWidgetRef;
	private editable var m_PerkPointsValue : inkTextRef;
	private editable var m_PerkPreviousValue : inkTextRef;
	private editable var m_SkillIcon : inkImageRef;
	private editable var m_SkillIconShadow : inkImageRef;
	private var bonusDisplay : LevelRewardDisplayData;
	private editable var m_passiveBonusRewardLabel : inkTextRef;
	private editable var m_passiveBonusReward : inkWidgetRef;
	var unlockedActivites : Int32;

	public export override function SetNotificationData( notificationData : GenericNotificationViewData )
	{
		var iconRecord : UIIcon_Record;
		super.SetNotificationData( notificationData );
		m_levelupData = ( ( LevelUpNotificationViewData )( notificationData ) );
		inkTextRef.SetLetterCase( m_LevelUpLabelText, textLetterCase.UpperCase );
		inkWidgetRef.SetVisible( m_actionRef, m_levelupData.action != NULL );
		if( m_levelupData.levelupdata.type == gamedataProficiencyType.Level || m_levelupData.levelupdata.type == gamedataProficiencyType.StreetCred )
		{
			inkTextRef.SetText( m_LevelUpValue, IntToString( m_levelupData.levelupdata.lvl ) );
			inkTextRef.SetText( m_LevelUpPreviousValue, IntToString( Max( 0, m_levelupData.levelupdata.lvl - 1 ) ) );
			inkTextRef.SetText( m_PerkPointsValue, IntToString( m_levelupData.levelupdata.perkPoints ) );
			inkTextRef.SetText( m_PerkPreviousValue, IntToString( Max( 0, m_levelupData.levelupdata.perkPoints - 1 ) ) );
			if( m_levelupData.levelupdata.type == gamedataProficiencyType.Level )
			{
				inkTextRef.SetText( m_AttributePointsValue, IntToString( m_levelupData.levelupdata.attributePoints ) );
				inkTextRef.SetText( m_AttributePointsPreviousValue, IntToString( Max( 0, m_levelupData.levelupdata.attributePoints - 1 ) ) );
				inkTextRef.SetText( m_LevelUpLabelText, "LocKey#21980" );
				if( m_animation.IsPlaying() )
				{
					m_animation.Stop();
				}
				m_animation = PlayLibraryAnimation( 'LevelUp_03' );
			}
			if( m_levelupData.levelupdata.type == gamedataProficiencyType.StreetCred )
			{
				unlockedActivites = TweakDBInterface.GetInt( TDBID.Create( "Constants.StreetCredActivityUnlocks.level" + m_levelupData.levelupdata.lvl ), 0 );
				if( unlockedActivites > 0 )
				{
					inkTextRef.SetText( m_AttributePointsPreviousValue, IntToString( unlockedActivites ) );
					inkTextRef.SetText( m_AttributePointsValue, IntToString( Max( 0, unlockedActivites - 1 ) ) );
					inkWidgetRef.SetVisible( m_LevelUpHolder, false );
				}
				else
				{
					inkWidgetRef.SetVisible( m_AttributePointsHolder, false );
					inkWidgetRef.SetVisible( m_actionRef, false );
					inkWidgetRef.SetVisible( m_LevelUpHolder, false );
				}
				if( m_animation.IsPlaying() )
				{
					m_animation.Stop();
				}
				m_animation = PlayLibraryAnimation( 'StreetCredUp_03' );
			}
			PlaySound( m_levelupData.soundEvent, m_levelupData.soundAction );
		}
		else if( m_levelupData.levelupdata.type == gamedataProficiencyType.Espionage )
		{
			inkTextRef.SetText( m_LevelUpValue, IntToString( m_levelupData.levelupdata.lvl ) );
			inkTextRef.SetText( m_LevelUpPreviousValue, IntToString( Max( 0, m_levelupData.levelupdata.lvl - 1 ) ) );
			inkTextRef.SetText( m_AttributePointsValue, IntToString( m_levelupData.levelupdata.attributePoints ) );
			inkTextRef.SetText( m_AttributePointsPreviousValue, IntToString( Max( 0, m_levelupData.levelupdata.attributePoints - 1 ) ) );
			inkTextRef.SetText( m_PerkPointsValue, IntToString( m_levelupData.levelupdata.espionagePoints ) );
			if( m_animation.IsPlaying() )
			{
				m_animation.Stop();
			}
			m_animation = PlayLibraryAnimation( 'Relic_Up' );
			PlaySound( m_levelupData.soundEvent, m_levelupData.soundAction );
		}
		else
		{
			inkTextRef.SetText( m_LevelUpLabelText, m_levelupData.proficiencyRecord.Loc_name_key() );
			inkTextRef.SetText( m_LevelUpValue, IntToString( m_levelupData.levelupdata.lvl ) );
			inkTextRef.SetText( m_LevelUpPreviousValue, IntToString( Max( 0, m_levelupData.levelupdata.lvl - 1 ) ) );
			bonusRecord = m_levelupData.proficiencyRecord.GetPassiveBonusesItem( m_levelupData.levelupdata.lvl - 1 );
			bonusDisplay = new LevelRewardDisplayData;
			bonusDisplay.level = m_levelupData.levelupdata.lvl - 1;
			bonusDisplay.locPackage = UILocalizationDataPackage.FromPassiveUIDataPackage( bonusRecord.UiData() );
			bonusDisplay.description = LocKeyToString( bonusRecord.UiData().Loc_name_key() );
			if( bonusDisplay.locPackage.GetParamsCount() )
			{
				inkWidgetRef.SetVisible( m_passiveBonusReward, true );
				inkTextRef.SetText( m_passiveBonusRewardLabel, LocKeyToString( bonusRecord.UiData().Loc_name_key() ) );
				inkTextRef.SetTextParameters( m_passiveBonusRewardLabel, bonusDisplay.locPackage.GetTextParams() );
			}
			else
			{
				inkWidgetRef.SetVisible( m_passiveBonusReward, false );
			}
			iconRecord = TweakDBInterface.GetUIIconRecord( TDBID.Create( "UIIcon." + ( ( String )( m_levelupData.levelupdata.type ) ) ) );
			inkImageRef.SetTexturePart( m_SkillIcon, iconRecord.AtlasPartName() );
			inkImageRef.SetTexturePart( m_SkillIconShadow, iconRecord.AtlasPartName() );
			if( m_animation.IsPlaying() )
			{
				m_animation.Stop();
			}
			m_animation = PlayLibraryAnimation( 'SkillUp_02' );
			PlaySound( m_levelupData.soundEvent, m_levelupData.soundAction );
		}
	}

}

