class ProgressBarSimpleWidgetLogicController extends inkLogicController
{
	private var m_width : Float;
	private var m_height : Float;
	var m_currentValue : Float;
	default m_currentValue = 1;
	var m_previousValue : Float;
	default m_previousValue = 1;
	var m_MaxCNBarFlashSize : Float;
	default m_MaxCNBarFlashSize = 500;
	editable var m_fullBar : inkWidgetRef;
	editable var m_changePBar : inkWidgetRef;
	editable var m_changeNBar : inkWidgetRef;
	editable var m_emptyBar : inkWidgetRef;
	editable var m_barCap : inkWidgetRef;
	editable var m_damagePreviewBar : inkWidgetRef;
	editable var m_showBarCap : Bool;
	default m_showBarCap = false;
	editable var m_animDuration : Float;
	default m_animDuration = 2;
	private var m_full_anim_proxy : inkAnimProxy;
	private var m_full_anim : inkAnimDef;
	private var m_empty_anim_proxy : inkAnimProxy;
	private var m_empty_anim : inkAnimDef;
	private var m_changeP_anim_proxy : inkAnimProxy;
	private var m_changeP_anim : inkAnimDef;
	private var m_changeN_anim_proxy : inkAnimProxy;
	private var m_changeN_anim : inkAnimDef;
	private var m_barCap_anim_proxy : inkAnimProxy;
	private var m_barCap_anim : inkAnimDef;
	protected var m_rootWidget : weak< inkCompoundWidget >;

	protected event OnInitialize()
	{
		SetDefaultValues();
		inkWidgetRef.SetVisible( m_barCap, false );
		m_rootWidget = ( ( inkCompoundWidget )( GetRootWidget() ) );
	}

	public function SetDefaultValues()
	{
		var tempSize : Vector2;
		tempSize = inkWidgetRef.GetSize( m_fullBar );
		m_width = tempSize.X;
		m_height = tempSize.Y;
		inkWidgetRef.SetSize( m_fullBar, Vector2( m_width, m_height ) );
		inkWidgetRef.SetSize( m_changePBar, Vector2( 0.0, m_height ) );
		inkWidgetRef.SetSize( m_changeNBar, Vector2( 0.0, m_height ) );
		inkWidgetRef.SetSize( m_emptyBar, Vector2( 0.0, m_height ) );
	}

