enum PerkMenuAttribute
{
	Body = 0,
	Reflex = 1,
	Technical_Ability = 2,
	Cool = 3,
	Intelligence = 4,
	Espionage = 5,
	Johnny = 6,
	Count = 7,
	Invalid = -1,
}

class PerksMenuAttributeItemController extends inkLogicController
{
	protected editable var m_attributeDisplay : inkWidgetRef;
	protected editable var m_connectionLine : inkImageRef;
	protected editable var m_attributeType : PerkMenuAttribute;
	protected editable var m_skillsLevelsContainer : inkCompoundRef;
	protected const editable var m_proficiencyButtonRefs : array< inkWidgetRef >;
	protected editable var m_isReversed : Bool;
	protected var m_dataManager : PlayerDevelopmentDataManager;
	protected var m_attributeDisplayController : weak< PerksMenuAttributeDisplayController >;
	protected var m_recentlyPurchased : Bool;
	protected var m_holdStarted : Bool;
	protected var m_data : AttributeData;
	protected var m_cool_in_proxy : inkAnimProxy;
	protected var m_cool_out_proxy : inkAnimProxy;

	protected event OnInitialize()
	{
		var i : Int32;
		var perksMenuAttributeItemCreated : PerksMenuAttributeItemCreated;
		var perkButtonController : ProficiencyButtonController;
		m_holdStarted = false;
		for( i = 0; i < m_proficiencyButtonRefs.Size(); i += 1 )
		{
			perkButtonController = ( ( ProficiencyButtonController )( inkWidgetRef.GetController( m_proficiencyButtonRefs[ i ] ) ) );
			perkButtonController.SetIndex( i );
			perkButtonController.RegisterToCallback( 'OnButtonClick', this, 'OnProficiencyClicked' );
		}
		m_attributeDisplayController = ( ( PerksMenuAttributeDisplayController )( inkWidgetRef.GetController( m_attributeDisplay ) ) );
		m_attributeDisplayController.RegisterToCallback( 'OnHold', this, 'OnAttributeItemHold' );
		m_attributeDisplayController.RegisterToCallback( 'OnRelease', this, 'OnAttributeItemClicked' );
		m_attributeDisplayController.RegisterToCallback( 'OnHoverOver', this, 'OnAttributeItemHoverOver' );
		m_attributeDisplayController.RegisterToCallback( 'OnHoverOut', this, 'OnAttributeItemHoverOut' );
		RegisterToCallback( 'OnEnter', this, 'OnContainerHoverOver' );
		RegisterToCallback( 'OnLeave', this, 'OnContainerHoverOut' );
		inkImageRef.SetOpacity( m_connectionLine, 0.002 );
		perksMenuAttributeItemCreated = new PerksMenuAttributeItemCreated;
		perksMenuAttributeItemCreated.perksMenuAttributeItem = this;
		QueueEvent( perksMenuAttributeItemCreated );
		ShowProficiencyButton( false );
	}

	public function Setup( dataManager : PlayerDevelopmentDataManager )
	{
		m_dataManager = dataManager;
		m_attributeDisplayController.Setup( m_attributeType, dataManager );
		m_data = dataManager.GetAttribute( m_dataManager.GetAttributeRecordIDFromEnum( m_attributeType ) );
		SetupProficiencyButtons( m_data );
	}

	public function GetStatType() : gamedataStatType
	{
		return m_attributeDisplayController.GetStatType();
	}

	public function GetAttributeType() : PerkMenuAttribute
	{
		return m_attributeType;
	}

	public function UpdateData( attributeData : AttributeData )
	{
		m_attributeDisplayController.UpdateData( attributeData );
		m_data = attributeData;
		SetupProficiencyButtons( attributeData );
	}

	protected function SetupProficiencyButtons( attributeData : AttributeData )
	{
		var perkButtonController : ProficiencyButtonController;
		var attributeDisplayData : AttributeDisplayData;
		var proficiencies : array< ProficiencyDisplayData >;
		var i, dataCount : Int32;
		attributeDisplayData = m_dataManager.GetAttributeData( attributeData.id );
		proficiencies = attributeDisplayData.m_proficiencies;
		dataCount = proficiencies.Size();
		for( i = 0; ( i < m_proficiencyButtonRefs.Size() ) && ( i < dataCount ); i += 1 )
		{
			perkButtonController = ( ( ProficiencyButtonController )( inkWidgetRef.GetController( m_proficiencyButtonRefs[ i ] ) ) );
			perkButtonController.SetLabel( proficiencies[ i ].m_localizedName );
			perkButtonController.SetLevel( proficiencies[ i ].m_level );
		}
	}

