class NewPerksGaugeController extends inkLogicController
{
	editable var m_bar : inkWidgetRef;
	editable var m_possibleBar : inkWidgetRef;
	editable var m_currentLevelIndicator : inkWidgetRef;
	editable var m_possibleLevelIndicator : inkWidgetRef;
	editable var m_levelText : inkTextRef;
	const editable var m_levels : array< NewPerksGaugePointDetails >;

	private function SetBottomMargin( widget : inkWidgetRef, bottomMargin : Float )
	{
		var margin : inkMargin;
		margin = inkWidgetRef.GetMargin( widget );
		margin.bottom = bottomMargin;
		inkWidgetRef.SetMargin( widget, margin );
	}

	public function RefreshLevelRequirementsFromTDB()
	{
		var level : Int32;
		level = TDB.GetInt( T"NewPerks.NoviceNewPerkTier.requiredAttributePoints" );
		m_levels[ 1 ].m_level = level;
		level = TDB.GetInt( T"NewPerks.AdeptNewPerkTier.requiredAttributePoints" );
		m_levels[ 2 ].m_level = level;
		level = TDB.GetInt( T"NewPerks.ExpertNewPerkTier.requiredAttributePoints" );
		m_levels[ 3 ].m_level = level;
		level = TDB.GetInt( T"NewPerks.MasterNewPerkTier.requiredAttributePoints" );
		m_levels[ 4 ].m_level = level;
	}

	public function UpdateLevel( currentLevel : Int32, possibleLevel : Int32 )
	{
		var currentHeight, possibleHeight : Float;
		var i, limit : Int32;
		var isOnAnyLevel : Bool;
		currentHeight = GetHeight( currentLevel );
		if( currentLevel != possibleLevel )
		{
			possibleHeight = GetHeight( possibleLevel ) - currentHeight;
			inkWidgetRef.SetVisible( m_possibleBar, true );
			inkWidgetRef.SetVisible( m_possibleLevelIndicator, true );
			inkWidgetRef.SetHeight( m_possibleBar, ( ( Float )( CeilF( possibleHeight ) ) ) );
			SetBottomMargin( m_possibleBar, ( ( Float )( CeilF( currentHeight ) ) ) );
			SetBottomMargin( m_possibleLevelIndicator, ( ( Float )( CeilF( currentHeight + possibleHeight ) ) ) );
		}
		else
		{
			inkWidgetRef.SetVisible( m_possibleBar, false );
			inkWidgetRef.SetVisible( m_possibleLevelIndicator, false );
		}
		for( i = 0, limit = m_levels.Size(); i < limit; i += 1 )
		{
			if( m_levels[ i ].m_level == currentLevel )
			{
				isOnAnyLevel = true;
			}
			inkWidgetRef.SetState( m_levels[ i ].m_widget, ( ( m_levels[ i ].m_level <= currentLevel ) ? ( 'Achieved' ) : ( 'Default' ) ) );
		}
		inkTextRef.SetText( m_levelText, IntToString( currentLevel ) );
		inkTextRef.SetVisible( m_levelText, !( isOnAnyLevel ) );
		inkWidgetRef.SetHeight( m_bar, ( ( Float )( CeilF( currentHeight ) ) ) );
		SetBottomMargin( m_currentLevelIndicator, ( ( Float )( CeilF( currentHeight ) ) ) );
	}

	public function GetLevels() : array< NewPerksGaugePointDetails >
	{
		return m_levels;
	}

	private function GetHeight( level : Int32 ) : Float
	{
		var height : Float;
		var i, limit, levelDiff : Int32;
		limit = m_levels.Size();
		if( limit > 2 )
		{
			height += ( ( ( Float )( Min( level, m_levels[ 1 ].m_level ) ) ) * ( m_levels[ 1 ].m_height / ( ( Float )( m_levels[ 1 ].m_level ) ) ) );
			level -= Min( level, ( ( Int32 )( m_levels[ 1 ].m_level ) ) );
			for( i = 2; i < limit; i += 1 )
			{
				levelDiff = m_levels[ i ].m_level - m_levels[ ( i - 1 ) ].m_level;
				height += ( ( ( Float )( Min( level, levelDiff ) ) ) * ( ( m_levels[ i ].m_height - m_levels[ ( i - 1 ) ].m_height ) / ( ( Float )( levelDiff ) ) ) );
				level -= Min( level, levelDiff );
			}
		}
		return height;
	}

}

struct NewPerksGaugePointDetails
{
	editable var m_level : Int32;
	editable var m_height : Float;
	editable var m_widget : inkWidgetRef;
}

