abstract class LookAtPresetBaseDecisions extends DefaultTransition
{

	public const function HasItemEquipped( const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var desiredTypeStr : String;
		var desiredItemType : gamedataItemType;
		var equippedObject : ItemObject;
		var equippedItemType : gamedataItemType;
		desiredTypeStr = GetStaticStringParameterDefault( "itemType", "" );
		desiredItemType = ( ( gamedataItemType )( ( ( Int32 )( EnumValueFromString( "gamedataItemType", desiredTypeStr ) ) ) ) );
		if( GetStaticBoolParameterDefault( "leftHandItem", false ) )
		{
			equippedObject = scriptInterface.GetTransactionSystem().GetItemInSlot( scriptInterface.executionOwner, T"AttachmentSlots.WeaponLeft" );
		}
		else
		{
			equippedObject = scriptInterface.GetTransactionSystem().GetItemInSlot( scriptInterface.executionOwner, T"AttachmentSlots.WeaponRight" );
		}
		if( equippedObject == NULL )
		{
			return false;
		}
		equippedItemType = TDB.GetItemRecord( ItemID.GetTDBID( equippedObject.GetItemID() ) ).ItemType().Type();
		return desiredItemType == equippedItemType;
	}

	protected const virtual function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( HasItemEquipped( scriptInterface ) )
		{
			return true;
		}
		return false;
	}

	protected const virtual function ExitCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( !( HasItemEquipped( scriptInterface ) ) )
		{
			return true;
		}
		return false;
	}

}

abstract class LookAtPresetBaseEvents extends DefaultTransition
{
	var m_lookAtEvents : array< LookAtAddEvent >;
	var m_attachLeft : Bool;
	var m_attachRight : Bool;

	public static function GetLookatPartsRequests( lookatPresetRecord : weak< LookAtPreset_Record >, lookAtParts : ref< array< LookAtPartRequest > > )
	{
		var i : Int32;
		var partRecords : array< weak< LookAtPart_Record > >;
		var lookAtPartRequest : LookAtPartRequest;
		lookatPresetRecord.LookAtParts( partRecords );
		for( i = 0; i < partRecords.Size(); i += 1 )
		{
			lookAtPartRequest.partName = partRecords[ i ].PartName();
			lookAtPartRequest.weight = partRecords[ i ].Weight();
			lookAtPartRequest.suppress = partRecords[ i ].Suppress();
			lookAtPartRequest.mode = partRecords[ i ].Mode();
			lookAtParts.PushBack( lookAtPartRequest );
		}
	}

	public static function AddLookat( scriptInterface : StateGameScriptInterface, recordID : TweakDBID, priority : Int32, lookAtEventsArray : ref< array< LookAtAddEvent > >, out attachLeft : Bool, out attachRight : Bool )
	{
		var lookAtPartRequests : array< LookAtPartRequest >;
		var lookatPreset : weak< LookAtPreset_Record >;
		var lookAtEvent : LookAtAddEvent;
		var facingPosProvider : LookAtFacingPositionProvider;
		lookatPreset = TweakDBInterface.GetLookAtPresetRecord( recordID );
		if( !( lookatPreset ) )
		{
			return;
		}
		lookAtEvent = new LookAtAddEvent;
		facingPosProvider = new LookAtFacingPositionProvider;
		facingPosProvider.SetCameraComponent( scriptInterface.executionOwner );
		lookAtEvent.targetPositionProvider = facingPosProvider;
		lookAtEvent.bodyPart = lookatPreset.BodyPart();
		lookAtEvent.request.transitionSpeed = lookatPreset.TransitionSpeed();
		lookAtEvent.request.hasOutTransition = lookatPreset.HasOutTransition();
		lookAtEvent.request.outTransitionSpeed = lookatPreset.OutTransitionSpeed();
		lookAtEvent.request.limits.softLimitDegrees = lookatPreset.SoftLimitDegrees();
		lookAtEvent.request.limits.hardLimitDegrees = lookatPreset.HardLimitDegrees();
		lookAtEvent.request.limits.hardLimitDistance = lookatPreset.HardLimitDistance();
		lookAtEvent.request.limits.backLimitDegrees = lookatPreset.BackLimitDegrees();
		lookAtEvent.request.calculatePositionInParentSpace = lookatPreset.CalculatePositionInParentSpace();
		if( !( IsFinal() ) )
		{
			lookAtEvent.SetDebugInfo( "Gameplay " + TDBID.ToStringDEBUG( lookatPreset.GetID() ) );
		}
		lookAtEvent.request.suppress = lookatPreset.Suppress();
		lookAtEvent.request.mode = lookatPreset.Mode();
		lookAtEvent.request.priority = priority;
		GetLookatPartsRequests( lookatPreset, lookAtPartRequests );
		lookAtEvent.SetAdditionalPartsArray( lookAtPartRequests );
		scriptInterface.executionOwner.QueueEvent( lookAtEvent );
		lookAtEventsArray.PushBack( lookAtEvent );
		attachLeft = lookatPreset.AttachLeftHandtoRightHand();
		attachRight = lookatPreset.AttachRightHandtoLeftHand();
	}

