class CrosshairGameController_Basic extends gameuiCrosshairBaseGameController
{
	private editable var m_leftPart : inkImageRef;
	private editable var m_rightPart : inkImageRef;
	private editable var m_upPart : inkImageRef;
	private editable var m_downPart : inkImageRef;
	private editable var m_centerPart : inkImageRef;
	private var m_bufferedSpread : Vector2;
	private var m_currentFireMode : gamedataTriggerMode;
	private var m_weaponlocalBB : weak< IBlackboard >;
	private var m_bbcurrentFireMode : CallbackHandle;
	private var m_ricochetModeActive : Uint32;
	private var m_RicochetChance : Uint32;
	editable var m_horizontalMinSpread : Float;
	default m_horizontalMinSpread = 20;
	editable var m_verticalMinSpread : Float;
	default m_verticalMinSpread = 20;
	editable var m_gameplaySpreadMultiplier : Float;
	default m_gameplaySpreadMultiplier = 1;

	protected event OnPreIntro()
	{
		GetRootWidget().SetOpacity( 0.0 );
		m_weaponlocalBB = GetWeaponLocalBlackboard();
		m_bbcurrentFireMode = m_weaponlocalBB.RegisterListenerVariant( GetAllBlackboardDefs().Weapon.TriggerMode, this, 'OnTriggerModeChanged' );
		m_currentFireMode = gamedataTriggerMode.Invalid;
		super.OnPreIntro();
	}

	protected event OnPreOutro()
	{
		if( m_weaponlocalBB )
		{
			m_weaponlocalBB.UnregisterListenerVariant( GetAllBlackboardDefs().Weapon.TriggerMode, m_bbcurrentFireMode );
		}
		super.OnPreOutro();
	}

	protected function OnTriggerModeChanged( value : Variant )
	{
		var record : TriggerMode_Record;
		var anim : inkAnimDef;
		var rotationInterpolator : inkAnimRotation;
		var previousFireMode : gamedataTriggerMode;
		record = ( ( TriggerMode_Record )value );
		previousFireMode = m_currentFireMode;
		m_currentFireMode = record.Type();
		if( m_currentFireMode == gamedataTriggerMode.Burst )
		{
			anim = new inkAnimDef;
			rotationInterpolator = new inkAnimRotation;
			rotationInterpolator.SetStartRotation( 0.0 );
			rotationInterpolator.SetEndRotation( -90.0 );
			rotationInterpolator.SetDuration( 0.1 );
			rotationInterpolator.SetType( inkanimInterpolationType.Linear );
			rotationInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
			anim.AddInterpolator( rotationInterpolator );
			GetRootWidget().PlayAnimation( anim );
		}
		else if( previousFireMode == gamedataTriggerMode.Burst )
		{
			anim = new inkAnimDef;
			rotationInterpolator = new inkAnimRotation;
			rotationInterpolator.SetStartRotation( -90.0 );
			rotationInterpolator.SetEndRotation( 0.0 );
			rotationInterpolator.SetDuration( 0.1 );
			rotationInterpolator.SetType( inkanimInterpolationType.Linear );
			rotationInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
			anim.AddInterpolator( rotationInterpolator );
			GetRootWidget().PlayAnimation( anim );
		}
	}

	public override function GetIntroAnimation( firstEquip : Bool ) : inkAnimProxy
	{
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( 0.0 );
		alphaInterpolator.SetEndTransparency( 1.0 );
		alphaInterpolator.SetDuration( 0.25 );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		OnShow();
		return m_rootWidget.PlayAnimation( anim );
	}

	public override function GetOutroAnimation() : inkAnimProxy
	{
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( 1.0 );
		alphaInterpolator.SetEndTransparency( 0.0 );
		alphaInterpolator.SetDuration( 0.25 );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		OnHide();
		return m_rootWidget.PlayAnimation( anim );
	}

