class WantedBarGameController extends inkHUDGameController
{
	private const editable var starsWidget : array< inkWidgetRef >;
	private var m_wantedBlackboard : weak< IBlackboard >;
	private var m_wantedBlackboardDef : UI_WantedBarDef;
	private var m_wantedDataCallbackID : CallbackHandle;
	private var m_wantedStateCallbackID : CallbackHandle;
	private var m_wantedZoneCallbackID : CallbackHandle;
	private var m_introAnimProxy : inkAnimProxy;
	private var m_bountyStarAnimProxy : array< inkAnimProxy >;
	private var m_bountyAnimProxy : inkAnimProxy;
	private var m_animOptionsLoop : inkAnimOptions;
	private var m_currentState : Int32;
	private var m_numOfStar : Int32;
	private var m_wantedLevel : Int32;
	private var m_rootWidget : weak< inkWidget >;
	private var m_isDogtown : Bool;
	private const var WANTED_TIER_1 : Float;
	default WANTED_TIER_1 = 1.0f;
	private const var WANTED_MIN : Float;
	default WANTED_MIN = 0.1f;

	protected event OnInitialize()
	{
		m_rootWidget = GetRootWidget();
		m_rootWidget.SetVisible( false );
		m_wantedBlackboardDef = GetAllBlackboardDefs().UI_WantedBar;
		m_wantedBlackboard = GetBlackboardSystem().Get( m_wantedBlackboardDef );
		m_wantedDataCallbackID = m_wantedBlackboard.RegisterListenerInt( m_wantedBlackboardDef.CurrentWantedLevel, this, 'OnWantedDataChange', true );
		m_wantedStateCallbackID = m_wantedBlackboard.RegisterListenerName( m_wantedBlackboardDef.CurrentChaseState, this, 'OnWantedStateChange', true );
		m_numOfStar = starsWidget.Size();
		m_bountyStarAnimProxy.Resize( m_numOfStar );
		m_wantedBlackboard.SetInt( GetAllBlackboardDefs().UI_WantedBar.DeescalationStages, 3, true );
		m_wantedBlackboard.SetFloat( GetAllBlackboardDefs().UI_WantedBar.BlinkingStarsDurationTime, 25.0, true );
		UpdateWantedBar( m_wantedBlackboard.GetInt( m_wantedBlackboardDef.CurrentWantedLevel ) );
	}

	protected event OnUninitialize()
	{
		m_wantedBlackboard.UnregisterDelayedListener( m_wantedBlackboardDef.CurrentWantedLevel, m_wantedDataCallbackID );
		m_wantedBlackboard.UnregisterDelayedListener( m_wantedBlackboardDef.CurrentChaseState, m_wantedStateCallbackID );
	}

	protected event OnWantedDataChange( value : Int32 )
	{
		UpdateWantedBar( value );
	}

	protected event OnWantedStateChange( value : CName )
	{
		var i : Int32;
		var star : StarController;
		for( i = 0; i < m_numOfStar; i += 1 )
		{
			star = ( ( StarController )( inkWidgetRef.GetController( starsWidget[ i ] ) ) );
			star.UpdateState( value );
			if( value == 'Dropping' && inkWidgetRef.IsVisible( starsWidget[ i ] ) )
			{
				star.StartBlink( m_wantedBlackboard.GetFloat( m_wantedBlackboardDef.BlinkingStarsDurationTime ), m_wantedBlackboard.GetInt( m_wantedBlackboardDef.DeescalationStages ) );
			}
		}
	}

	public function UpdateWantedBar( newWantedLevel : Int32 )
	{
		var i : Int32;
		var isWanted : Bool;
		var state : CName;
		var star : StarController;
		isWanted = newWantedLevel > 0;
		state = ( ( isWanted ) ? ( m_wantedBlackboard.GetName( m_wantedBlackboardDef.CurrentChaseState ) ) : ( 'Default' ) );
		for( i; i < m_numOfStar; i += 1 )
		{
			star = ( ( StarController )( inkWidgetRef.GetController( starsWidget[ i ] ) ) );
			if( i < newWantedLevel )
			{
				star.SetBounty( true );
			}
			else if( i >= newWantedLevel )
			{
				star.SetBounty( false );
			}
			if( isWanted )
			{
				star.UpdateState( state );
			}
			else
			{
				star.UpdateState( state );
			}
		}
		m_wantedLevel = newWantedLevel;
		if( !( m_rootWidget.IsVisible() ) && isWanted )
		{
			m_introAnimProxy = PlayLibraryAnimation( 'stars_intro' );
			m_introAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnWantedBarIntro' );
		}
		m_rootWidget.SetVisible( isWanted );
	}

