class CrosshairGameController_Melee extends gameuiCrosshairBaseMelee
{
	private editable var m_targetColorChange : inkWidgetRef;
	private var m_chargeBar : weak< inkCanvas >;
	private var m_chargeBarFG : weak< inkRectangle >;
	private var m_chargeBarMonoTop : weak< inkImage >;
	private var m_chargeBarMonoBottom : weak< inkImage >;
	private var m_chargeBarMask : weak< inkMask >;
	private editable var m_chargeValueL : weak< inkText >;
	private editable var m_chargeValueR : weak< inkText >;
	private var m_bbcharge : Uint32;
	private var m_meleeResourcePoolListener : MeleeResourcePoolListener;
	private var m_weaponID : EntityID;
	private var m_displayChargeBar : Bool;
	private var m_currentState : Int32;
	private var m_meleeLeapAttackObjectTagger : MeleeLeapAttackObjectTagger;

	protected event OnInitialize()
	{
		super.OnInitialize();
		m_chargeBar = ( ( inkCanvas )( GetWidget( 'chargeBar' ) ) );
		m_chargeBarMask = ( ( inkMask )( GetWidget( 'chargeBar/overheat_mask' ) ) );
		m_chargeBarFG = ( ( inkRectangle )( GetWidget( 'chargeBar/chargeBarFG' ) ) );
		m_chargeBarMonoTop = ( ( inkImage )( GetWidget( '5_hairlines/hair_top' ) ) );
		m_chargeBarMonoBottom = ( ( inkImage )( GetWidget( '5_hairlines/hair_bottom' ) ) );
		m_chargeValueL = ( ( inkText )( GetWidget( 'chargeBar/fluffL' ) ) );
		m_chargeValueR = ( ( inkText )( GetWidget( 'chargeBar/fluffR' ) ) );
	}

	protected event OnPlayerAttach( playerPuppet : GameObject )
	{
		super.OnPlayerAttach( playerPuppet );
		m_meleeLeapAttackObjectTagger = new MeleeLeapAttackObjectTagger;
		m_meleeLeapAttackObjectTagger.SetUp( playerPuppet );
	}

	protected event OnPreIntro()
	{
		var statPoolsSystem : StatPoolsSystem;
		var playerObject : GameObject;
		var chargePct : Float;
		var weaponObject : ItemObject;
		chargePct = 0.0;
		weaponObject = GetWeaponItemObject();
		m_displayChargeBar = false;
		playerObject = ( ( GameObject )( GetOwnerEntity() ) );
		statPoolsSystem = GameInstance.GetStatPoolsSystem( playerObject.GetGame() );
		if( weaponObject && statPoolsSystem )
		{
			m_weaponID = weaponObject.GetEntityID();
			if( statPoolsSystem.IsStatPoolAdded( m_weaponID, gamedataStatPoolType.WeaponCharge ) )
			{
				m_displayChargeBar = true;
				m_meleeResourcePoolListener = new MeleeResourcePoolListener;
				m_meleeResourcePoolListener.Bind( this );
				statPoolsSystem.RequestRegisteringListener( m_weaponID, gamedataStatPoolType.WeaponCharge, m_meleeResourcePoolListener );
				chargePct = statPoolsSystem.GetStatPoolValue( m_weaponID, gamedataStatPoolType.WeaponCharge );
				SetChargeScale( chargePct );
			}
		}
		m_chargeBar.SetVisible( m_displayChargeBar );
		super.OnPreIntro();
	}

	protected event OnPreOutro()
	{
		if( m_meleeResourcePoolListener )
		{
			GameInstance.GetStatPoolsSystem( GetPlayerControlledObject().GetGame() ).RequestUnregisteringListener( m_weaponID, gamedataStatPoolType.WeaponCharge, m_meleeResourcePoolListener );
			m_meleeResourcePoolListener = NULL;
		}
		super.OnPreOutro();
	}

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

	public function UpdateTargetIndicator()
	{
		if( ( m_meleeLeapAttackObjectTagger && m_targetEntity ) && ( m_currentState == ( ( Int32 )( gamePSMMeleeWeapon.ChargedHold ) ) ) )
		{
			m_meleeLeapAttackObjectTagger.SetVisionOnTargetObj( m_targetEntity, GetDistanceToTarget() );
		}
	}