	public function SetProgress( newValue : Float, silent : Bool ) : Bool
	{
		var sizeInterpolator : inkAnimSize;
		var barSize : Vector2;
		var sizeF, sizeCP, sizeCN, sizeE : Float;
		var visualCNMax : Float;
		var playNegativeFlashAnim : Bool;
		var negativeMargin : inkMargin;
		var fullBarSize : Vector2;
		m_previousValue = m_currentValue;
		m_currentValue = newValue;
		if( m_showBarCap )
		{
			inkWidgetRef.SetVisible( m_barCap, newValue != 1.0 );
		}
		if( silent )
		{
			if( m_full_anim_proxy )
			{
				m_full_anim_proxy.Stop();
			}
			if( m_empty_anim_proxy )
			{
				m_empty_anim_proxy.Stop();
			}
			if( m_changeP_anim_proxy )
			{
				m_changeP_anim_proxy.Stop();
			}
			if( m_changeN_anim_proxy )
			{
				m_changeN_anim_proxy.Stop();
			}
			if( m_barCap_anim_proxy )
			{
				m_barCap_anim_proxy.Stop();
			}
			inkWidgetRef.SetSize( m_fullBar, Vector2( m_width * m_currentValue, m_height ) );
			inkWidgetRef.SetSize( m_changePBar, Vector2( 0.0, m_height ) );
			inkWidgetRef.SetSize( m_changeNBar, Vector2( 0.0, m_height ) );
			inkWidgetRef.SetSize( m_emptyBar, Vector2( m_width * ( 1.0 - m_currentValue ), m_height ) );
		}
		else
		{
			if( ( m_previousValue - m_currentValue ) < 0.0 )
			{
				barSize = inkWidgetRef.GetSize( m_changePBar );
				sizeCP = ClampF( ( barSize.X / m_width ) + AbsF( m_previousValue - m_currentValue ), 0.0, 1.0 );
				if( m_changeN_anim_proxy.IsPlaying() )
				{
					barSize = inkWidgetRef.GetSize( m_changeNBar );
					sizeCN = ClampF( ( barSize.X / m_width ) - AbsF( m_previousValue - m_currentValue ), 0.0, 1.0 );
				}
				else
				{
					sizeCN = 0.0;
				}
			}
			else
			{
				barSize = inkWidgetRef.GetSize( m_changeNBar );
				sizeCN = ClampF( ( barSize.X / m_width ) + AbsF( m_previousValue - m_currentValue ), 0.0, 1.0 );
				if( m_changeP_anim_proxy && m_changeP_anim_proxy.IsPlaying() )
				{
					barSize = inkWidgetRef.GetSize( m_changePBar );
					sizeCP = ClampF( ( barSize.X / m_width ) - AbsF( m_previousValue - m_currentValue ), 0.0, 1.0 );
				}
				else
				{
					sizeCP = 0.0;
				}
			}
			sizeF = ClampF( m_currentValue - sizeCP, 0.0, 1.0 );
			sizeE = ClampF( ( 1.0 - m_currentValue ) - sizeCN, 0.0, 1.0 );
			if( m_full_anim_proxy )
			{
				m_full_anim_proxy.Stop();
			}
			if( m_empty_anim_proxy )
			{
				m_empty_anim_proxy.Stop();
			}
			if( m_changeP_anim_proxy )
			{
				m_changeP_anim_proxy.Stop();
			}
			if( m_changeN_anim_proxy )
			{
				m_changeN_anim_proxy.Stop();
			}
			m_full_anim = new inkAnimDef;
			sizeInterpolator = new inkAnimSize;
			sizeInterpolator.SetStartSize( Vector2( m_width * sizeF, m_height ) );
			sizeInterpolator.SetEndSize( Vector2( m_width * m_currentValue, m_height ) );
			sizeInterpolator.SetDuration( ( sizeF + sizeCP ) * m_animDuration );
			sizeInterpolator.SetStartDelay( 0.0 );
			sizeInterpolator.SetType( inkanimInterpolationType.Linear );
			sizeInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
			m_full_anim.AddInterpolator( sizeInterpolator );
			m_changeP_anim = new inkAnimDef;
			sizeInterpolator = new inkAnimSize;
			sizeInterpolator.SetStartSize( Vector2( m_width * sizeCP, m_height ) );
			sizeInterpolator.SetEndSize( Vector2( 0.0, m_height ) );
			sizeInterpolator.SetDuration( ( sizeF + sizeCP ) * m_animDuration );
			sizeInterpolator.SetStartDelay( 0.0 );
			sizeInterpolator.SetType( inkanimInterpolationType.Linear );
			sizeInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
			m_changeP_anim.AddInterpolator( sizeInterpolator );
			visualCNMax = MinF( m_MaxCNBarFlashSize, m_width * AbsF( sizeCN ) );
			m_changeN_anim = new inkAnimDef;
			sizeInterpolator = new inkAnimSize;
			sizeInterpolator.SetStartSize( Vector2( visualCNMax, m_height ) );
			sizeInterpolator.SetEndSize( Vector2( 0.0, m_height ) );
			sizeInterpolator.SetDuration( ( sizeE + sizeCN ) * m_animDuration );
			sizeInterpolator.SetStartDelay( 0.0 );
			sizeInterpolator.SetType( inkanimInterpolationType.Linear );
			sizeInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
			m_changeN_anim.AddInterpolator( sizeInterpolator );
			m_empty_anim = new inkAnimDef;
			sizeInterpolator = new inkAnimSize;
			sizeInterpolator.SetStartSize( Vector2( m_width * sizeE, m_height ) );
			sizeInterpolator.SetEndSize( Vector2( m_width * ( 1.0 - m_currentValue ), m_height ) );
			sizeInterpolator.SetDuration( ( sizeE + sizeCN ) * m_animDuration );
			sizeInterpolator.SetStartDelay( 0.0 );
			sizeInterpolator.SetType( inkanimInterpolationType.Linear );
			sizeInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
			m_empty_anim.AddInterpolator( sizeInterpolator );
			if( ( sizeF + sizeCP ) > 0.0 )
			{
				m_full_anim_proxy = inkWidgetRef.PlayAnimation( m_fullBar, m_full_anim );
				m_changeP_anim_proxy = inkWidgetRef.PlayAnimation( m_changePBar, m_changeP_anim );
			}
			if( ( sizeE + sizeCN ) > 0.0 )
			{
				playNegativeFlashAnim = true;
				m_changeN_anim_proxy = inkWidgetRef.PlayAnimation( m_changeNBar, m_changeN_anim );
				m_empty_anim_proxy = inkWidgetRef.PlayAnimation( m_emptyBar, m_empty_anim );
			}
			if( ( sizeF + sizeCP ) <= 0.0 )
			{
				inkWidgetRef.SetSize( m_fullBar, Vector2( m_width * sizeF, m_height ) );
				inkWidgetRef.SetSize( m_changePBar, Vector2( m_width * sizeCP, m_height ) );
			}
			if( ( sizeE + sizeCN ) <= 0.0 )
			{
				inkWidgetRef.SetSize( m_changeNBar, Vector2( m_width * sizeCN, m_height ) );
				inkWidgetRef.SetSize( m_emptyBar, Vector2( m_width * sizeE, m_height ) );
			}
		}
		fullBarSize = inkWidgetRef.GetSize( m_fullBar );
		negativeMargin.left = fullBarSize.X;
		inkWidgetRef.SetMargin( m_changeNBar, negativeMargin );
		inkWidgetRef.SetMargin( m_damagePreviewBar, negativeMargin );
		return playNegativeFlashAnim;
	}

	public function GetFullSize() : Vector2
	{
		return Vector2( m_width, m_height );
	}

}

class NameplateBarLogicController extends ProgressBarSimpleWidgetLogicController
{
	private var damagePreview : weak< DamagePreviewController >;

	public function SetNameplateBarProgress( newValue : Float, silent : Bool )
	{
		var playNegativeFlashAnim : Bool;
		playNegativeFlashAnim = super.SetProgress( newValue, silent );
		if( playNegativeFlashAnim )
		{
			PlayLibraryAnimation( 'ProgressBar_Change_Flash' );
		}
	}

	public function SetDamagePreview( damage : Float, offset : Float )
	{
		if( damagePreview == NULL )
		{
			damagePreview = ( ( DamagePreviewController )( SpawnFromLocal( m_rootWidget, 'damagePreview' ).GetController() ) );
		}
		damagePreview.SetPreview( damage, offset );
	}

}