	protected event OnAttributeItemClicked( evt : inkPointerEvent )
	{
		var perksMenuAttributeItemClickedEvent : PerksMenuAttributeItemClicked;
		var perksMenuAttributeItemReleasedEvent : PerksMenuAttributeItemReleased;
		if( evt.IsAction( 'click' ) )
		{
			perksMenuAttributeItemClickedEvent = new PerksMenuAttributeItemClicked;
			perksMenuAttributeItemClickedEvent.widget = GetRootWidget();
			perksMenuAttributeItemClickedEvent.attributeType = m_attributeType;
			perksMenuAttributeItemClickedEvent.attributeData = m_attributeDisplayController.GetAttributeData();
			perksMenuAttributeItemClickedEvent.isHeld = m_holdStarted;
			QueueEvent( perksMenuAttributeItemClickedEvent );
		}
		else if( evt.IsAction( 'upgrade_attribute' ) )
		{
			perksMenuAttributeItemReleasedEvent = new PerksMenuAttributeItemReleased;
			QueueEvent( perksMenuAttributeItemReleasedEvent );
			m_holdStarted = false;
		}
	}

	protected event OnProficiencyClicked( controller : weak< inkButtonController > )
	{
		var toSend : PerksMenuProficiencyItemClicked;
		var profCtrl : weak< ProficiencyButtonController >;
		profCtrl = ( ( ProficiencyButtonController )( controller ) );
		toSend = new PerksMenuProficiencyItemClicked;
		toSend.widget = profCtrl.GetRootWidget();
		toSend.attributeType = m_attributeType;
		toSend.attributeData = m_attributeDisplayController.GetAttributeData();
		toSend.index = profCtrl.GetIndex();
		QueueEvent( toSend );
	}

	protected event OnAttributeItemHold( evt : inkPointerEvent )
	{
		var progress : Float;
		var upgradeEvent : AttributeUpgradePurchased;
		var holdStartEvent : PerksMenuAttributeItemHoldStart;
		var isEspionage : Bool;
		progress = evt.GetHoldProgress();
		isEspionage = m_attributeType == PerkMenuAttribute.Espionage;
		if( isEspionage )
		{
			return false;
		}
		if( evt.IsAction( 'upgrade_attribute' ) )
		{
			if( ( progress > 0.0 ) && !( m_holdStarted ) )
			{
				holdStartEvent = new PerksMenuAttributeItemHoldStart;
				holdStartEvent.widget = GetRootWidget();
				holdStartEvent.attributeType = m_attributeType;
				holdStartEvent.attributeData = m_attributeDisplayController.GetAttributeData();
				holdStartEvent.actionName = evt.GetActionName();
				QueueEvent( holdStartEvent );
				m_holdStarted = true;
				if( !( m_data.availableToUpgrade ) || !( m_dataManager.IsAttributeUpgradeable( m_attributeType ) ) )
				{
					PlaySound( 'Attributes', 'OnFail' );
					m_attributeDisplayController.PlayAnimation( ( ( m_isReversed ) ? ( 'locked_attribute_reverse' ) : ( 'locked_attribute' ) ) );
				}
			}
			if( progress >= 1.0 )
			{
				if( !( m_recentlyPurchased ) )
				{
					m_recentlyPurchased = true;
					upgradeEvent = new AttributeUpgradePurchased;
					upgradeEvent.attributeType = m_attributeType;
					upgradeEvent.attributeData = m_attributeDisplayController.GetAttributeData();
					QueueEvent( upgradeEvent );
					if( m_data.availableToUpgrade && m_dataManager.IsAttributeUpgradeable( m_attributeType ) )
					{
						m_attributeDisplayController.PlayAnimation( ( ( m_isReversed ) ? ( 'buy_attribute_reverse' ) : ( 'buy_attribute' ) ) );
						PlayLibraryAnimation( 'buy_wire_anim' );
					}
				}
			}
			else
			{
				m_recentlyPurchased = false;
			}
		}
	}

	protected event OnContainerHoverOver( evt : inkPointerEvent )
	{
		ShowProficiencyButton( true );
	}

	protected event OnContainerHoverOut( evt : inkPointerEvent )
	{
		ShowProficiencyButton( false );
		m_holdStarted = false;
	}

	protected event OnAttributeItemHoverOver( evt : inkPointerEvent )
	{
		ShowProficiencyButton( true );
	}

	protected event OnAttributeItemHoverOut( evt : inkPointerEvent ) {}

	protected function PlayConnectionAnimation( value : Bool )
	{
		var transparencyAnimation : inkAnimDef;
		var transparencyInterpolator : inkAnimTransparency;
		transparencyAnimation = new inkAnimDef;
		transparencyInterpolator = new inkAnimTransparency;
		transparencyInterpolator.SetDuration( 0.34999999 );
		transparencyInterpolator.SetDirection( inkanimInterpolationDirection.To );
		transparencyInterpolator.SetType( inkanimInterpolationType.Linear );
		transparencyInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		transparencyInterpolator.SetEndTransparency( ( ( value ) ? ( 1.0 ) : ( 0.0 ) ) );
		transparencyAnimation.AddInterpolator( transparencyInterpolator );
		inkImageRef.PlayAnimation( m_connectionLine, transparencyAnimation );
	}

