class HighlightEffector extends ContinuousEffector
{
	protected var m_owner : weak< GameObject >;
	protected var m_maxDistance : Float;
	protected var m_effectDuraton : Float;
	protected var m_highlightVisible : Bool;
	protected var m_searchFilter : CName;
	protected var m_targetingSet : CName;

	protected export override function Initialize( record : TweakDBID, game : GameInstance, parentRecord : TweakDBID )
	{
		m_maxDistance = TDB.GetFloat( record + T".maxDistance" );
		m_effectDuraton = TDB.GetFloat( record + T".delayTime" ) + 0.1;
		m_highlightVisible = TDB.GetBool( record + T".highlightVisible" );
		m_searchFilter = TDB.GetCName( record + T".searchFilter" );
		m_targetingSet = TDB.GetCName( record + T".targetingSet", 'Frustum' );
	}

	protected override function ContinuousAction( owner : GameObject, instigator : GameObject )
	{
		m_owner = owner;
		ProcessEffector();
	}

	protected function ProcessEffector()
	{
		var searchQuery : TargetSearchQuery;
		switch( m_searchFilter )
		{
			case 'TechPreviewNPC':
				searchQuery.searchFilter = TSF_And( TSF_Not( TSFMV.Att_Friendly ), TSF_Any( TSFMV.Att_Hostile | TSFMV.Sp_Aggressive ), TSF_All( TSFMV.Obj_Puppet | TSFMV.St_AliveAndActive ) );
			break;
			case 'Device':
				searchQuery.searchFilter = TSF_And( TSF_All( TSFMV.Obj_Device ), TSF_All( TSFMV.St_AliveAndActive ), TSF_Any( TSFMV.Att_Hostile | TSFMV.Sp_Aggressive ) );
			break;
			case 'Sensor':
				searchQuery.searchFilter = TSF_Any( TSFMV.Obj_Sensor );
			break;
			case 'AccessPoint':
				searchQuery.searchFilter = TSF_Any( TSFMV.Obj_Device );
			break;
			default:
				searchQuery.searchFilter = TSF_EnemyNPC();
			break;
		}
		searchQuery.testedSet = ( ( TargetingSet )( ( ( Int32 )( EnumValueFromName( 'TargetingSet', m_targetingSet ) ) ) ) );
		searchQuery.includeSecondaryTargets = false;
		searchQuery.maxDistance = m_maxDistance;
		searchQuery.filterObjectByDistance = true;
		ProcessHighlight( searchQuery );
	}

	private virtual function ProcessHighlight( searchQuery : TargetSearchQuery )
	{
		RevealAllObjects( m_owner, searchQuery );
	}

	protected function RevealAllObjects( owner : GameObject, query : TargetSearchQuery )
	{
		var i, size : Int32;
		var target : GameObject;
		var targets : array< TS_TargetPartInfo >;
		var onlyAP : Bool;
		onlyAP = m_searchFilter == 'AccessPoint';
		GameInstance.GetTargetingSystem( owner.GetGame() ).GetTargetParts( owner, query, targets );
		size = targets.Size();
		for( i = 0; i < size; i += 1 )
		{
			target = ( ( GameObject )( TS_TargetPartInfo.GetComponent( targets[ i ] ).GetEntity() ) );
			if( target && ( m_highlightVisible || !( GameInstance.GetTargetingSystem( owner.GetGame() ).IsVisibleTarget( owner, target ) ) ) )
			{
				if( onlyAP && !( target.IsAccessPoint() ) )
				{
					continue;
				}
				RevealObject( owner, target, true, m_effectDuraton );
			}
		}
	}

	protected function RevealObject( owner : weak< GameObject >, object : weak< GameObject >, reveal : Bool, lifetime : Float )
	{
		var revealEvt : RevealObjectEvent;
		var puppet : ScriptedPuppet;
		if( !( object ) )
		{
			return;
		}
		puppet = ( ( ScriptedPuppet )( object ) );
		if( puppet )
		{
			if( ( puppet.IsBoss() || puppet.GetNPCType() == gamedataNPCType.Cerberus ) || puppet.GetNPCType() == gamedataNPCType.Chimera )
			{
				return;
			}
		}
		revealEvt = new RevealObjectEvent;
		revealEvt.reveal = reveal;
		revealEvt.reason.reason = 'highlightEffector';
		revealEvt.reason.sourceEntityId = owner.GetEntityID();
		revealEvt.lifetime = lifetime;
		object.QueueEvent( revealEvt );
	}

}

