
	-- ========================================================================================================
	-- 	Sets up the F-15 Eagle radar scripts, "compile_eri_radar()" is likely run by LuaExportStart().
	-- ========================================================================================================

-- Last time main eagle radar script was run
g_time_ran_Radar=0;

-- Running specific eagle radar routisnes, That is Targetstep, Stt->tws OR Ecm relock
g_runEagleFcns=false;		-- Disables normal eagle radar lua functions in favor of these below
g_doEagleStep=false;		-- Target step part 1
g_doEagleStep2=false;		-- Part 2 ( used if you have multiple targets bugged to cycle pdt between these )
g_doEagleStep3=false;		-- Last step of the multiple tws bugged targets algorithm
g_doEagleLRB=false;		-- Global set by LEAVU to activate LBST
g_toBugTWS=false;		-- global to activate stt->tws

-- variables for stt->tws switch and automatic ECM relock
g_bugTime=0;			-- Because we want to rebug tws after manual unlock STT after a specific time, this global is updated when unlocking stt
g_EagleLookForECM=false;	-- Same as the above, but when losing lock, start looking for ECM
g_EagleLookedForECMat=0;	-- Same as the above, but when losing lock, start looking for ECM

-- LBST/Long Range Bore Sight variables
g_runningLRB=false; 		-- If the LBST search mode is active?
g_lbstTarget=nil;			-- Test target to lock
g_LBSTdetectionTime=0;	-- Time of detection for this target (we dont want super uber fast LBST)

-- Memory of last modes
g_last_search_mode='RWS'; 	-- Default assumed last radar search submode
g_last_submode='RWS'; 	-- Default assumed last radar submode

-- Basic radar settings
g_last_scale=74080;	-- Default assumed radar VSD scale

-- Target step variables
g_targets_steppable={};  	-- Sorted RDR step memory
g_index_worldId=0; 	-- keeps memory of WorldID of last target that was stepped to
g_target_index=0; 	-- keeps memory of last index in the radar memory list that was stepped to

-- Target memory data
g_desiredTwsPdt=0;
g_oldPdtId=0;
g_oldLockedtargets=0;
g_lastbugged={};
g_oldPdtBurnthrough=true;
g_targetWasJamming=false;

-- Data for cursor follows bugged target in TWS
g_timeStoppedFollowingBuggedTarget = g_time;
g_cursorTargetID = nil;

g_lastCursorX = 0.0;
g_lastCursorY = 0.0;

-- Flanker radar az control
timeMoveCursor = 0;

if LuaExportBeforeNextFrame then
	local origBeforeNF = LuaExportBeforeNextFrame;
	function LuaExportBeforeNextFrame()
		origBeforeNF();
		eri_radar();
	end
else
	function LuaExportBeforeNextFrame()
		eri_radar();
	end
end

-- ================================
-- 	Main Radar Script
-- ================================

function eri_radar()

	if g_targets then
		for i,cur in pairs(g_targets) do
			update_steppable_target(cur);
		end
	end

	if g_MeObject and g_time-g_time_ran_Radar>0.03 then
		g_time_ran_Radar = g_time;
		
		if isF15() then			
	
			-- Check for used keyboard input
			look_for_keypress();
	
			-- These are special interrupt functions that require the main radar script's main loop to be paused
			if g_runEagleFcns then
				if g_toBugTWS then bugTws();
				elseif g_doEagleStep then doEagleStep1();
				elseif g_doEagleStep2 then doEagleStep2();
				elseif g_doEagleStep3 then doEagleStep3();
				elseif g_doEagleLRB then activate_LRB();
				else g_runEagleFcns=false end
	
			-- The following is the main radar scripts main loop
			else
				clean_steppable_targets();		-- Clean out Radar memory of old and/or out of gimbal targets (used by target step)
				cursor_on_target(); 	-- Keep radar cursor on our current target
				set_rdr_el_and_az(); 	-- Keeps radar antenna az/el angles on target(s) and/or cursor
				ECCM();			-- Run the ECCM scripts
	
				-- If to go from STT->TWS. And saves states of 'old*' variables and any modes (such as STT or pdtID)
				run_LBST();
				STT_lock_to_TWS_bug();
				save_modes_and_globals();
			end		

		end
	end

end


