class NewPerkSkillsLogicController extends inkLogicController
{
	private editable var m_virtualGridContainer : inkVirtualCompoundRef;
	private editable var m_scrollBarContainer : inkWidgetRef;
	private var m_virtualGrid : weak< inkVirtualGridController >;
	private var m_dataSource : ScriptableDataSource;
	private var m_itemsClassifier : inkVirtualItemTemplateClassifier;
	private var m_scrollBar : weak< inkScrollController >;
	private var m_dataManager : weak< PlayerDevelopmentDataManager >;
	private var m_isActiveScreen : Bool;
	private var m_initialized : Bool;
	private var virtualItems : array< IScriptable >;

	protected event OnUninitialize()
	{
		var i : Int32;
		var controller : weak< NewPerksSkillBarLogicController >;
		UnregisterData();
		for( i = 0; i < inkVirtualCompoundRef.GetNumChildren( m_virtualGridContainer ); i += 1 )
		{
			controller = ( ( weak< weak< NewPerksSkillBarLogicController > > )( inkVirtualCompoundRef.GetWidgetByIndex( m_virtualGridContainer, i ).GetController() ) );
			controller.UnregisterAllCallbacks();
		}
	}

	public function UnregisterData()
	{
		m_virtualGrid.SetClassifier( NULL );
		m_virtualGrid.SetSource( NULL );
		m_itemsClassifier = NULL;
		m_dataSource = NULL;
	}

	public function Initialize( dataManager : weak< PlayerDevelopmentDataManager > )
	{
		var i, limit : Int32;
		var proficiencyDisplayData : ProficiencyDisplayData;
		if( !( m_initialized ) )
		{
			m_dataManager = dataManager;
			m_virtualGrid = ( ( inkVirtualGridController )( inkVirtualCompoundRef.GetControllerByType( m_virtualGridContainer, 'inkVirtualGridController' ) ) );
			m_dataSource = new ScriptableDataSource;
			m_itemsClassifier = new inkVirtualItemTemplateClassifier;
			m_virtualGrid.SetClassifier( m_itemsClassifier );
			m_virtualGrid.SetSource( m_dataSource );
			for( i = 0, limit = ( ( Int32 )( gamedataProficiencyType.Count ) ); i < limit; i += 1 )
			{
				if( PlayerDevelopmentData.IsProfficiencyObsolete( ( ( gamedataProficiencyType )( i ) ) ) )
				{
					continue;
				}
				proficiencyDisplayData = dataManager.GetProficiencyDisplayData( ( ( gamedataProficiencyType )( i ) ) );
				if( proficiencyDisplayData )
				{
					virtualItems.PushBack( ( ( IScriptable )( proficiencyDisplayData ) ) );
				}
			}
			m_dataSource.Reset( virtualItems );
		}
		m_initialized = true;
	}

	public function SetActive( value : Bool )
	{
		m_isActiveScreen = value;
	}

}

class NewPerksSkillBarLogicController extends inkVirtualCompoundItemController
{
	private editable var m_statsProgressWidget : inkWidgetRef;
	private editable var m_levelsContainer : inkCompoundRef;
	private var m_data : ProficiencyDisplayData;
	private var m_requestedSkills : Int32;
	private var m_statsProgressController : weak< StatsProgressController >;
	private var m_levelsControllers : array< weak< NewPerksSkillLevelLogicController > >;

	protected event OnInitialize()
	{
		m_statsProgressController = ( ( weak< weak< StatsProgressController > > )( inkWidgetRef.GetController( m_statsProgressWidget ) ) );
		inkWidgetRef.RegisterToCallback( m_statsProgressWidget, 'OnHoverOver', this, 'OnSkillOverOver' );
		inkWidgetRef.RegisterToCallback( m_statsProgressWidget, 'OnHoverOut', this, 'OnSkillHoverOut' );
	}

	protected event OnDataChanged( value : Variant )
	{
		m_data = ( ( ProficiencyDisplayData )( ( ( IScriptable )value ) ) );
		if( m_data )
		{
			m_statsProgressController.SetProfiencyLevel( m_data );
			UpdateSkillsCount();
		}
	}

	public function UnregisterAllCallbacks()
	{
		var i : Int32;
		for( i = 0; i < m_levelsControllers.Size(); i += 1 )
		{
			m_levelsControllers[ i ].UnregisterFromCallback( 'OnHoverOver', this, 'OnHoverOver' );
			m_levelsControllers[ i ].UnregisterFromCallback( 'OnHoverOut', this, 'OnHoverOut' );
		}
		inkWidgetRef.UnregisterFromCallback( m_statsProgressWidget, 'OnHoverOver', this, 'OnSkillOverOver' );
		inkWidgetRef.UnregisterFromCallback( m_statsProgressWidget, 'OnHoverOut', this, 'OnSkillHoverOut' );
	}