	private function StopHoverAnimations()
	{
		if( m_cool_in_proxy )
		{
			m_cool_in_proxy.Stop();
		}
		if( m_cool_out_proxy )
		{
			m_cool_out_proxy.Stop();
		}
	}

	private function ShowProficiencyButton( value : Bool )
	{
		var i, count : Int32;
		var hoverOverEvent : PerksMenuAttributeItemHoverOver;
		var hoverOutEvent : PerksMenuAttributeItemHoverOut;
		count = m_proficiencyButtonRefs.Size();
		for( i = 0; i < count; i += 1 )
		{
			inkWidgetRef.SetVisible( m_proficiencyButtonRefs[ i ], value );
		}
		if( value )
		{
			m_attributeDisplayController.SetHovered( true );
			PlayConnectionAnimation( true );
			hoverOverEvent = new PerksMenuAttributeItemHoverOver;
			hoverOverEvent.widget = GetRootWidget();
			hoverOverEvent.attributeType = m_attributeType;
			hoverOverEvent.attributeData = m_attributeDisplayController.GetAttributeData();
			QueueEvent( hoverOverEvent );
			StopHoverAnimations();
			m_cool_in_proxy = m_attributeDisplayController.PlayAnimation( ( ( m_isReversed ) ? ( 'cool_attribute_hover_in_reverse' ) : ( 'cool_attribute_hover_in' ) ) );
		}
		else
		{
			m_attributeDisplayController.SetHovered( false );
			PlayConnectionAnimation( false );
			hoverOutEvent = new PerksMenuAttributeItemHoverOut;
			hoverOutEvent.widget = GetRootWidget();
			hoverOutEvent.attributeType = m_attributeType;
			hoverOutEvent.attributeData = m_attributeDisplayController.GetAttributeData();
			QueueEvent( hoverOutEvent );
			StopHoverAnimations();
			m_cool_out_proxy = m_attributeDisplayController.PlayAnimation( ( ( m_isReversed ) ? ( 'cool_attribute_hover_out_reverse' ) : ( 'cool_attribute_hover_out' ) ) );
		}
	}

}

class ProficiencyButtonController extends inkButtonController
{
	private editable var m_labelText : inkTextRef;
	private editable var m_levelText : inkTextRef;
	private editable var m_frameHovered : inkWidgetRef;
	private var m_transparencyAnimationProxy : inkAnimProxy;
	private var m_index : Int32;

	protected event OnInitialize()
	{
		RegisterToCallback( 'OnButtonStateChanged', this, 'OnButtonStateChanged' );
	}

	public function SetLabel( const value : ref< String > )
	{
		inkTextRef.SetText( m_labelText, value );
	}

	public function SetLevel( value : Int32 )
	{
		var levelParams : inkTextParams;
		levelParams = new inkTextParams;
		levelParams.AddNumber( "level", value );
		inkTextRef.SetTextParameters( m_levelText, levelParams );
	}

	public function SetIndex( value : Int32 )
	{
		m_index = value;
	}

	public function GetIndex() : Int32
	{
		return m_index;
	}

	protected event OnButtonStateChanged( controller : weak< inkButtonController >, oldState : inkEButtonState, newState : inkEButtonState )
	{
		switch( newState )
		{
			case inkEButtonState.Normal:
				PlaySelectionAnimation( false );
			break;
			case inkEButtonState.Hover:
				PlaySelectionAnimation( true );
			break;
			case inkEButtonState.Press:
				PlaySound( 'Button', 'OnPress' );
			break;
			case inkEButtonState.Disabled:
				break;
		}
	}

	private function PlaySelectionAnimation( value : Bool )
	{
		var transparencyAnimation : inkAnimDef;
		var transparencyInterpolator : inkAnimTransparency;
		transparencyAnimation = new inkAnimDef;
		transparencyInterpolator = new inkAnimTransparency;
		transparencyInterpolator.SetDuration( 0.34999999 );
		transparencyInterpolator.SetDirection( inkanimInterpolationDirection.To );
		transparencyInterpolator.SetType( inkanimInterpolationType.Linear );
		transparencyInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		transparencyInterpolator.SetEndTransparency( ( ( value ) ? ( 1.0 ) : ( 0.0 ) ) );
		transparencyAnimation.AddInterpolator( transparencyInterpolator );
		if( m_transparencyAnimationProxy && m_transparencyAnimationProxy.IsPlaying() )
		{
			m_transparencyAnimationProxy.Stop();
		}
		m_transparencyAnimationProxy = inkWidgetRef.PlayAnimation( m_frameHovered, transparencyAnimation );
	}

}