function isF15()
	if g_MeObject and g_MeObject.Type then
		if g_MeObject.Type.level1 == 1 and g_MeObject.Type.level2 == 1 and g_MeObject.Type.level3 == 1 and g_MeObject.Type.level4 == 6 then
			return true;
		end
	end
	return false;
end

-- =======================================================
-- 	Allow us to detect keypresses, so import that dll
-- =======================================================

kb_libs = package.loadlib("./bin/lua_keys.dll","init_libs") or package.loadlib("./bin/lua_keys_win7.dll","init_libs")
if kb_libs then kb_libs(); end -- Lib successfully initialized! allows access to kb_fcns
-- use http://msdn.microsoft.com/en-us/library/bb431750.aspx as reference for key codes

-- Our keyboard settings
keys = {};
keys["step"]=0x60;		-- num0
keys["lbst"]=0x61;		-- num1
keys["masterArm"]=0x62;	-- num2

-- Called each ERI radar cycle to check for keyboard input
clickedTstepAt = -300;
clickedTstep = false;
function look_for_keypress()

	if kb_fcns then

		if kb_fcns.has_been_pressed(keys["step"]) then
			if ( not clickedTstep ) then
				clickedTstepAt = g_time;
				clickedTstep = true;
			end
		end

		if kb_fcns.has_been_pressed(keys["lbst"]) then
			g_runEagleFcns=true;
			g_doEagleLRB=true;
		end

		if kb_fcns.has_been_pressed(keys["masterArm"]) then
			--LoSetCommand(283);
		end

		if ( clickedTstep and g_time-clickedTstepAt>0.5 ) then
			clickedTstep = false;
			g_runEagleFcns=true;
			g_doEagleStep=true;
		end

	end

end

-- Sorts the radar memory table
function steppable_targets_sort()
	for i=1,#g_targets_steppable do
		for e=i, #g_targets_steppable do
			if (g_targets_steppable[e][3]<g_targets_steppable[i][3]) then
				local temp=deepcopy(g_targets_steppable[i]);
				g_targets_steppable[i]=deepcopy(g_targets_steppable[e]);
				g_targets_steppable[e]=temp;
			end
		end
	end
end

-- Called by the target step routines
function snapToNextTarget()
	if #g_targets_steppable>g_target_index then

		local wid=g_targets_steppable[g_target_index+1][1];
		local wob=getObjectById(wid);

		if wob then
			g_target_index=g_target_index+1;
			g_index_worldId=wid;
			eagle_snapCursorTo(wob);
		else
			snapToFirstTarget();
		end
	else
		snapToFirstTarget();
	end
end

-- Called by the target step routines
function snapToFirstTarget()
	if #g_targets_steppable>0 then
		local wid=g_targets_steppable[1][1];
		local wob=getObjectById(wid);
		if wob then
			g_index_worldId=wid;
			g_target_index=1;
			eagle_snapCursorTo(wob);
		end
	end
end

--Sets the scale of the eagle radar
function setEagleRadarScale(desiredScale)

	if g_radarData.scale.distance~=desiredScale then

		-- Set scale 10 nm
		LoSetCommand(103);
		LoSetCommand(103);
		LoSetCommand(103);
		LoSetCommand(103);
		local setScale = 18520;

		while setScale<desiredScale do
			setScale = setScale*2;
			LoSetCommand(104);
		end

	end

end

-- Some scale conversions
function getEagleRadarScale(dist)

	if 		dist>126000	then 		return 296320;
	elseif 	dist>54000  	then  	return 148160;
	elseif 	dist>27000 	then  	return 74080;
	elseif 	dist>13500 	then  	return 37040;
	end

	return 18520;

end

-- Moves the F-15 cursor to a specified world object, also sets scale and takes ecm into account
function eagle_snapCursorTo(targetObject)

	-- Calculate the relative angle left-right for the cursor (off your nose) in degrees and set the cursor angle left-right
	local desiredX=get_relative_bearing(g_MeObject,targetObject)/60.0;
	if desiredX>3.0 then 
		desiredX = desiredX - 6.0;
	end
	if math.abs(g_radarData.TDC.x-desiredX)>0.001 then
		LoSetCommand(2103, desiredX);
	end	

	-- Should not move Y without burnthrough
	if not g_PdtBT then return end

	-- Calculate the distance from me to the target
	local dist=getDistance(g_MeObject, targetObject);
	
	-- Calculate otimal radar scale for the target
	local scaleDist=getEagleRadarScale(dist);

	-- Save the last scale setting
	g_last_scale=scaleDist;

	-- Set the radar scale
	setEagleRadarScale(scaleDist);
	
	-- Cap the distance at 2km no to get issues with auto cursor jumping
	if dist<2000 then 
		dist = 2000;
	end
	
	-- Set the cursor range
	local desiredY = -1+2*(scaleDist-dist)/scaleDist;
	if math.abs(desiredY-g_radarData.TDC.y)>0.001 then
		LoSetCommand(2104, -desiredY);
	end

