class RipperdocMetersBase extends inkLogicController
{
	[ category = "Base" ]
	protected editable var m_barAnchor : inkWidgetRef;
	[ category = "Base" ]
	protected editable var m_hoverArea : inkWidgetRef;
	[ category = "Base Bars" ]
	protected editable var m_barWidgetLibraryName : CName;
	[ category = "Base Bars" ]
	protected editable var m_barGapSize : Float;
	default m_barGapSize = 12.f;
	[ tooltip = "Magic Number use for slope bars length calculation" ][ category = "Base Bars" ]
	protected editable var m_slopeLengthModifier : Float;
	[ category = "Base Bars" ]
	protected editable var barIntroAnimDuration : Float;
	default barIntroAnimDuration = 0.3f;
	[ tooltip = "Value use to calculated labels offsets. Need to be updated evetime actual bars properties is changed." ][ category = "Base Bars" ]
	protected editable var m_barsHeigh : Float;
	[ tooltip = "Value use to calculated labels offsets. Need to be updated evetime actual bars properties is changed." ][ category = "Base Bars" ]
	protected editable var m_barsMargin : Float;
	[ category = "Base Constants" ]
	protected const editable var BAR_COUNT : Int32;
	default BAR_COUNT = 50;
	[ category = "Base Constants" ]
	protected const editable var BAR_SLOPE_COUNT : Int32;
	default BAR_SLOPE_COUNT = 4;
	[ category = "Base Constants" ]
	protected const editable var BAR_ANIM_DURATION : Float;
	default BAR_ANIM_DURATION = 0.3f;
	[ category = "Base Constants" ]
	protected const editable var BAR_DELAY_OFFSET : Float;
	default BAR_DELAY_OFFSET = 0.050;
	[ category = "Base Pulse Params" ]
	protected editable var m_pulseAnimtopOpacity : Float;
	default m_pulseAnimtopOpacity = 1.0f;
	[ category = "Base Pulse Params" ]
	protected editable var m_pulseAnimbottomOpacity : Float;
	default m_pulseAnimbottomOpacity = 0.2f;
	[ category = "Base Pulse Params" ]
	protected editable var m_pulseAnimpulseRate : Float;
	default m_pulseAnimpulseRate = 0.4f;
	[ category = "Base Pulse Params" ]
	protected editable var m_pulseAnimdelay : Float;
	default m_pulseAnimdelay = 0.1f;
	protected var m_pulseAnimationParams : PulseAnimationParams;
	protected var m_bars : array< weak< RipperdocNewMeterBar > >;
	protected var m_barGaps : array< Int32 >;
	protected var m_tooltipData : RipperdocBarTooltipTooltipData;
	protected var m_barIntroAnimDef : inkAnimDef;
	protected var m_barIntroAnimProxy : inkAnimProxy;
	protected var m_isIntroPlayed : Bool;

	protected function MoveLabelToBar( labelContainer : inkWidgetRef, bar : RipperdocNewMeterBar, animProxy : inkAnimProxy, alignToTop : Bool, instant : Bool )
	{
		var distance : Vector2;
		var verticalDelta : Float;
		var oldMargin : inkMargin;
		var newMargin : inkMargin;
		var newTopMargin : Float;
		var animation : inkAnimDef;
		var marginInterpolator : inkAnimMargin;
		distance = WidgetUtils.WidgetToWidget( inkWidgetRef.Get( labelContainer ), bar.GetRootWidget() );
		if( animProxy != NULL )
		{
			animProxy.GotoEndAndStop();
		}
		oldMargin = inkWidgetRef.GetMargin( labelContainer );
		newTopMargin = distance.Y;
		if( alignToTop )
		{
			newTopMargin -= bar.GetHeight();
		}
		newTopMargin = MaxF( newTopMargin, 0.0 );
		newMargin = inkMargin( oldMargin.left, newTopMargin, oldMargin.right, oldMargin.bottom );
		verticalDelta = AbsF( oldMargin.top - distance.Y );
		if( verticalDelta != 0.0 )
		{
			verticalDelta -= bar.GetHeight();
			marginInterpolator = new inkAnimMargin;
			marginInterpolator.SetDuration( ( ( instant ) ? ( 0.0 ) : ( MinF( verticalDelta * 0.1, 0.30000001 ) ) ) );
			marginInterpolator.SetStartMargin( oldMargin );
			marginInterpolator.SetEndMargin( newMargin );
			marginInterpolator.SetType( inkanimInterpolationType.Sinusoidal );
			marginInterpolator.SetMode( inkanimInterpolationMode.EasyOut );
			animation = new inkAnimDef;
			animation.AddInterpolator( marginInterpolator );
			animProxy = inkWidgetRef.PlayAnimation( labelContainer, animation );
			inkWidgetRef.PlayAnimation( labelContainer, animation );
			if( !( m_isIntroPlayed ) )
			{
				m_isIntroPlayed = true;
				animProxy.RegisterToCallback( inkanimEventType.OnStart, this, 'OnIntroAnimationFinished_METER' );
			}
		}
	}

	protected function GetSlopeAnimOffset( index : Int32, originBar : Int32 ) : Float
	{
		return SqrF( ( ( Float )( index - originBar ) ) ) * m_slopeLengthModifier;
	}

	protected function SetupBarIntroAnimation()
	{
		var scaleInterpolator : inkAnimScale;
		m_barIntroAnimDef = new inkAnimDef;
		scaleInterpolator = new inkAnimScale;
		scaleInterpolator.SetMode( inkanimInterpolationMode.EasyOut );
		scaleInterpolator.SetType( inkanimInterpolationType.Linear );
		scaleInterpolator.SetStartScale( Vector2( 0.0, 1.0 ) );
		scaleInterpolator.SetEndScale( Vector2( 1.0, 1.0 ) );
		scaleInterpolator.SetDuration( barIntroAnimDuration );
		m_barIntroAnimDef.AddInterpolator( scaleInterpolator );
	}

	protected function StartPulse( pulse : PulseAnimation, params : PulseAnimationParams, target : weak< inkWidget > )
	{
		pulse.Configure( target, 1.0, 0.2, 0.40000001, 0.1 );
		pulse.Start( false );
	}

	protected function StopPulse( pulse : PulseAnimation )
	{
		if( pulse )
		{
			pulse.Stop();
		}
	}

	protected function SetupPulseAnimParams( topOpacity, bottomOpacity, pulseRate, delay : Float )
	{
		m_pulseAnimationParams.topOpacity = topOpacity;
		m_pulseAnimationParams.bottomOpacity = bottomOpacity;
		m_pulseAnimationParams.pulseRate = pulseRate;
		m_pulseAnimationParams.delay = delay;
	}

	protected event OnBarHoverOver( evt : inkPointerEvent )
	{
		var barHoverOverEvent : BarHoverOverEvent;
		barHoverOverEvent = new BarHoverOverEvent;
		barHoverOverEvent.data = m_tooltipData;
		QueueEvent( barHoverOverEvent );
	}

	protected event OnBarHoverOut( evt : inkPointerEvent )
	{
		var barHoverOutEvent : BarHoverOutEvent;
		barHoverOutEvent = new BarHoverOutEvent;
		QueueEvent( barHoverOutEvent );
	}

}

class BarHoverOverEvent extends Event
{
	var data : RipperdocBarTooltipTooltipData;
}