	private function StopBountyAnims()
	{
		var i : Int32;
		m_bountyAnimProxy.GotoEndAndStop();
		for( i; i < m_numOfStar; i += 1 )
		{
			m_bountyStarAnimProxy[ i ].GotoEndAndStop();
		}
	}

	private function FlashAndHide()
	{
		StopBountyAnims();
		if( m_rootWidget.IsVisible() )
		{
			m_bountyAnimProxy = PlayLibraryAnimation( 'flash_and_hide' );
			m_bountyAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnWantedBarHidden' );
		}
	}

	protected event OnWantedBarHidden( animationProxy : inkAnimProxy )
	{
		StopBountyAnims();
		m_rootWidget.SetVisible( false );
		m_bountyAnimProxy.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnWantedBarHidden' );
	}

	protected event OnWantedBarIntro( animationProxy : inkAnimProxy )
	{
		m_rootWidget.SetVisible( true );
		m_introAnimProxy.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnWantedBarIntro' );
	}

}

class StarController extends inkLogicController
{
	private var m_animIntroProxy : inkAnimProxy;
	private var m_animIntroOptions : inkAnimOptions;
	private var m_rootWidget : weak< inkWidget >;
	private var m_animBlink : inkAnimDef;
	private var m_animBlinkProxy : inkAnimProxy;
	private var m_animBlinkOptions : inkAnimOptions;
	private var m_animBlinkLoops : Uint32[ 3 ];
	private var m_animBlinkLastStage : Int32;
	private var m_blinkAnimLoopType : inkanimLoopType;
	default m_blinkAnimLoopType = inkanimLoopType.Cycle;
	private var m_blinkDuration : Float;
	default m_blinkDuration = 1.0f;
	private editable var bountyBadgeWidget : inkWidgetRef;
	[ tooltip = "Time Dilation for blink 1st stage, biggger -> quicker blinks" ][ category = "Animation" ]
	private editable var m_blinkSpeed1 : Float;
	default m_blinkSpeed1 = 1.f;
	[ tooltip = "Time Dilation for blink 1st stage, biggger -> quicker blinks" ][ category = "Animation" ]
	private editable var m_blinkSpeed2 : Float;
	default m_blinkSpeed2 = 2.f;
	[ tooltip = "Time Dilation for blink 1st stage, biggger -> quicker blinks" ][ category = "Animation" ]
	private editable var m_blinkSpeed3 : Float;
	default m_blinkSpeed3 = 3.f;
	[ category = "Animation" ]
	private editable var m_blinkAnimInterpolationMode : inkanimInterpolationMode;
	default m_blinkAnimInterpolationMode = inkanimInterpolationMode.EasyIn;
	[ category = "Animation" ]
	private editable var m_blinkAnimInterpolationType : inkanimInterpolationType;
	default m_blinkAnimInterpolationType = inkanimInterpolationType.Linear;
	[ category = "Icon " ]
	private editable var m_icon : inkImageRef;
	[ category = "Icon " ]
	private editable var m_iconBg : inkImageRef;
	[ category = "Icon " ]
	private editable var m_ncpdIconName : CName;
	default m_ncpdIconName = 'star_active';
	[ category = "Icon " ]
	private editable var m_ncpdIconBgName : CName;
	default m_ncpdIconBgName = 'star_shadow';
	[ category = "Icon " ]
	private editable var m_dogtownIconName : CName;
	default m_dogtownIconName = 'kutrz_active';
	[ category = "Icon " ]
	private editable var m_dogtownIconBgName : CName;
	default m_dogtownIconBgName = 'kutrz_shadow';

	protected event OnInitialize()
	{
		m_rootWidget = GetRootWidget();
		m_animBlinkLastStage = 0;
		CreateBlinkAnimation();
		inkImageRef.SetTexturePart( m_icon, m_ncpdIconName );
		inkImageRef.SetTexturePart( m_iconBg, m_ncpdIconBgName );
	}