end

-- checks if enumerated table 'list' includes entry 'id'
function ID_in_list(list,id)
	for i=1, #list do
		if list[i]==id then
			return true;
		end
	end
	return false;
end

function ID_in_list_at(list,id)
	for i=1, #list do
		if list[i]==id then
			return i;
		end
	end
	return -1;
end

-- First step after initiating a targets step
function doEagleStep1()

	-- Cancel any activate radar scripts
	g_lookforECM=false;
	g_doEagleStep=false;

	-- Sort the table of available targets, sort by range
	steppable_targets_sort();

	-- If we have previously snapped to a target, pick the next one in the list
	if g_index_worldId>0 and g_target_index>0 then
		g_target_index=0;

		-- Check if the previous target is still present on scope
		for i=1,#g_targets_steppable do
			if g_targets_steppable[i][1]==g_index_worldId then
				g_target_index=i;
				break;
			end
		end

		-- simulate error with target step
		local r = math.random();
		if ( r < 0.1 ) then
			g_target_index = g_target_index + 1;
		end

		-- if He isnt, snap to the first target on scope
		if g_target_index==0 then
			snapToFirstTarget();

		-- if he IS present, then snap to the next
		else
			snapToNextTarget();
		end

	-- If we havent snapped to any targets previously, just pick the first in the list
	else
		snapToFirstTarget();
	end

	-- Now, check if we have multiple TWS targets designated, and if we do, we should cycle the PDT among them
	if #g_targets_steppable>0 then		

		-- check if the target we just snapped to is actually designated by our radar, if it is, then determine if there are any other secondary bugged targets tws. If there are, we must proceed with g_doEagleStep2
		if ID_in_list(g_dTargets,g_index_worldId) and #g_dTargets>1 then
			g_doEagleStep2=true;
			g_desiredTwsPdt=g_index_worldId;
		end

		-- Snap to him (again?)
		local ob1=getObjectById(g_index_worldId); -- this is our target that we snapped to
		if ob1 then
			eagle_snapCursorTo(ob1);
		end

	end

end

--part of eagle target step
function doEagleStep2()

	g_doEagleStep2=false;

	-- Keep a list of what we had bugged
	g_lastbugged=deepcopy(g_dTargets);

	-- Unlock/unbug all except our new desired pdt
	for i=1, g_dTargetsCount do
		if g_desiredTwsPdt~=g_dTargets[i] then
			unlock_ID(g_dTargets[i]);
		end
	end

	-- Call for step 3 to relock/rebug the others
	g_doEagleStep3=true;

end

--part of eagle target step
function doEagleStep3()
	g_doEagleStep3=false;

	-- Now simply relock/rebug all that we unbugged in step2
	for i=1,#g_lastbugged do
		if g_desiredTwsPdt~=g_lastbugged[i] then
			lock_ID(g_lastbugged[i]);
		end
	end

	-- Don't forget to snap our cursor back to our pdt (as the above locking operation will move the cursor)
	local o=getObjectById(g_desiredTwsPdt);
	if o then
		eagle_snapCursorTo(o);
	end

end

-- enables moving from stt lock to tws bug state
function bugTws()
	if g_time-g_bugTime>0.05 then
		local oldTarget=getObjectById(g_oldPdtId);
		if oldTarget then
			eagle_snapCursorTo(oldTarget);
			LoSetCommand(100);
		end
		g_toBugTWS=false;
	end
end

-- unlocks a target ID
function unlock_ID(id)
	local obj=getObjectById(id);
	if obj then
		eagle_snapCursorTo(obj);
		LoSetCommand(143);
	end
end