	public function SetHandAttachAnimVars( scriptInterface : StateGameScriptInterface )
	{
		AnimationControllerComponent.SetInputFloatToReplicate( scriptInterface.executionOwner, 'pla_left_hand_attach', ( ( m_attachLeft ) ? ( 1.0 ) : ( 0.0 ) ) );
		AnimationControllerComponent.SetInputFloatToReplicate( scriptInterface.executionOwner, 'pla_right_hand_attach', ( ( m_attachRight ) ? ( 1.0 ) : ( 0.0 ) ) );
	}

	public function AddAllLookAtsInList( scriptInterface : StateGameScriptInterface, const presetNames : ref< array< String > >, priority : Int32, lookAtEventsArray : ref< array< LookAtAddEvent > > )
	{
		var attachLeftReturn : Bool;
		var attachRightReturn : Bool;
		var i : Int32;
		m_attachLeft = false;
		m_attachRight = false;
		for( i = 0; i < presetNames.Size(); i += 1 )
		{
			AddLookat( scriptInterface, TDBID.Create( "LookatPreset." + presetNames[ i ] ), priority, lookAtEventsArray, attachLeftReturn, attachRightReturn );
			m_attachLeft = m_attachLeft || attachLeftReturn;
			m_attachRight = m_attachRight || attachRightReturn;
		}
		SetHandAttachAnimVars( scriptInterface );
	}

	public static function RemoveAddedLookAts( scriptInterface : StateGameScriptInterface, lookAtEventsArray : ref< array< LookAtAddEvent > > )
	{
		var lookAtEvent : LookAtAddEvent;
		var i : Int32;
		for( i = 0; i < lookAtEventsArray.Size(); i += 1 )
		{
			lookAtEvent = lookAtEventsArray[ i ];
			if( !( lookAtEvent ) )
			{
				continue;
			}
			LookAtRemoveEvent.QueueRemoveLookatEvent( scriptInterface.executionOwner, lookAtEvent );
		}
		lookAtEventsArray.Clear();
	}

	public virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		AddAllLookAtsInList( scriptInterface, GetStaticStringArrayParameter( "lookAtPresetNames" ), 1, m_lookAtEvents );
	}

	public virtual function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveAddedLookAts( scriptInterface, m_lookAtEvents );
	}

	public virtual function OnForcedExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveAddedLookAts( scriptInterface, m_lookAtEvents );
	}

}

class lookAtPresetGunBaseDecisions extends LookAtPresetBaseDecisions
{
}

class lookAtPresetGunBaseEvents extends LookAtPresetBaseEvents
{
	var m_overrideLookAtEvents : array< LookAtAddEvent >;
	var m_gunState : Int32;
	var m_originalAttachLeft : Bool;
	var m_originalAttachRight : Bool;

	public static function IsReloading( const stateContext : StateContext ) : Bool
	{
		return stateContext.GetStateMachineCurrentState( 'Weapon' ) == 'reload';
	}

	public static function IsInSafeMode( const stateContext : StateContext ) : Bool
	{
		return stateContext.GetStateMachineCurrentState( 'Weapon' ) == 'publicSafe';
	}

	public function SetGunState( scriptInterface : StateGameScriptInterface, const newGunState : Int32 )
	{
		if( m_gunState != newGunState )
		{
			RemoveAddedLookAts( scriptInterface, m_overrideLookAtEvents );
			m_gunState = newGunState;
			if( m_gunState == 1 )
			{
				AddAllLookAtsInList( scriptInterface, GetStaticStringArrayParameter( "safeLookAtPresetNames" ), 0, m_overrideLookAtEvents );
			}
			else if( m_gunState == 2 )
			{
				AddAllLookAtsInList( scriptInterface, GetStaticStringArrayParameter( "reloadLookAtPresetNames" ), 0, m_overrideLookAtEvents );
			}
			else
			{
				m_attachLeft = m_originalAttachLeft;
				m_attachRight = m_originalAttachRight;
				SetHandAttachAnimVars( scriptInterface );
			}
		}
	}

