#using scripts\codescripts\struct;

#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\duplicaterender_mgr;
#using scripts\shared\filter_shared;
#using scripts\shared\visionset_mgr_shared;
#using scripts\shared\util_shared;

#using scripts\shared\abilities\_ability_player;
#using scripts\shared\abilities\_ability_power;
#using scripts\shared\abilities\_ability_util;

                                                                                
    	   	                                                                                                                                         	                                	                                                                                                                                                                                                                                                                                                                                                                    	        	     	              	    	   	               	                                              	                                                           	                               	                     	                                                                                                           	                                                                 	                                                              	                                                                                                                                             	                            	                                     	                                       	                                                                                                              	   	                  	       	                                                    	                   	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            	                                                                                                 	                                    	                                                                                        	           	                        	                                            	                                             	                                                   	                                                             	                                                         	                                                                    	                                                                                                                                                                                                                                	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  	    	         	                                                              	                                                          	                                   	                                   	                                                    	                                       	                                           	     	                                                                                                                                                                                                                                                      	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         	                                                               	        	                                                                                                                              	                                                                                                                     	                               	                                                      	                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         	   	                                                                                                                                                                                                                                  	                                                                                                                                                                                                                                                                                                                                                                                                                                                   
                                                             	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    	               	   	                                                        	  	                                                                                 	                                                                                                          	     	                               	                    	                                 	                                        	                            	                                                                  	                               	                                                                                         

#using scripts\shared\system_shared;

#namespace gadget_vision_pulse;

function autoexec __init__sytem__() {     system::register("gadget_vision_pulse",&__init__,undefined,undefined);    }

function __init__()
{
	if ( !SessionModeIsCampaignGame() )
	{
		callback::on_localplayer_spawned( &on_localplayer_spawned );
		
		duplicate_render::set_dr_filter_offscreen( "reveal_en", 50, "reveal_enemy", undefined, 2, "mc/hud_outline_model_z_red", 1  );
		duplicate_render::set_dr_filter_offscreen( "reveal_self", 50, "reveal_self", undefined, 2, "mc/hud_outline_model_z_red_alpha", 1  );
	}
	
	clientfield::register( "toplayer", "vision_pulse_active", 1, 1, "int", &vision_pulse_changed, !true, true );
	visionset_mgr::register_visionset_info( "vision_pulse", 1, 12, undefined, "vision_puls_bw" );
}

function on_localplayer_spawned( localClientNum )
{
	if( self == GetLocalPlayer( localClientNum ) )
	{
		self.vision_pulse_owner = undefined;
		filter::init_filter_vision_pulse( localClientNum );
	
		self gadgetpulseresetreveal();
		self set_reveal_self( localClientNum, false );
		self set_reveal_enemy( localClientNum, false );
		self thread watch_emped( localClientNum );
	}
}

function watch_emped( localClientNum )
{
	self endon( "entityshutdown" );
	
	while( 1 )
	{
		if( self IsEMPJammed() )
		{
			self thread disableShader( localClientNum, 0 );
			self notify ( "emp_jammed_vp" );
			break;
		}
		{wait(.016);};
	}
}

function disableShader( localClientNum, duration )
{
	self endon ("startVPShader" );
	self endon( "death" );
	self endon( "entityshutdown" );
	self notify( "disableVPShader" );
	self endon( "disableVPShader" );
	
	wait( duration );
	
	filter::disable_filter_vision_pulse( localClientNum, 3 );
}

function watch_world_pulse_end( localClientNum )
{
	self notify ( "watchworldpulseend" );
	self endon ( "watchworldpulseend" );
	self util::waittill_any( "entityshutdown", "death", "emp_jammed_vp" );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 0, getvisionpulsemaxradius( localClientNum ) + 1 ); 	// Weird thing needed by the shader
}

function do_vision_world_pulse( localClientNum )
{
	self endon( "entityshutdown" );
	self endon( "death" );
	
	self notify( "startVPShader" );
	
	self thread watch_world_pulse_end( localClientNum );
	
	filter::enable_filter_vision_pulse( localClientNum, 3 );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 1, 1.0 );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 2, 0.08 );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 3, 0.0 );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 4, 1.0 );
	
	startTime = GetServerTime( localClientNum );
	
	{wait(.016);};
	amount = 1.0;
	irisAmount = 0.0;
	pulsemaxradius = 0;
	while( ( GetServerTime( localClientNum ) - starttime ) < 2000 )
	{
		elapsedTime = ( GetServerTime( localClientNum ) - starttime ) * 1.0;
		if( elapsedTime < ( 2000 * 0.1 ) )
		{
			irisAmount = elapsedTime / ( 2000 * 0.1 );
		}
		else if( elapsedTime < ( 2000 * ( .5 + 0.1 ) ) )
		{
			irisAmount = 1.0 - elapsedTime / ( 2000 * .5 );
		}
		else
		{
			irisAmount = 0.0;
		}
		amount = 1.0 -  elapsedTime / 2000;
		pulseRadius = getvisionpulseradius( localClientNum );
		pulseMaxRadius = getvisionpulsemaxradius( localClientNum );
		filter::set_filter_vision_pulse_constant( localClientNum, 3, 0, pulseRadius );
		filter::set_filter_vision_pulse_constant( localClientNum, 3, 3, irisAmount );
		filter::set_filter_vision_pulse_constant( localClientNum, 3, 11, pulseMaxRadius );
		{wait(.016);};
	}
	
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 0, pulseMaxRadius + 1 ); 	// Weird thing needed by the shader
	
	self thread disableShader( localClientNum, 4000 / 1000 );	
}