	private function CreateBlinkAnimation()
	{
		var transparencyInterp : inkAnimTransparency;
		var sectionDuration : Float;
		sectionDuration = m_blinkDuration / 2.0;
		m_animBlink = new inkAnimDef;
		transparencyInterp = new inkAnimTransparency;
		transparencyInterp.SetMode( m_blinkAnimInterpolationMode );
		transparencyInterp.SetType( m_blinkAnimInterpolationType );
		transparencyInterp.SetStartTransparency( 1.0 );
		transparencyInterp.SetEndTransparency( 0.0 );
		transparencyInterp.SetDuration( sectionDuration );
		m_animBlink.AddInterpolator( transparencyInterp );
		transparencyInterp.SetStartDelay( sectionDuration );
		transparencyInterp.SetStartTransparency( 0.0 );
		transparencyInterp.SetEndTransparency( 1.0 );
		transparencyInterp.SetDuration( sectionDuration );
		m_animBlink.AddInterpolator( transparencyInterp );
		m_animBlinkOptions.loopType = m_blinkAnimLoopType;
	}

	private function PlayBlink( stage : Int32 )
	{
		switch( stage )
		{
			case 0:
				m_animBlinkOptions.customTimeDilation = m_blinkSpeed1;
			break;
			case 1:
				m_animBlinkOptions.customTimeDilation = m_blinkSpeed2;
			break;
			case 2:
				m_animBlinkOptions.customTimeDilation = m_blinkSpeed3;
			break;
		}
		m_animBlinkOptions.applyCustomTimeDilation = true;
		m_animBlinkOptions.loopCounter = m_animBlinkLoops[ stage ];
		m_animBlinkProxy = inkWidgetRef.PlayAnimationWithOptions( bountyBadgeWidget, m_animBlink, m_animBlinkOptions );
		m_animBlinkLastStage = stage;
	}

	public function SetBounty( arg : Bool )
	{
		if( arg != inkWidgetRef.IsVisible( bountyBadgeWidget ) )
		{
			m_animIntroProxy.GotoEndAndStop();
			if( arg )
			{
				inkWidgetRef.SetVisible( bountyBadgeWidget, arg );
				m_animIntroProxy = PlayLibraryAnimationOnAutoSelectedTargets( 'bounty_intro', inkWidgetRef.Get( bountyBadgeWidget ) );
			}
			else
			{
				m_animIntroOptions.playReversed = true;
				m_animIntroProxy = PlayLibraryAnimationOnAutoSelectedTargets( 'bounty_intro', inkWidgetRef.Get( bountyBadgeWidget ), m_animIntroOptions );
				inkWidgetRef.SetVisible( bountyBadgeWidget, arg );
			}
		}
	}

	public function UpdateState( newState : CName )
	{
		if( newState != m_rootWidget.GetState() )
		{
			if( newState != 'Dropping' && m_animBlinkProxy.IsPlaying() )
			{
				StopBlink();
			}
			m_rootWidget.SetState( newState );
		}
	}

	public function StartBlink( timeTotal : Float, stages : Int32 )
	{
		var timeStage : Float;
		timeStage = timeTotal / ( ( Float )( stages ) );
		m_animBlinkLoops[ 0 ] = ( ( Uint32 )( RoundMath( ( timeStage * m_blinkSpeed1 ) / m_blinkDuration ) ) );
		m_animBlinkLoops[ 1 ] = ( ( Uint32 )( RoundMath( ( timeStage * m_blinkSpeed2 ) / m_blinkDuration ) ) );
		m_animBlinkLoops[ 2 ] = ( ( Uint32 )( RoundMath( ( timeStage * m_blinkSpeed3 ) / m_blinkDuration ) ) );
		StopBlink();
		PlayBlink( 0 );
		m_animBlinkProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnBlinkLoopFinished' );
	}

	public function StopBlink()
	{
		m_animBlinkProxy.GotoStartAndStop();
		m_animBlinkProxy.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnBlinkLoopFinished' );
		inkWidgetRef.SetOpacity( bountyBadgeWidget, 1.0 );
	}

	protected event OnBlinkLoopFinished( animProxy : inkAnimProxy )
	{
		if( m_animBlinkLastStage < ( m_animBlinkLoops.Size() - 1 ) )
		{
			PlayBlink( m_animBlinkLastStage + 1 );
			m_animBlinkProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnBlinkLoopFinished' );
		}
		else
		{
			m_animBlinkProxy.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnBlinkLoopFinished' );
			inkWidgetRef.SetOpacity( bountyBadgeWidget, 1.0 );
		}
	}

}

