class CrosshairGameController_Tech_Hex extends BaseTechCrosshairController
{
	private var m_leftBracket : weak< inkImage >;
	private var m_rightBracket : weak< inkImage >;
	private var m_hori : weak< inkWidget >;
	private var m_chargeBar : weak< inkWidget >;
	private var m_chargeBoth : weak< inkWidget >;
	private var m_chargeLeftBar : weak< inkRectangle >;
	private var m_chargeRightBar : weak< inkRectangle >;
	private var m_centerPart : weak< inkImage >;
	private var m_fluffCanvas : weak< inkWidget >;
	var m_chargeAnimationProxy : inkAnimProxy;
	private var m_bufferedSpread : Vector2;
	private var m_weaponlocalBB : weak< IBlackboard >;
	private var m_bbcharge : CallbackHandle;
	private var m_bbcurrentFireMode : CallbackHandle;
	private var m_currentFireMode : gamedataTriggerMode;
	private var m_bbNPCStatsInfo : CallbackHandle;
	editable var m_horizontalMinSpread : Float;
	default m_horizontalMinSpread = 0;
	editable var m_verticalMinSpread : Float;
	default m_verticalMinSpread = 0;
	editable var m_gameplaySpreadMultiplier : Float;
	default m_gameplaySpreadMultiplier = 1;
	private var m_charge : Float;
	private var m_spread : Float;

	protected event OnInitialize()
	{
		m_rootWidget = ( ( inkWidget )( GetRootWidget() ) );
		m_leftBracket = ( ( inkImage )( GetWidget( 'Details/left' ) ) );
		m_rightBracket = ( ( inkImage )( GetWidget( 'Details/right' ) ) );
		m_hori = ( ( inkWidget )( GetWidget( 'hori' ) ) );
		m_chargeBar = ( ( inkWidget )( GetWidget( 'fg' ) ) );
		m_centerPart = ( ( inkImage )( GetWidget( 'center' ) ) );
		m_chargeBoth = ( ( inkWidget )( GetWidget( 'chargeBars' ) ) );
		m_chargeLeftBar = ( ( inkRectangle )( GetWidget( 'chargeBars/leftBar/leftBarFG' ) ) );
		m_chargeRightBar = ( ( inkRectangle )( GetWidget( 'chargeBars/rightBar/rightBarFG' ) ) );
		m_fluffCanvas = ( ( inkWidget )( GetWidget( 'fluffCanvas' ) ) );
		m_leftBracket.SetMargin( inkMargin( -( ( ( Float )( m_horizontalMinSpread ) ) + ( m_gameplaySpreadMultiplier * m_bufferedSpread.X ) ), 0.0, 0.0, 0.0 ) );
		m_rightBracket.SetMargin( inkMargin( ( ( Float )( m_horizontalMinSpread ) ) + ( m_gameplaySpreadMultiplier * m_bufferedSpread.X ), 0.0, 0.0, 0.0 ) );
		m_hori.SetSize( ( ( ( ( Float )( m_horizontalMinSpread ) ) + ( m_gameplaySpreadMultiplier * m_bufferedSpread.X ) ) * 2.0 ) + 64.0, 1.0 );
		super.OnInitialize();
		m_charge = 0.0;
		m_spread = 0.0;
	}

	protected event OnUninitialize()
	{
		super.OnUninitialize();
	}

	protected event OnPreIntro()
	{
		var m_uiBlackboard : IBlackboard;
		m_weaponlocalBB = GetWeaponLocalBlackboard();
		if( m_weaponlocalBB )
		{
			m_bbcharge = m_weaponlocalBB.RegisterListenerFloat( GetAllBlackboardDefs().Weapon.Charge, this, 'OnChargeChanged' );
			m_bbcurrentFireMode = m_weaponlocalBB.RegisterListenerVariant( GetAllBlackboardDefs().Weapon.TriggerMode, this, 'OnTriggerModeChanged' );
			m_weaponlocalBB.SignalUint( GetAllBlackboardDefs().Weapon.MagazineAmmoCount );
		}
		m_uiBlackboard = GetBlackboardSystem().Get( GetAllBlackboardDefs().UI_NPCNextToTheCrosshair );
		if( m_uiBlackboard )
		{
			m_bbNPCStatsInfo = m_uiBlackboard.RegisterListenerVariant( GetAllBlackboardDefs().UI_NPCNextToTheCrosshair.NameplateData, this, 'OnNPCStatsChanged' );
		}
		OnChargeChanged( 0.0 );
		super.OnPreIntro();
	}

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

	protected function OnTriggerModeChanged( value : Variant )
	{
		var record : TriggerMode_Record;
		record = ( ( TriggerMode_Record )value );
		m_currentFireMode = record.Type();
		m_chargeBoth.SetVisible( m_currentFireMode == gamedataTriggerMode.Charge );
	}

	public export override function GetIntroAnimation( firstEquip : Bool ) : inkAnimProxy
	{
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		var crosshairReticleData : gameuiDriverCombatCrosshairReticleData;
		crosshairReticleData = ( ( gameuiDriverCombatCrosshairReticleData )( GetUIBlackboard().GetVariant( GetAllBlackboardDefs().UIGameData.DriverCombatCrosshairReticle ) ) );
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( 0.0 );
		alphaInterpolator.SetEndTransparency( crosshairReticleData.opacity );
		alphaInterpolator.SetDuration( 0.25 );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		OnShow();
		return m_rootWidget.PlayAnimation( anim );
	}