-- locks a target ID
function lock_ID(id)
	local obj=getObjectById(id);
	if obj then
		eagle_snapCursorTo(obj);
		LoSetCommand(100);
	end
end

-- Activates Long range boresight algorithm
function activate_LRB()

	g_lbstTarget=nil;
	g_doEagleLRB=false;
	g_runningLRB=true;
	LoSetCommand(108);
	LoSetCommand(106);
	LoSetCommand(262);
	LoSetCommand(92);

end

-- Keeps the eagle radar antenna az angle pointed at the desired angle (called continously)
function move_eagle_azimuth_angle_direct(desired_angle)
	if g_radarData.ScanZone.size.azimuth<1.9*math.pi/3 then
		local current_angle = g_radarData.ScanZone.position.azimuth*180.0/math.pi;
		if math.abs(desired_angle-current_angle)>0.1 then
			LoSetCommand(2027,desired_angle/30.0)
		end
	end
end

function move_eagle_elevation_angle_direct(desired_angle)
	if math.abs(desired_angle-g_radarData.ScanZone.position.elevation*180.0/math.pi)>0.05 then
		LoSetCommand(2028, desired_angle/30);
	end	
end

-- prints text to a file log.txt in platinum folder
function logText(line)
	local file = io.open("./Temp/log.txt","a+")
	file:write(line);
	file:close();
end

-- Keeps Long Range Bore sight pointed in nose direction
function update_LRB_angles()

	if g_radarData.ScanZone.position.azimuth~=0 then
		LoSetCommand(2027,0);
	end	
	
	if g_radarData.TDC.x~=0 then
		LoSetCommand(2103, 0);
	end
	
	if g_radarData.TDC.y~=0 then
		LoSetCommand(2104, 0);
	end
	
	closestToBore=30;

	if g_lbstTarget then
		closestToBore=math.abs(get_relative_bearing(g_MeObject,g_lbstTarget));
	end

	if g_radarData.scale.distance~=74080 then
		setEagleRadarScale(74080);
	end

	local desiredAngle=(57.295779*g_acVectors.PITCH)-0.6;
	local oldDesiredAngle=(57.295779*g_radarData.ScanZone.position.elevation)-0.6;
	if math.abs(desiredAngle-oldDesiredAngle)>0.5 then
		if math.abs(desiredAngle)<30 then
			LoSetCommand(2028, -desiredAngle/30);
		end
	end

end

-- Zeros out the radar memory used by target step
function clean_steppable_targets()
	for i=#g_targets_steppable,1,-1 do	
		if g_time-g_targets_steppable[i][2]>7.0 then -- timeout / fade
			table.remove(g_targets_steppable,i);
		end
	end
end

-- Scans current targets on radar screen and sees if they are valid for an LRB lock!
function Scan_LRB(cur)

	-- Limit our boresight to +- 10 degrees in the azimuthal angle
	local LRB_limit=10;

	-- Make the test for the contact that our radar last scanned
	local curt=getObjectById(cur.ID);

	-- Make sure our target is alive and scanned in search mode
	if curt and (not lockNotSearch(cur.flags)) and cur.jammer_burned then

		-- Get his Az angle and distance in km
		local Az=math.abs(get_relative_bearing(g_MeObject,curt));
		local dist=cur.distance;

		-- Compare him with the last scanned target, to see which is closest to bore
		if g_lbsttarget then
			closestToBore=math.abs(get_relative_bearing(g_MeObject,g_lbsttarget));
			if closestToBore>LRB_limit then
				closestToBore=30;
				g_lbsttarget=nil;
			end
		end

		-- Update the timers (we want the LBST to have a specific delay in the lock) for locking
		if Az<LRB_limit and dist<74080 and Az<closestToBore then
			closestToBore=Az;
			g_lbsttarget=deepcopy(curt);
			if g_time-g_LBSTdetectionTime>2.3 then
				g_LBSTdetectionTime=g_time;
			end
		end

	end

end

-- Locks a target world object with radar.
function lock_targetObject(curt)
	eagle_snapCursorTo(curt);
	LoSetCommand(100);
	g_runningLRB=false;
end

-- gets the desired radar elevation angle in degrees(off horizon) for locking a target world object
function getDesiredElevation(targetObject)
	return 57.29578*math.asin((targetObject.LatLongAlt.Alt-g_MeObject.LatLongAlt.Alt)/getDistance(g_MeObject,targetObject));