function vision_pulse_owner_valid( owner )
{
	if( isDefined( owner ) && ( owner isPlayer() ) && isAlive( owner ) )
	{
		return true;
	}
	
	return false;
}

function watch_vision_pulse_owner_death( localClientNum )
{
	self endon( "entityshutdown" );
	self endon( "death" );
	self endon( "finished_local_pulse" );
	self notify ( "watch_vision_pulse_owner_death" );
	self endon ( "watch_vision_pulse_owner_death" );
	
	owner = self.vision_pulse_owner;
	if( vision_pulse_owner_valid( owner ) )
	{
		owner util::waittill_any( "entityshutdown", "death" );
	}
	
	self notify ( "vision_pulse_owner_death" );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 7, 0 );
	self thread disableShader( localClientNum, 4000 / 1000 );
	self.vision_pulse_owner = undefined;
}

function do_vision_local_pulse( localClientNum )
{
	self endon( "entityshutdown" );
	self endon( "death" );
	self endon ( "vision_pulse_owner_death" );
	
	self notify( "startVPShader" );
	
	self notify( "startLocalPulse" );
	self endon( "startLocalPulse" );
	
	self thread watch_vision_pulse_owner_death( localClientNum );
	
	origin = getrevealpulseorigin( localClientNum );
	//pulseMaxRadius = getrevealpulsemaxradius( localClientNum );
	filter::enable_filter_vision_pulse( localClientNum, 3 );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 5, 0.4 );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 6, 0.0001 );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 8, origin[0] );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 9, origin[1] );
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 7, 1 );
	
	startTime = GetServerTime( localClientNum );
	while( ( GetServerTime( localClientNum ) - starttime ) < 4000 )
	{
		if( (GetServerTime( localClientNum ) - starttime ) < 2000 )
		{
			pulseRadius = ( (GetServerTime( localClientNum ) - starttime ) / 2000) * 2000;
		}
		//pulseRadius = GetRevealPulseRadius( localClientNum );
		filter::set_filter_vision_pulse_constant( localClientNum, 3, 10, pulseRadius );
		
		{wait(.016);};
	}
	
	filter::set_filter_vision_pulse_constant( localClientNum, 3, 7, 0 );
	self thread disableShader( localClientNum, 4000 / 1000 );
	self notify ( "finished_local_pulse" );
	self.vision_pulse_owner = undefined;
}

function vision_pulse_changed( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
{		
	if ( newVal )
	{
		if( self == GetLocalPlayer( localClientNum ) )
		{
			if ( IsDemoPlaying() && (bnewent || oldval == newval ) )
			{
				return;
			}
			
			self thread do_vision_world_pulse( localClientNum );
		}
	}
}

function do_reveal_enemy_pulse( localClientNum )
{
	self endon( "entityshutdown" );
	self endon( "death" );
	
	self notify( "startEnemyPulse" );
	self endon( "startEnemyPulse" );
	startTime = GetServerTime( localClientNum );
	currTime = startTime;
		
	self MapShaderConstant( localclientnum, 0, "scriptVector7", 0.0, 0, 0, 0 );
	while( ( currTime - starttime ) < 4000 )
	{
		if( ( currTime - starttime ) > ( 4000 - 500 ) )
		{
			value = float( ( currTime - starttime - ( 4000 - 500 ) ) / 500 );
			self MapShaderConstant( localclientnum, 0, "scriptVector7", value, 0, 0, 0 );
		}

		{wait(.016);};
		currTime = GetServerTime( localClientNum );
	}
}

function set_reveal_enemy( localClientNum, on_off )
{
	if( on_off )
	{
		self thread do_reveal_enemy_pulse( localClientNum );
	}
	self duplicate_render::update_dr_flag( localClientNum, "reveal_enemy", on_off );
}

function set_reveal_self( localClientNum, on_off )
{
	if( on_off && ( self == GetLocalPlayer( localClientNum ) ) )
	{
		self thread do_vision_local_pulse( localClientNum );
	}
	else if( !on_off )
	{
		filter::set_filter_vision_pulse_constant( localClientNum, 3, 7, 0 );
	}
}

function gadget_visionpulse_reveal(localClientNum, bReveal)
{
	self notify( "gadget_visionpulse_changed" );
	
	player = GetLocalPlayer( localClientNum );
	//player motionpulse_enable( true );
	if( !isDefined( self.visionPulseRevealSelf ) && player == self )
	{
		self.visionPulseRevealSelf = false;
	}
	
	if( !isDefined( self.visionPulseReveal ) )
	{
		self.visionPulseReveal = false;
	}
	
	if(player == self)
	{
		owner = self gadgetpulsegetowner( localClientNum );
		if ( ( self.visionPulseRevealSelf != bReveal ) || ( isDefined( self.vision_pulse_owner ) && isDefined( owner ) && ( self.vision_pulse_owner != owner ) ) )
		{
			self.vision_pulse_owner = owner;
			self.visionPulseRevealSelf = bReveal;
			self set_reveal_self( localClientNum, bReveal );
		}
	}
	else
	{
		if ( self.visionPulseReveal != bReveal )
		{
			self.visionPulseReveal = bReveal;
			self set_reveal_enemy( localClientNum, bReveal );
		}
	}
}