	protected event OnBulletSpreadChanged( spread : Vector2 )
	{
		super.OnBulletSpreadChanged( spread );
		inkImageRef.SetMargin( m_leftPart, inkMargin( -( ( ( Float )( m_horizontalMinSpread ) ) + ( m_gameplaySpreadMultiplier * spread.X ) ), 0.0, 0.0, 0.0 ) );
		inkImageRef.SetMargin( m_rightPart, inkMargin( ( ( Float )( m_horizontalMinSpread ) ) + ( m_gameplaySpreadMultiplier * spread.X ), 0.0, 0.0, 0.0 ) );
		inkImageRef.SetMargin( m_upPart, inkMargin( 0.0, -( ( ( Float )( m_verticalMinSpread ) ) + ( m_gameplaySpreadMultiplier * spread.Y ) ), 0.0, 0.0 ) );
		inkImageRef.SetMargin( m_downPart, inkMargin( 0.0, ( ( Float )( m_verticalMinSpread ) ) + ( m_gameplaySpreadMultiplier * spread.Y ), 0.0, 0.0 ) );
		m_bufferedSpread = spread;
	}

	protected function ColapseCrosshair( full : Bool, duration : Float )
	{
		var anim : inkAnimDef;
		var marginInterpolator : inkAnimMargin;
		var alphaInterpolator : inkAnimTransparency;
		inkImageRef.StopAllAnimations( m_leftPart );
		inkImageRef.StopAllAnimations( m_rightPart );
		inkImageRef.StopAllAnimations( m_upPart );
		inkImageRef.StopAllAnimations( m_downPart );
		anim = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetStartMargin( inkImageRef.GetMargin( m_leftPart ) );
		marginInterpolator.SetEndMargin( inkMargin( 0.0, 0.0, 0.0, 0.0 ) );
		marginInterpolator.SetDuration( duration );
		marginInterpolator.SetType( inkanimInterpolationType.Linear );
		marginInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( marginInterpolator );
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( inkImageRef.GetOpacity( m_leftPart ) );
		alphaInterpolator.SetEndTransparency( 0.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		inkImageRef.PlayAnimation( m_leftPart, anim );
		anim = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetStartMargin( inkImageRef.GetMargin( m_rightPart ) );
		marginInterpolator.SetEndMargin( inkMargin( 0.0, 0.0, 0.0, 0.0 ) );
		marginInterpolator.SetDuration( duration );
		marginInterpolator.SetType( inkanimInterpolationType.Linear );
		marginInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( marginInterpolator );
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( inkImageRef.GetOpacity( m_rightPart ) );
		alphaInterpolator.SetEndTransparency( 0.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		inkImageRef.PlayAnimation( m_rightPart, anim );
		anim = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetStartMargin( inkImageRef.GetMargin( m_upPart ) );
		marginInterpolator.SetEndMargin( inkMargin( 0.0, 0.0, 0.0, 0.0 ) );
		marginInterpolator.SetDuration( duration );
		marginInterpolator.SetType( inkanimInterpolationType.Linear );
		marginInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( marginInterpolator );
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( inkImageRef.GetOpacity( m_upPart ) );
		alphaInterpolator.SetEndTransparency( 0.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		inkImageRef.PlayAnimation( m_upPart, anim );
		anim = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetStartMargin( inkImageRef.GetMargin( m_downPart ) );
		marginInterpolator.SetEndMargin( inkMargin( 0.0, 0.0, 0.0, 0.0 ) );
		marginInterpolator.SetDuration( duration );
		marginInterpolator.SetType( inkanimInterpolationType.Linear );
		marginInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( marginInterpolator );
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( inkImageRef.GetOpacity( m_downPart ) );
		alphaInterpolator.SetEndTransparency( 0.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		inkImageRef.PlayAnimation( m_downPart, anim );
		if( full )
		{
			HideCenterPart( duration );
		}
	}

	protected function ExpandCrosshair( full : Bool, duration : Float )
	{
		var anim : inkAnimDef;
		var marginInterpolator : inkAnimMargin;
		var alphaInterpolator : inkAnimTransparency;
		inkImageRef.StopAllAnimations( m_leftPart );
		inkImageRef.StopAllAnimations( m_rightPart );
		inkImageRef.StopAllAnimations( m_upPart );
		inkImageRef.StopAllAnimations( m_downPart );
		anim = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetStartMargin( inkMargin( 0.0, 0.0, 0.0, 0.0 ) );
		marginInterpolator.SetEndMargin( inkMargin( -( m_horizontalMinSpread ) - ( m_bufferedSpread.X * m_gameplaySpreadMultiplier ), 0.0, 0.0, 0.0 ) );
		marginInterpolator.SetDuration( duration );
		marginInterpolator.SetType( inkanimInterpolationType.Linear );
		marginInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( marginInterpolator );
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( inkImageRef.GetOpacity( m_leftPart ) );
		alphaInterpolator.SetEndTransparency( 1.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		inkImageRef.PlayAnimation( m_leftPart, anim );
		anim = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetStartMargin( inkMargin( 0.0, 0.0, 0.0, 0.0 ) );
		marginInterpolator.SetEndMargin( inkMargin( m_horizontalMinSpread + ( m_bufferedSpread.X * m_gameplaySpreadMultiplier ), 0.0, 0.0, 0.0 ) );
		marginInterpolator.SetDuration( duration );
		marginInterpolator.SetType( inkanimInterpolationType.Linear );
		marginInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( marginInterpolator );
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( inkImageRef.GetOpacity( m_rightPart ) );
		alphaInterpolator.SetEndTransparency( 1.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		inkImageRef.PlayAnimation( m_rightPart, anim );
		anim = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetStartMargin( inkMargin( 0.0, 0.0, 0.0, 0.0 ) );
		marginInterpolator.SetEndMargin( inkMargin( 0.0, -( m_verticalMinSpread ) - ( m_bufferedSpread.Y * m_gameplaySpreadMultiplier ), 0.0, 0.0 ) );
		marginInterpolator.SetDuration( duration );
		marginInterpolator.SetType( inkanimInterpolationType.Linear );
		marginInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( marginInterpolator );
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( inkImageRef.GetOpacity( m_upPart ) );
		alphaInterpolator.SetEndTransparency( 1.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		inkImageRef.PlayAnimation( m_upPart, anim );
		anim = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetStartMargin( inkMargin( 0.0, 0.0, 0.0, 0.0 ) );
		marginInterpolator.SetEndMargin( inkMargin( 0.0, m_verticalMinSpread + ( m_bufferedSpread.Y * m_gameplaySpreadMultiplier ), 0.0, 0.0 ) );
		marginInterpolator.SetDuration( duration );
		marginInterpolator.SetType( inkanimInterpolationType.Linear );
		marginInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( marginInterpolator );
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( inkImageRef.GetOpacity( m_downPart ) );
		alphaInterpolator.SetEndTransparency( 1.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		inkImageRef.PlayAnimation( m_downPart, anim );
		if( full )
		{
			ShowCenterPart( duration );
		}
	}

	private function ShowCenterPart( duration : Float )
	{
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( inkImageRef.GetOpacity( m_centerPart ) );
		alphaInterpolator.SetEndTransparency( 1.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		inkImageRef.PlayAnimation( m_centerPart, anim );
	}

	private function HideCenterPart( duration : Float )
	{
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( inkImageRef.GetOpacity( m_centerPart ) );
		alphaInterpolator.SetEndTransparency( 0.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		inkImageRef.PlayAnimation( m_centerPart, anim );
	}

	private function OnShow()
	{
		switch( GetCrosshairState() )
		{
			case gamePSMCrosshairStates.Safe:
				ShowCenterPart( 0.25 );
			break;
			default:
				ExpandCrosshair( true, 0.25 );
			break;
		}
	}

	private function OnHide()
	{
		switch( GetCrosshairState() )
		{
			case gamePSMCrosshairStates.Safe:
				HideCenterPart( 0.25 );
			break;
			default:
				ColapseCrosshair( true, 0.25 );
			break;
		}
	}

	protected override function OnState_Safe()
	{
		ColapseCrosshair( false, 0.1 );
	}

	protected override function OnState_HipFire()
	{
		ExpandCrosshair( true, 0.1 );
	}

	protected override function OnState_Aim()
	{
		ColapseCrosshair( true, 0.1 );
	}

	protected override function OnState_Reload()
	{
		ColapseCrosshair( false, 0.25 );
	}

	protected override function OnState_Sprint()
	{
		ColapseCrosshair( false, 0.1 );
	}

	protected override function OnState_GrenadeCharging()
	{
		ColapseCrosshair( false, 0.1 );
	}

	protected override function OnState_Scanning()
	{
		ColapseCrosshair( true, 0.1 );
	}

	protected override function ApplyCrosshairGUIState( state : CName, aimedAtEntity : Entity )
	{
		inkImageRef.SetState( m_leftPart, state );
		inkImageRef.SetState( m_rightPart, state );
		inkImageRef.SetState( m_upPart, state );
		inkImageRef.SetState( m_downPart, state );
	}

}