end


-- Reads provided detected target from radar screen and puts into radar memory (used by target step)
function update_steppable_target(cur)

	-- Add new contacts that are (not jamming or we have BT)
	if cur.jammer_burned then
	
		-- Make sure the target data exists
		local target=getObjectById(cur.ID);

		if target then

			-- Give this detection a time stamp and get his range
			local index=0;
	
			-- Find out if the contact already is in memory (and we need to update him, not add him)
			for e=1, #g_targets_steppable do
				if cur.ID==g_targets_steppable[e][1] then
					index=e;
					break;
				end
			end		
			
			if index==0 then

				-- Only add if has been in mem for 3 sec
				if ( g_time - target.createdAt > 3 ) then
					g_targets_steppable[1+#g_targets_steppable]={cur.ID,g_time,getDistance(g_MeObject,target)};
				end

			-- If contacts exist, then update their data (if burnthrough or not jamming)
			else
				g_targets_steppable[index][2]=g_time;
				g_targets_steppable[index][3]=getDistance(g_MeObject,target);
			end
		
		end

	end

end


-- ================================================================
-- New section for cursor follows bugged target with TWS bug state!
-- ================================================================

-- moves the radar vsd TDC to a target object
function moveCursorTo(targetObject)

	if g_PdtBT then 

		local pos = getCursorXY(targetObject);

		g_lastCursorX = pos[1];
		g_lastCursorY =  -1+2*pos[2];

		LoSetCommand(2103, g_lastCursorX);
		LoSetCommand(2104, -g_lastCursorY);

	end

end

-- Gets the current TDC position range to the previously set one by "TWS TDC follows target"
function cursorRangeFromOldSet()

	return math.sqrt(  (g_lastCursorX-g_radarData.TDC.x)^2    +   (g_lastCursorY+g_radarData.TDC.y)^2  );
	
end

-- Gets the desired position of the cursor if we want to put it on top of a contact
function getCursorXY(targetObject)

	local diffAngle=get_relative_bearing(g_MeObject,targetObject);	
	if diffAngle>180.0 then 
		diffAngle = diffAngle - 360.0; 
	end	
	return { diffAngle/60.0, (g_radarData.scale.distance-getDistance(g_MeObject, targetObject))/g_radarData.scale.distance };

end

-- Gets the TDC's on screen distance to a target object
function getCursorRangeToObject(targetObject)

	local pos = getCursorXY(targetObject);
	return math.sqrt(  ( pos[1] - g_radarData.TDC.x)^2    +   (-1+2*pos[2] + g_radarData.TDC.y)^2  );
	
end

-- Separate script to snap cursor to tws target
function cursor_on_target()
	
	if g_acMode.SystemMode and g_acMode.SystemMode.submode=='STT' then	
		if g_dTargetsCount>0 then
			eagle_snapCursorTo(g_dTargetObjects[1]);
		end
	-- Cursor on target is only active when targets designated
	elseif g_cursorTargetID then
			
		local index = ID_in_list_at(g_dTargets,g_cursorTargetID);

		if index==-1 or cursorRangeFromOldSet()>0.01 then
			g_cursorTargetID = nil;
			g_timeStoppedFollowingBuggedTarget = g_time;
		else
			moveCursorTo(g_dTargetObjects[index]);
		end

	-- Look for new target to follow
	elseif g_dTargetsCount>0 and g_time-g_timeStoppedFollowingBuggedTarget>0.30 then

		local closest = 100000;
		g_cursorTargetID = nil;
	
		for i=1, g_dTargetsCount do
			local range = getCursorRangeToObject(g_dTargetObjects[i]);
			if range<0.08 and range<closest then
				g_cursorTargetID = g_dTargets[i];
				closest = range;
			end
		end
		
		local target = getObjectById(g_cursorTargetID);
		if target then
			moveCursorTo(target);
		end
		
	end
	
	
end

-- because master has bugs
function InNavMode()
	if g_acMode and g_acMode.SystemMode.submode~='ROUTE' and g_acMode.SystemMode.submode~='ARRIVAL' and g_acMode.SystemMode.submode~='LANDING' and g_acMode.SystemMode.submode~='OFF' then
		return false;
	end
	return true;
end

-- because master has bugs
function InCAC()

	if g_acMode and g_acMode.SystemMode.submode~='GUN' and g_acMode.SystemMode.submode~='VERTICAL_SCAN' and g_acMode.SystemMode.submode~='BORE' and g_acMode.SystemMode.submode~='HELMET' then
		return false;
        end

	return true;

end

function set_rdr_el_and_az()

	-- Dont do in CAC....
	if InCAC() then
		return;
	end

	local cursorAzAngle 		= 	60.0*g_radarData.TDC.x;

	-- Move the radar antenna azimuth to the cursor if no designated targets (FTW!!)
	if g_dTargetsCount==0 then
		move_eagle_azimuth_angle_direct(cursorAzAngle);

	-- Keep antenna on single target
	-- The purpose of this part is to make the az depend on both cursor and target angle
	elseif g_dTargetsCount==1 or (g_dTargetsCount>1 and g_acMode.SystemMode.submode=='STT') then

		local desiredRadarElevation=getDesiredElevation(g_dTargetObjects[1]);
		local oldRadarElevation = (180/math.pi)*g_radarData.ScanZone.position.elevation or 0;
		local elevation_error = desiredRadarElevation-oldRadarElevation;

		if math.abs(elevation_error)>2.0 then
			if math.abs(desiredRadarElevation)>31 and not InNavMode() and g_acMode.SystemMode.submode~='STT' then
				LoSetCommand(285);
			else
				if math.abs(elevation_error)>10 then
					LoSetCommand(2028, -desiredRadarElevation/30);
				else
					LoSetCommand(2028, -(oldRadarElevation + elevation_error - sign(elevation_error)*2.0)/30);
				end
			end
		end

		local desiredAzAngle	=	get_relative_bearing(g_MeObject,g_dTargetObjects[1]);

		if math.abs(desiredAzAngle-cursorAzAngle)<15 then
			move_eagle_azimuth_angle_direct(cursorAzAngle);
		else
			move_eagle_azimuth_angle_direct(desiredAzAngle+15*sign(cursorAzAngle-desiredAzAngle));
		end


	-- Optimize antenna for multiple targets
	else

		-- Store the accepted angles here
		local azimuth_angles = {};
		local elevation_angles = {};

		-- Now check target by target if they dont break the max/min-relations of elevation of azimuth
		for i = 1, g_dTargetsCount do
			local desiredAzAngle = get_relative_bearing(g_MeObject,g_dTargetObjects[i]);
			local desiredElevation = getDesiredElevation(g_dTargetObjects[i]);
			if azimuthCompatible(azimuth_angles, desiredAzAngle) and elevationCompatible(elevation_angles, desiredElevation) then
				--Build table of valid targets
				azimuth_angles[#azimuth_angles+1] = desiredAzAngle;
				elevation_angles[#elevation_angles+1] = desiredElevation;
			end
		end

		if #azimuth_angles>0 then
			move_eagle_azimuth_angle_direct((tablemax(azimuth_angles)+tablemin(azimuth_angles))/2);
			move_eagle_elevation_angle_direct(-(tablemax(elevation_angles)+tablemin(elevation_angles))/2);
		end

	end

	-- Now keep cursor inside scan zone (final thing) if 3A az
	if g_radarData.ScanZone.size.azimuth<math.pi/2 then
		local scanAngle = g_radarData.ScanZone.position.azimuth*180.0/math.pi;
		if math.abs(cursorAzAngle-scanAngle)>30 then
			LoSetCommand(2103, (scanAngle + 30*sign(cursorAzAngle-scanAngle))/60.0);
		end
	end
end

function tablemax(angles)
	local toReturn = nil;
	for i = 1,#angles do
		if (not toReturn) or (toReturn<angles[i]) then
			toReturn = angles[i];
		end
	end
	return toReturn or 0;
end

function tablemin(angles)
	local toReturn = nil;
	for i = 1, #angles do
		if (not toReturn) or (toReturn>angles[i]) then
			toReturn = angles[i];
		end
	end
	return toReturn or 0;
end

function azimuthCompatible(azimuth_angles, desiredAzAngle)
	for i = 1, #azimuth_angles do
		if math.abs(desiredAzAngle-azimuth_angles[i])>45 then
			return false;
		end
	end
	return true;
end

function elevationCompatible(elevation_angles, desiredElevation)
	for i= 1,#elevation_angles do
		if math.abs(desiredElevation-elevation_angles[i])>8.0 then
			return false;
		end
	end
	return true;
end

function ECCM()

	-- We just came to BT so stabilize cursor
	if g_dTargetsCount>0 and g_PdtBT and (not g_oldPdtBurnthrough) then
		eagle_snapCursorTo(g_dTargetObjects[1]);
	end
	
	scan_and_relock_ECM();	-- Handles the ECM relock and STT->tws after target turns off ECM
end

-- If LRB is activated, this function scans current targets and designates if needed
function run_LBST()

	if g_targets and g_runningLRB then

		if g_dTargetsCount==0 then

			-- Keeps radar aligned with pitch
			update_LRB_angles();

			-- Look for new LRB targets
			for i,cur in pairs(g_targets) do
				Scan_LRB(cur);
			end

			-- Designate target through LBST
			if g_runningLRB and g_lbsttarget and g_time-g_LBSTdetectionTime>1.25 then
				lock_targetObject(g_lbsttarget);
				g_lbsttarget=nil;
			end

		else
			g_runningLRB=false;
		end
	end
end

-- This determines if and how we should auatomatically relock ECM
function scan_and_relock_ECM()

	-- Search functions to run if 0 g_dTargets
	if g_EagleLookForECM then
		if g_targets and g_dTargetsCount==0 then

			-- Look for LRB targets and/or ECM contacts to relock
			for i,cur in pairs(g_targets) do
				if g_EagleLookForECM then
					-- Look no more than 5 seconds
					if g_time-g_EagleLookedForECMat>5 then
						g_EagleLookForECM=false;

					-- ok if we found the correct jammer, attack!
					elseif cur.isjamming>0 and g_oldPdtId==cur.ID then
						local targetObject=getObjectById(g_oldPdtId)
						if targetObject then
							if not cur.jammer_burned then
								eagle_snapCursorTo(targetObject);
								LoSetCommand(100);
							end
						end
						g_EagleLookForECM=false;
					end
				end
			end
		-- if we already have a target we should not be looking for an ecm contact
		else
			g_EagleLookForECM=false;
		end

	-- activate to look for ECM to relock
	elseif g_dTargetsCount==0 and g_oldLockedtargets==1 and g_targetWasJamming==false then
		g_runEagleFcns=true;
		g_EagleLookForECM=true;
		g_EagleLookedForECMat=g_time;
	end

	-- If he turns off ECM, we should go to tws! not stt !
	if  (not g_oldPdtBurnthrough) and (not g_PdtIsJamming) and g_acMode.SystemMode.submode=='STT' and g_last_search_mode=='TWS' then
		LoSetCommand(143);
	end

end

-- Do we need to step from STT->TWS bug?
function STT_lock_to_TWS_bug()
	if g_oldPdtBurnthrough and g_last_submode=='STT' and g_acMode.SystemMode.submode=='TWS' and g_last_search_mode=='TWS' then
		local oldTarget=getObjectById(g_oldPdtId)
		if oldTarget then
			g_timeStoppedFollowingBuggedTarget = 0;
			eagle_snapCursorTo(oldTarget);
			g_runEagleFcns=true;
			g_toBugTWS=true;
			g_bugTime=g_time;
		end
	end
end

-- Saves the current->old state of our selected modes
function save_modes_and_globals()

	if g_dTargetsCount==0 then

		-- Update modes
		if g_acMode.SystemMode.submode=='TWS' then
			g_runningLRB=false;
			g_last_search_mode='TWS';
		elseif g_acMode.SystemMode.submode~='STT' then
			g_last_search_mode='RWS';
			if g_acMode.SystemMode.master=='BVR' then
				if g_acMode.SystemMode.submode~='RWS' then
					g_runningLRB=false;
				end
			else
				g_runningLRB=false;
			end
		else
			g_runningLRB=false;
		end

	end

	-- Save states
	g_oldPdtId			=	g_dTargets[1] or g_oldPdtId;
	g_oldLockedtargets	=	g_dTargetsCount;
	g_oldPdtBurnthrough	=	g_PdtBT;
	g_targetWasJamming	=	g_PdtIsJamming;
	g_last_submode		=	g_acMode.SystemMode.submode;

end