	public override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		super.OnEnter( stateContext, scriptInterface );
		m_originalAttachLeft = m_attachLeft;
		m_originalAttachRight = m_attachRight;
		m_gunState = 0;
	}

	protected function OnUpdate( timeDelta : Float, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( IsReloading( stateContext ) )
		{
			SetGunState( scriptInterface, 2 );
		}
		else if( IsInSafeMode( stateContext ) )
		{
			SetGunState( scriptInterface, 1 );
		}
		else
		{
			SetGunState( scriptInterface, 0 );
		}
	}

	public override function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		SetGunState( scriptInterface, 0 );
		super.OnExit( stateContext, scriptInterface );
	}

	public override function OnForcedExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		SetGunState( scriptInterface, 0 );
		super.OnExit( stateContext, scriptInterface );
	}

}

class LookAtPresetMeleeBaseDecisions extends LookAtPresetBaseDecisions
{
}

class LookAtPresetMeleeBaseEvents extends LookAtPresetBaseEvents
{
}

class lookAtPresetItemBaseDecisions extends LookAtPresetBaseDecisions
{
}

class lookAtPresetItemBaseEvents extends LookAtPresetBaseEvents
{
}

class UnarmedLookAtDecisions extends LookAtPresetBaseDecisions
{

	protected const override function ExitCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( GetActiveWeapon( scriptInterface ) || GetActiveLeftHandItem( scriptInterface ) )
		{
			return true;
		}
		return false;
	}

}

class UnarmedLookAtEvents extends LookAtPresetBaseEvents
{
}

class AssualtRifleLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class AssualtRifleLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class FistsLookAtDecisions extends LookAtPresetMeleeBaseDecisions
{
}

class FistsLookAtEvents extends LookAtPresetMeleeBaseEvents
{
}

class HammerLookAtDecisions extends LookAtPresetMeleeBaseDecisions
{
}

class HammerLookAtEvents extends LookAtPresetMeleeBaseEvents
{
}

class HandgunLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class HandgunLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class HmgLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class HmgLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class KatanaLookAtDecisions extends LookAtPresetMeleeBaseDecisions
{
}

class KatanaLookAtEvents extends LookAtPresetMeleeBaseEvents
{
}

class KnifeLookAtDecisions extends LookAtPresetMeleeBaseDecisions
{
}

class KnifeLookAtEvents extends LookAtPresetMeleeBaseEvents
{
}

class LmgLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class LmgLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class LongBladeLookAtDecisions extends LookAtPresetMeleeBaseDecisions
{
}

class LongBladeLookAtEvents extends LookAtPresetMeleeBaseEvents
{
}

class MeleeLookAtDecisions extends LookAtPresetMeleeBaseDecisions
{
}

class MeleeLookAtEvents extends LookAtPresetMeleeBaseEvents
{
}

class OneHandedClubLookAtDecisions extends LookAtPresetMeleeBaseDecisions
{
}

class OneHandedClubLookAtEvents extends LookAtPresetMeleeBaseEvents
{
}

class PrecisionRifleLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class PrecisionRifleLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class RevolverLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class RevolverLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class RifleLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class RifleLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class ShortBladeLookAtDecisions extends LookAtPresetMeleeBaseDecisions
{
}

class ShortBladeLookAtEvents extends LookAtPresetMeleeBaseEvents
{
}

class ShotgunLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class ShotgunLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class ShotgunDualLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class ShotgunDualLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class SniperRifleLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class SniperRifleLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class SmgLookAtDecisions extends lookAtPresetGunBaseDecisions
{
}

class SmgLookAtEvents extends lookAtPresetGunBaseEvents
{
}

class TwoHandedClubLookAtDecisions extends LookAtPresetMeleeBaseDecisions
{
}

class TwoHandedClubLookAtEvents extends LookAtPresetMeleeBaseEvents
{
}

class GrenadeLookAtDecisions extends lookAtPresetItemBaseDecisions
{
}

class GrenadeLookAtEvents extends lookAtPresetItemBaseEvents
{
}