	protected event OnGamePSMMeleeWeapon( state : Int32 )
	{
		var weaponObject : ItemObject;
		weaponObject = GetWeaponItemObject();
		super.OnGamePSMMeleeWeapon( state );
		UpdateCrosshairGUIState( false );
		if( m_meleeLeapAttackObjectTagger && ( WeaponObject.IsOfType( weaponObject.GetItemID(), gamedataItemType.Wea_Katana ) || WeaponObject.IsOfType( weaponObject.GetItemID(), gamedataItemType.Wea_Sword ) ) )
		{
			m_currentState = state;
			if( m_currentState == ( ( Int32 )( gamePSMMeleeWeapon.ChargedHold ) ) )
			{
				m_meleeLeapAttackObjectTagger.SetVisionOnTargetObj( m_targetEntity, GetDistanceToTarget() );
			}
			else
			{
				m_meleeLeapAttackObjectTagger.ResetVisionOnTargetObj();
			}
		}
	}

	public function UpdateResourceValue( oldValue : Float, newValue : Float, percToPoints : Float )
	{
		SetChargeScale( newValue );
	}

	public virtual function SetChargeScale( pct : Float )
	{
		var scale : Vector2;
		var scaleFG : Vector2;
		var scaleLerp : Float;
		scaleLerp = pct / 100.0;
		scaleLerp = 1.0 - PowF( 1.0 - scaleLerp, 0.66000003 );
		scale = Vector2( 1.0, scaleLerp );
		scaleFG = Vector2( scaleLerp, 1.0 );
		m_chargeBarMask.SetScale( scale );
		m_chargeBarFG.SetScale( scaleFG );
		m_chargeBarMonoTop.SetScale( scale );
		m_chargeBarMonoBottom.SetScale( scale );
		m_chargeValueL.SetText( ( ( String )( RoundF( pct ) ) ) + "%" );
		m_chargeValueR.SetText( ( ( String )( RoundF( pct ) ) ) + "%" );
	}

	protected event OnUninitialize()
	{
		if( m_meleeResourcePoolListener && GetPlayerControlledObject() )
		{
			GameInstance.GetStatPoolsSystem( GetPlayerControlledObject().GetGame() ).RequestUnregisteringListener( m_weaponID, gamedataStatPoolType.WeaponCharge, m_meleeResourcePoolListener );
			m_meleeResourcePoolListener = NULL;
		}
	}

	public export 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 );
		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 function ShowCrosshairFromState( show : Bool )
	{
		m_chargeBar.SetVisible( show && m_displayChargeBar );
		GetRootWidget().SetOpacity( ( ( show ) ? ( 1.0 ) : ( 0.0 ) ) );
	}

	protected override function OnState_Safe()
	{
		ShowCrosshairFromState( true );
	}

	protected override function OnState_Scanning()
	{
		ShowCrosshairFromState( false );
	}

	protected override function OnState_GrenadeCharging()
	{
		ShowCrosshairFromState( false );
	}

	protected override function OnState_HipFire()
	{
		ShowCrosshairFromState( true );
	}

	protected override function OnState_Reload()
	{
		ShowCrosshairFromState( true );
	}

	protected override function OnState_Aim()
	{
		ShowCrosshairFromState( true );
	}

	protected override function OnState_Sprint()
	{
		ShowCrosshairFromState( true );
	}

	protected override function OnState_LeftHandCyberware()
	{
		ShowCrosshairFromState( false );
	}

}

class MeleeResourcePoolListener extends ScriptStatPoolsListener
{
	private var m_meleeCrosshair : weak< CrosshairGameController_Melee >;

	public function Bind( crosshair : weak< CrosshairGameController_Melee > )
	{
		m_meleeCrosshair = crosshair;
	}

	public export override function OnStatPoolValueChanged( oldValue : Float, newValue : Float, percToPoints : Float )
	{
		m_meleeCrosshair.UpdateResourceValue( oldValue, newValue, percToPoints );
	}

}