	public export override function GetOutroAnimation() : inkAnimProxy
	{
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		var crosshairReticleData : gameuiDriverCombatCrosshairReticleData;
		crosshairReticleData = ( ( gameuiDriverCombatCrosshairReticleData )( GetUIBlackboard().GetVariant( GetAllBlackboardDefs().UIGameData.DriverCombatCrosshairReticle ) ) );
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( crosshairReticleData.opacity );
		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 )
	{
		m_bufferedSpread = spread;
		UpdateSpread();
	}

	protected function OnChargeChanged( chargeValue : Float )
	{
		var actualMaxValue : Float;
		var playbackOptions : inkAnimOptions;
		var chargeOffset : Float;
		actualMaxValue = GetCurrentChargeLimit();
		chargeOffset = 0.92000002;
		m_chargeLeftBar.SetSize( Vector2( MinF( 108.0, ( chargeValue * 108.0 ) / chargeOffset ), 10.0 ) );
		m_chargeRightBar.SetSize( Vector2( MinF( 108.0, ( chargeValue * 108.0 ) / chargeOffset ), 10.0 ) );
		if( chargeValue >= actualMaxValue )
		{
			if( !( m_chargeAnimationProxy ) )
			{
				playbackOptions.loopInfinite = true;
				playbackOptions.loopType = inkanimLoopType.Cycle;
				m_chargeAnimationProxy = PlayLibraryAnimation( 'chargeMax', playbackOptions );
			}
		}
		else
		{
			if( m_chargeAnimationProxy )
			{
				m_chargeAnimationProxy.Stop();
				m_chargeAnimationProxy = NULL;
			}
		}
		m_charge = chargeValue / GetCurrentChargeLimit();
		UpdateChargeBar();
	}

	private function UpdateSpread()
	{
		m_leftBracket.SetMargin( inkMargin( -( ( ( Float )( m_horizontalMinSpread ) ) + ( m_gameplaySpreadMultiplier * m_bufferedSpread.X ) ), 0.0, 0.0, 0.0 ) );
		m_rightBracket.SetMargin( inkMargin( ( ( Float )( m_horizontalMinSpread ) ) + ( m_gameplaySpreadMultiplier * m_bufferedSpread.X ), 0.0, 0.0, 0.0 ) );
		m_hori.SetSize( ( ( ( ( Float )( m_horizontalMinSpread ) ) + ( m_gameplaySpreadMultiplier * m_bufferedSpread.X ) ) * 2.0 ) + 64.0, 3.0 );
		UpdateChargeBar();
	}

	private function UpdateChargeBar()
	{
		var baseSize : Vector2;
		baseSize = m_hori.GetSize();
		m_chargeBar.SetSize( baseSize.X * m_charge, baseSize.Y );
	}

	protected function CollapseCrosshair( duration : Float )
	{
		var anim : inkAnimDef;
		var marginInterpolator : inkAnimMargin;
		var sizeInterpolator : inkAnimSize;
		var alphaInterpolator : inkAnimTransparency;
		if( m_chargeAnimationProxy )
		{
			m_chargeAnimationProxy.Stop();
		}
		anim = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetStartMargin( m_leftBracket.GetMargin() );
		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 );
		m_leftBracket.PlayAnimation( anim );
		anim = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetStartMargin( m_rightBracket.GetMargin() );
		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 );
		m_rightBracket.PlayAnimation( anim );
		anim = new inkAnimDef;
		sizeInterpolator = new inkAnimSize;
		sizeInterpolator.SetStartSize( m_hori.GetSize() );
		sizeInterpolator.SetEndSize( Vector2( 0.0, 0.0 ) );
		sizeInterpolator.SetDuration( duration );
		sizeInterpolator.SetType( inkanimInterpolationType.Linear );
		sizeInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( sizeInterpolator );
		m_hori.PlayAnimation( anim );
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( 1.0 );
		alphaInterpolator.SetEndTransparency( 0.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		m_rootWidget.PlayAnimation( anim );
	}

	protected function ExpandCrosshair( duration : Float )
	{
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		if( m_chargeAnimationProxy )
		{
			m_chargeAnimationProxy.Stop();
		}
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( 0.0 );
		alphaInterpolator.SetEndTransparency( 1.0 );
		alphaInterpolator.SetDuration( duration );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		m_rootWidget.PlayAnimation( anim );
	}

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

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

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

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

	protected override function OnState_Safe()
	{
		CollapseCrosshair( 0.1 );
	}

	protected override function OnState_HipFire()
	{
		m_leftBracket.StopAllAnimations();
		m_rightBracket.StopAllAnimations();
		m_hori.StopAllAnimations();
		ExpandCrosshair( 0.1 );
		UpdateSpread();
	}

	protected override function OnState_Aim()
	{
		CollapseCrosshair( 0.1 );
		UpdateSpread();
	}

	protected override function OnState_Reload()
	{
		CollapseCrosshair( 0.25 );
	}

	protected override function OnState_Sprint()
	{
		CollapseCrosshair( 0.1 );
	}

	protected override function OnState_GrenadeCharging()
	{
		CollapseCrosshair( 0.1 );
	}

	protected override function OnState_Scanning()
	{
		CollapseCrosshair( 0.1 );
	}

	protected override function ApplyCrosshairGUIState( state : CName, aimedAtEntity : Entity )
	{
		m_rootWidget.SetState( state );
	}

}

