abstract class ChangeNPCState extends AIbehaviortaskScript
{
}

abstract class ChangeHighLevelStateAbstract extends AIbehaviortaskScript
{

	private export override function Activate( context : ScriptExecutionContext )
	{
		if( GetDesiredHighLevelState( context ) == gamedataNPCHighLevelState.Invalid )
		{
			return;
		}
		NPCPuppet.ChangeHighLevelState( ScriptExecutionContext.GetOwner( context ), GetDesiredHighLevelState( context ) );
		OnActivate( context );
	}

	private export override function Deactivate( context : ScriptExecutionContext )
	{
		OnDeactivate( context );
	}

	private virtual function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		return gamedataNPCHighLevelState.Relaxed;
	}

	private virtual function OnActivate( context : ScriptExecutionContext ) {}

	private virtual function OnDeactivate( context : ScriptExecutionContext ) {}
}

class RelaxedState extends ChangeHighLevelStateAbstract
{

	private override function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		return gamedataNPCHighLevelState.Relaxed;
	}

}

class AlertedState extends ChangeHighLevelStateAbstract
{

	private override function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		return gamedataNPCHighLevelState.Alerted;
	}

}

class CombatState extends ChangeHighLevelStateAbstract
{

	private override function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		return gamedataNPCHighLevelState.Combat;
	}

}

class StealthState extends ChangeHighLevelStateAbstract
{

	private override function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		return gamedataNPCHighLevelState.Stealth;
	}

}

class UnconsciousState extends ChangeHighLevelStateAbstract
{

	private override function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		return gamedataNPCHighLevelState.Unconscious;
	}

}

class DeadState extends ChangeHighLevelStateAbstract
{

	private override function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		return gamedataNPCHighLevelState.Dead;
	}

}

class HighLevelStateMapping extends ChangeHighLevelStateAbstract
{
	editable inlined var stateNameMapping : AIArgumentMapping;

	private override function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		if( stateNameMapping )
		{
			switch( ( ( CName )( ScriptExecutionContext.GetMappingValue( context, stateNameMapping ) ) ) )
			{
				case 'Relaxed':
					return gamedataNPCHighLevelState.Relaxed;
				case 'Alerted':
					return gamedataNPCHighLevelState.Alerted;
				case 'Combat':
					return gamedataNPCHighLevelState.Combat;
				case 'Unconscious':
					return gamedataNPCHighLevelState.Unconscious;
				case 'Dead':
					return gamedataNPCHighLevelState.Dead;
				default:
					break;
			}
		}
		return gamedataNPCHighLevelState.Invalid;
	}

}

abstract class StackChangeHighLevelStateAbstract extends AIbehaviortaskStackScript
{

	public export function OnActivate( context : ScriptExecutionContext )
	{
		var desiredState : gamedataNPCHighLevelState;
		desiredState = GetDesiredHighLevelState( context );
		if( desiredState == gamedataNPCHighLevelState.Invalid )
		{
			return;
		}
		NPCPuppet.ChangeHighLevelState( ScriptExecutionContext.GetOwner( context ), desiredState );
	}

	public virtual function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		return gamedataNPCHighLevelState.Relaxed;
	}

}

class StackRelaxedState extends StackChangeHighLevelStateAbstract
{

	public override function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		return gamedataNPCHighLevelState.Relaxed;
	}

}

class StackAlertedState extends StackChangeHighLevelStateAbstract
{

	public override function GetDesiredHighLevelState( context : ScriptExecutionContext ) : gamedataNPCHighLevelState
	{
		return gamedataNPCHighLevelState.Alerted;
	}

}

abstract class ChangeUpperBodyStateAbstract extends AIbehaviortaskScript
{

	private export override function Activate( context : ScriptExecutionContext )
	{
		NPCPuppet.ChangeUpperBodyState( ScriptExecutionContext.GetOwner( context ), GetDesiredUpperBodyState( context ) );
		OnActivate( context );
	}

	private export override function Deactivate( context : ScriptExecutionContext )
	{
		OnDeactivate( context );
	}

	private virtual function GetDesiredUpperBodyState( context : ScriptExecutionContext ) : gamedataNPCUpperBodyState
	{
		return gamedataNPCUpperBodyState.Normal;
	}

	private virtual function OnActivate( context : ScriptExecutionContext ) {}

	private virtual function OnDeactivate( context : ScriptExecutionContext ) {}
}

class ChangeUpperBodyState extends ChangeUpperBodyStateAbstract
{
	editable var m_newState : gamedataNPCUpperBodyState;

	private override function GetDesiredUpperBodyState( context : ScriptExecutionContext ) : gamedataNPCUpperBodyState
	{
		return m_newState;
	}

}

abstract class ChangeStanceStateAbstract extends AIbehaviortaskScript
{
	editable var changeStateOnDeactivate : Bool;
	default changeStateOnDeactivate = false;

	private export override function Activate( context : ScriptExecutionContext )
	{
		if( !( changeStateOnDeactivate ) )
		{
			NPCPuppet.ChangeStanceState( ScriptExecutionContext.GetOwner( context ), GetDesiredStanceState( context ) );
		}
		OnActivate( context );
	}

	private export override function Deactivate( context : ScriptExecutionContext )
	{
		if( changeStateOnDeactivate )
		{
			NPCPuppet.ChangeStanceState( ScriptExecutionContext.GetOwner( context ), GetDesiredStanceState( context ) );
		}
		OnDeactivate( context );
	}

	private virtual function GetDesiredStanceState( context : ScriptExecutionContext ) : gamedataNPCStanceState
	{
		return gamedataNPCStanceState.Stand;
	}

	private virtual function OnActivate( context : ScriptExecutionContext ) {}

	private virtual function OnDeactivate( context : ScriptExecutionContext ) {}
}

class ChangeStanceState extends ChangeStanceStateAbstract
{
	editable var m_newState : gamedataNPCStanceState;

	private override function GetDesiredStanceState( context : ScriptExecutionContext ) : gamedataNPCStanceState
	{
		return m_newState;
	}

}

class StandState extends ChangeStanceStateAbstract
{

	private override function GetDesiredStanceState( context : ScriptExecutionContext ) : gamedataNPCStanceState
	{
		return gamedataNPCStanceState.Stand;
	}

}

class VehicleState extends ChangeStanceStateAbstract
{

	private override function GetDesiredStanceState( context : ScriptExecutionContext ) : gamedataNPCStanceState
	{
		return gamedataNPCStanceState.Vehicle;
	}

}

class VehicleWindowState extends ChangeStanceStateAbstract
{

	private override function GetDesiredStanceState( context : ScriptExecutionContext ) : gamedataNPCStanceState
	{
		return gamedataNPCStanceState.VehicleWindow;
	}

}