	private function UpdateSkillsCount()
	{
		var i, limit, counter : Int32;
		for( i = 3, counter = 0, limit = m_requestedSkills; i < limit; i += 5 )
		{
			SetSkillLevelData( m_levelsControllers[ counter ], m_data.m_passiveBonusesData[ i ] );
			counter += 1;
		}
		limit = m_data.m_passiveBonusesData.Size();
		while( m_requestedSkills < limit )
		{
			AsyncSpawnFromLocal( inkCompoundRef.Get( m_levelsContainer ), 'SkillLevel', this, 'OnSkillLevelSpawned' );
			m_requestedSkills += 5;
		}
	}

	protected event OnSkillLevelSpawned( widget : inkWidget, userData : IScriptable )
	{
		var index : Int32;
		m_levelsControllers.PushBack( ( ( NewPerksSkillLevelLogicController )( widget.GetController() ) ) );
		index = m_levelsControllers.Size() - 1;
		SetSkillLevelData( m_levelsControllers[ index ], m_data.m_passiveBonusesData[ 3 + ( index * 5 ) ] );
		m_levelsControllers[ index ].RegisterToCallback( 'OnHoverOver', this, 'OnHoverOver' );
		m_levelsControllers[ index ].RegisterToCallback( 'OnHoverOut', this, 'OnHoverOut' );
	}

	private function SetSkillLevelData( controller : weak< NewPerksSkillLevelLogicController >, levelData : weak< LevelRewardDisplayData > )
	{
		var active : Bool;
		if( levelData.level <= m_data.m_level )
		{
			levelData.isLock = false;
			active = true;
		}
		else
		{
			levelData.isLock = true;
			active = false;
		}
		controller.SetData( levelData, active );
	}

	private function GetSkillDesciption( proficiency : gamedataProficiencyType ) : String
	{
		switch( proficiency )
		{
			case gamedataProficiencyType.CoolSkill:
				return "Gameplay-RPG-Skills-CoolSkillSources";
			case gamedataProficiencyType.IntelligenceSkill:
				return "Gameplay-RPG-Skills-IntelligenceSkillSources";
			case gamedataProficiencyType.ReflexesSkill:
				return "Gameplay-RPG-Skills-ReflexesSkillSources";
			case gamedataProficiencyType.StrengthSkill:
				return "Gameplay-RPG-Skills-BodySkillSources";
			case gamedataProficiencyType.TechnicalAbilitySkill:
				return "Gameplay-RPG-Skills-TechSkillSources";
		}
		return "";
	}

	protected event OnSkillOverOver( e : inkPointerEvent )
	{
		var evt : SkillHoverOver;
		evt = new SkillHoverOver;
		evt.widget = e.GetCurrentTarget();
		evt.title = m_data.m_localizedName;
		evt.description = GetSkillDesciption( m_data.m_proficiency );
		QueueEvent( evt );
	}

	protected event OnSkillHoverOut( e : inkPointerEvent )
	{
		QueueEvent( new SkillHoverOut );
	}

	protected event OnHoverOver( e : inkPointerEvent )
	{
		var evt : SkillRewardHoverOver;
		var controller : weak< NewPerksSkillLevelLogicController >;
		evt = new SkillRewardHoverOver;
		evt.widget = e.GetCurrentTarget();
		controller = ( ( weak< weak< NewPerksSkillLevelLogicController > > )( evt.widget.GetController() ) );
		evt.data = controller.GetRewardData();
		controller.HoverOver();
		QueueEvent( evt );
	}

	protected event OnHoverOut( e : inkPointerEvent )
	{
		var controller : weak< NewPerksSkillLevelLogicController >;
		controller = ( ( weak< weak< NewPerksSkillLevelLogicController > > )( e.GetCurrentTarget().GetController() ) );
		controller.HoverOut();
		QueueEvent( new SkillRewardHoverOut );
	}

}

class NewPerksSkillLevelLogicController extends inkLogicController
{
	private editable var m_levelText : inkTextRef;
	private var m_levelData : LevelRewardDisplayData;
	private var m_active : Bool;
	private var m_hovered : Bool;

	public function HoverOver()
	{
		m_hovered = true;
		UpdateState();
	}

	public function HoverOut()
	{
		m_hovered = false;
		UpdateState();
	}

	public function SetData( levelData : LevelRewardDisplayData, active : Bool )
	{
		m_levelData = levelData;
		m_active = active;
		UpdateState();
		inkTextRef.SetText( m_levelText, IntToString( m_levelData.level ) );
	}

	private function UpdateState()
	{
		if( m_hovered )
		{
			if( m_active )
			{
				GetRootWidget().SetState( 'DefaultHover' );
			}
			else
			{
				GetRootWidget().SetState( 'UnavailableHover' );
			}
		}
		else
		{
			if( m_active )
			{
				GetRootWidget().SetState( 'Default' );
			}
			else
			{
				GetRootWidget().SetState( 'Unavailable' );
			}
		}
	}

	public function GetRewardData() : LevelRewardDisplayData
	{
		return m_levelData;
	}

}

class SkillRewardHoverOver extends Event
{
	var data : weak< LevelRewardDisplayData >;
	var widget : weak< inkWidget >;
}

class SkillRewardHoverOut extends Event
{
}

class SkillHoverOver extends Event
{
	var widget : weak< inkWidget >;
	var title : String;
	var description : String;
}

class SkillHoverOut extends Event
{
}

