class Crosshair_Custom_HMG extends gameuiCrosshairBaseGameController
{
	private editable var m_leftPart : inkWidgetRef;
	private editable var m_rightPart : inkWidgetRef;
	private editable var m_topPart : inkWidgetRef;
	private editable var m_bottomPart : inkWidgetRef;
	private editable var m_horiPart : inkWidgetRef;
	private editable var m_vertPart : inkWidgetRef;
	private editable var m_overheatContainer : inkWidgetRef;
	private editable var m_overheatWarning : inkWidgetRef;
	private editable var m_overheatMask : inkWidgetRef;
	private editable var m_overheatValueL : inkTextRef;
	private editable var m_overheatValueR : inkTextRef;
	private editable var m_leftPartExtra : inkImageRef;
	private editable var m_rightPartExtra : inkImageRef;
	private editable var m_crosshairContainer : inkCanvasRef;
	private var offsetLeftRight : Float;
	default offsetLeftRight = .8;
	private var offsetLeftRightExtra : Float;
	default offsetLeftRightExtra = 1.2;
	private var latchVertical : Float;
	default latchVertical = 40.0;
	private var m_weaponLocalBB : weak< IBlackboard >;
	private var m_overheatBBID : CallbackHandle;
	private var m_forcedOverheatBBID : CallbackHandle;
	private editable var m_targetColorChange : inkWidgetRef;
	private var m_forcedCooldownProxy : inkAnimProxy;
	private var m_forcedCooldownOptions : inkAnimOptions;

	protected event OnInitialize()
	{
		super.OnInitialize();
		inkWidgetRef.SetVisible( m_overheatContainer, false );
		inkCanvasRef.SetVisible( m_crosshairContainer, true );
		m_forcedCooldownOptions.loopType = inkanimLoopType.Cycle;
		m_forcedCooldownOptions.loopInfinite = true;
	}

	protected event OnPreIntro()
	{
		var overheatPercentage : Float;
		var overheatValue : String;
		var isOverheating : Bool;
		m_weaponLocalBB = GetWeaponLocalBlackboard();
		if( m_weaponLocalBB )
		{
			m_overheatBBID = m_weaponLocalBB.RegisterDelayedListenerFloat( GetAllBlackboardDefs().Weapon.OverheatPercentage, this, 'OnOverheatChanged' );
			overheatPercentage = m_weaponLocalBB.GetFloat( GetAllBlackboardDefs().Weapon.OverheatPercentage );
			overheatValue = ( ( String )( RoundF( overheatPercentage ) ) ) + "%";
			inkTextRef.SetText( m_overheatValueL, overheatValue );
			inkTextRef.SetText( m_overheatValueR, overheatValue );
			m_forcedOverheatBBID = m_weaponLocalBB.RegisterDelayedListenerBool( GetAllBlackboardDefs().Weapon.IsInForcedOverheatCooldown, this, 'OnIsInForcedOverheatCooldown' );
			isOverheating = m_weaponLocalBB.GetBool( GetAllBlackboardDefs().Weapon.IsInForcedOverheatCooldown );
			inkWidgetRef.SetVisible( m_overheatWarning, isOverheating );
			inkCanvasRef.SetVisible( m_crosshairContainer, !( isOverheating ) );
			if( isOverheating )
			{
				m_forcedCooldownProxy = PlayLibraryAnimation( 'OverheatAnimation', m_forcedCooldownOptions );
			}
		}
		super.OnPreIntro();
	}

	protected event OnPreOutro()
	{
		if( m_weaponLocalBB )
		{
			m_weaponLocalBB.UnregisterDelayedListener( GetAllBlackboardDefs().Weapon.OverheatPercentage, m_overheatBBID );
			m_weaponLocalBB.UnregisterDelayedListener( GetAllBlackboardDefs().Weapon.IsInForcedOverheatCooldown, m_forcedOverheatBBID );
		}
		if( m_forcedCooldownProxy.IsPlaying() )
		{
			m_forcedCooldownProxy.Stop();
		}
		super.OnPreOutro();
	}

	public export override function GetIntroAnimation( firstEquip : Bool ) : inkAnimProxy
	{
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		PlayLibraryAnimation( 'PickUpWeapon' );
		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 );
		return m_rootWidget.PlayAnimation( anim );
	}

	public export 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 );
		return m_rootWidget.PlayAnimation( anim );
	}

	protected event OnBulletSpreadChanged( spread : Vector2 )
	{
		super.OnBulletSpreadChanged( spread );
		inkWidgetRef.SetMargin( m_leftPart, inkMargin( -( spread.X ) * offsetLeftRight, 0.0, 0.0, 0.0 ) );
		inkWidgetRef.SetMargin( m_rightPart, inkMargin( spread.X * offsetLeftRight, 0.0, 0.0, 0.0 ) );
		inkImageRef.SetMargin( m_leftPartExtra, inkMargin( -( spread.X ) / 2.0, 0.0, 0.0, 0.0 ) );
		inkImageRef.SetMargin( m_rightPartExtra, inkMargin( spread.X / 2.0, 0.0, 0.0, 0.0 ) );
		inkWidgetRef.SetSize( m_vertPart, 3.0, ( spread.Y * 2.0 ) + latchVertical );
		inkWidgetRef.SetSize( m_horiPart, spread.X, 3.0 );
		inkWidgetRef.SetMargin( m_topPart, inkMargin( 0.0, -( spread.Y ), 0.0, 0.0 ) );
		inkWidgetRef.SetMargin( m_bottomPart, inkMargin( 0.0, spread.Y, 0.0, 0.0 ) );
	}

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

	protected event OnOverheatChanged( argValue : Float )
	{
		argValue = argValue / 100.0;
		inkTextRef.SetText( m_overheatValueL, ( ( String )( RoundF( 100.0 * argValue ) ) ) + "%" );
		inkTextRef.SetText( m_overheatValueR, ( ( String )( RoundF( 100.0 * argValue ) ) ) + "%" );
		inkWidgetRef.SetVisible( m_overheatContainer, argValue > 0.01 );
		inkWidgetRef.SetScale( m_overheatMask, Vector2( 1.0, argValue ) );
	}

	protected event OnIsInForcedOverheatCooldown( argValue : Bool )
	{
		if( argValue && !( m_forcedCooldownProxy.IsPlaying() ) )
		{
			m_forcedCooldownProxy = PlayLibraryAnimation( 'OverheatAnimation', m_forcedCooldownOptions );
			inkWidgetRef.SetVisible( m_overheatWarning, true );
			inkCanvasRef.SetVisible( m_crosshairContainer, false );
		}
		else
		{
			m_forcedCooldownProxy.Stop();
			inkWidgetRef.SetVisible( m_overheatWarning, false );
			inkCanvasRef.SetVisible( m_crosshairContainer, true );
		}
	}

}

