--start core functions --
local function insidePolygon(polygon, point)
    local oddNodes = false
    local j = #polygon
    for i = 1, #polygon do
       if (polygon[i].y < point.y and polygon[j].y >= point.y or polygon[j].y < point.y and polygon[i].y >= point.y) then
            if (polygon[i].x + ( point.y - polygon[i].y ) / (polygon[j].y - polygon[i].y) * (polygon[j].x - polygon[i].x) < point.x) then
                oddNodes = not oddNodes;
            end
        end
        j = i;
    end
    return oddNodes 
end

--pass in table, get back count. 0 indicates both nil & 0entries
local function getTableCount(tbl)
    local c = 0;
    if tbl == nil then return 0; end
    for k,v in pairs(tbl) do
      c=c+1;
    end
    return c;
end

local function gKHprint(dbglevel,funcname,text)
    if (dbglevel == nil) then dbglevel = 0; end
    if (gKH_DebugLevel ==nil) then return; end

    if (gKH_DebugLevel >= dbglevel) then
        if(text == nil) then text = 'called.'; end
        if(funcname == nil) then
            print(text);
        else
            if (type(text) ~= 'table') and (type(text) ~='userdata') then
                print(funcname .. '(): ' .. text); 
            else
                print(funcname .. '(): [table] ');
                print(text);
            end
        end
    end
end

--feed it table of latitude=\longitude= and get back Y= X= ;for use with inPolygon();
local function fnConvertLatLonToYXtable(lltable)
    if (lltable ~=nil and getTableCount(lltable) > 0) then
        local retval = {}
        local tcount = getTableCount(lltable);
        for i=1, tcount do
            table.insert(retval,{y=tonumber(lltable[i].latitude),x=tonumber(lltable[i].longitude)});  --lowercase required.
        end
        if #retval > 0 then
            return retval;
        else
            gKHprint(0,'fnConvertLatLonToYXtable','generated table has no data, returning nil.');
            return nil;
        end
    else
        gKHprint(0,'fnConvertLatLonToYXtable','table missing or zero entries, returning nil.');
        return nil;
    end
end


--Returns true if any units from a side are found in area.
local function checkAreaForUnits(theSide,rpTable,coreUnitType,unitSubType)
  if (theSide == nil) or (rpTable == nil) or (coreUnitType == nil) then print('checkforArea:: invalid params'); return false; end
  if (unitSubType == nil) then unitSubType = 'None'; end --default to not using subtype.
  local retval = false;
  local s = VP_GetSide({name=theSide});
  local ctbl = fnConvertLatLonToYXtable(rpTable);
  if (s ~=nil and ctbl ~=nil) then
    local units = s:unitsBy(coreUnitType); --get back prefiltered table of names\guids by core type.
    if (units ~=nil) then
        local bFoundFlag = false;
        local u ; 
        local pt;
        for i,v in ipairs(units) do
            u = ScenEdit_GetUnit({guid=v.guid});
            if (u ~= nil) then
              pt = {y=u.latitude,x=u.longitude}
              if (unitSubType == 'None') then  -- Don't subfilter if it's empty check all units of coretype.
                bFoundFlag = insidePolygon(ctbl,pt);
                --bFoundFlag = u:inArea(rpTable);
                --print('1' .. u.name .. ' ' .. tostring(bFoundFlag)) 
              elseif (u.subtype == unitSubType) then -- check for subtype match provided.
                bFoundFlag = insidePolygon(ctbl,pt);
                --bFoundFlag = u:inArea(rpTable); 
                --print('2' .. u.name) 
              end
              u = nil; --clean up before next cycle
              pt = nil;
              if(bFoundFlag==true) then retval = true; break; end  --break on first found
            end
        end
        u = nil; --clean up upon break
        pt = nil;
    end
    units = nil; 
  end
  s = nil;
  ctbl=nil;
  return retval;
end

--end fucntions --

-- user code here
local r = ScenEdit_GetReferencePoints({side="Bad Guys", area={"RP-4","RP-5","RP-6","RP-7"}})
local rval;

if (r ~=nil) then
  if( checkAreaForUnits('Good Guys',r,'Facility','5002') == true) then
    print('A unit is still in the area');
  else
   print('No units left in area');
  end
end
r = nil;
