gKH = {}; -- define my personal namspace to contain my functions to. 
gKH.Magazines={}; --define my magazine code library where this stuff comes from
gKH.Temp={}; -- define my temporary storage namspace; --in this sample we are not saving the state or modifying tables but you could.

-- i would prefer you rename this to something more personal to yourself between 1 and say 6 characters.
-- like gXYZ, and throw this into note pad and just do a search and replace of gKH.Magazines to whatever you use.


---Begin global table variables ---
--guid,loadoutid,quanity required.
--don't forget to add the comma afte new entries unless it's the very last in the list(even then it's fine).
gKH.Temp.airbasesToFill = {
{name='SUA_1', guid='4FH7PU-0HMNDPRJL928I',loadoutid=26461, quantity=50,mydesc="f22 aim 260 loadout"}, 
{name='SUA_1', guid='4FH7PU-0HMNDPRJL928I',loadoutid=29716, quantity=50,mydesc="f18 aim 120D loadout"}, 
{name='SUA_2', guid='4FH7PU-0HMNDPRJL9A20',loadoutid=26461, quantity=50,mydesc="f22 aim 260 loadout"}, 
{name='SUA_2', guid='4FH7PU-0HMNDPRJL9A20',loadoutid=29716, quantity=50,mydesc="f18 aim 120D loadout"}
}


--requires 1147.44+/~1300
--name,guid are required, the guid must be actual guid, the name can be anything it techinicaly doesn't have to mach the unit.
--optional specific_magguid="guid string" and specific_wpnrecguid="guid string", quantity=number.
gKH.Temp.TopUpAllExistingMagsUnitList = {
    {name='SAM Bn S-400 #1', guid='4FH7PU-0HMNDPRJL9OQ0',comment="attempts all mags on unit"}, 
    {name='SAM Bn S-400 #2', guid='4FH7PU-0HMNDPRJL99BD',comment="attempts all mags on unit"}, 
    {name='DDG 125 #1 rim174 on munitions only', guid='4FH7PU-0HMNDPRJL9Q17',specific_magguid ="4FH7PU-0HMNDPRJL9QJH",specific_wpnrecguid="4FH7PU-0HMNDPRJL9QJI",comment="fastest perf it will only do this specific mag and only this specfic wpn record 174A blk1a"},
    {name='DDG 125 #1 helocoptermountonly', guid='4FH7PU-0HMNDPRJL9Q17',specific_magguid ="4FH7PU-0HMNDPRJL9Q6P",comment="will only process the helicopter mag."},
    {name='DDG 125 #1 mk54LHT to 24 only', guid='4FH7PU-0HMNDPRJL9Q17',specific_wpnrecguid ="4FH7PU-0HMNDPRJL9Q75",quantity=24,comment="will search all mags but only till it finds this specific mk54 LHT record and change it to 24"}
    --note the last entry would run faster searching wise if you also provided the magguid involved...but you don't have too.
}



--End global table variables ---



--- Begin global functions ---


---Function to fill a list of airbases from table data.
---@param tbl table @ A table of entries each containing at least a guid,loadoutid, and quantity.
function gKH.Magazines:FillAirBasesInitially(tbl)
    local fn = "FillAirBasesInitially(): "
    if (tbl ==nil) or type(tbl) ~= "table" then print(fn.. 'tbl parameter is missing or not a table. aborting'); return false; end
    local counter,scounter = 0,0;
    for k,v in pairs(tbl) do -- k= index, v = the list entry
        if v.guid == nil or v.loadoutid == nil or v.quantity == nil then print(fn.. "Table entry is invalid. a guid,loadoutid or quantity is missing."); return false; end
        local retval,unit = pcall(SE_GetUnit,{guid=v.guid}); --get unit, will fail when does not exist.
        if (retval == true) and unit ~=nil then -- unit exists so let's proceed. 
            local retval,response = pcall(ScenEdit_FillMagsForLoadout,{guid=v.guid, loadoutid=v.loadoutid, quantity=v.quantity});
            if ((retval == true) and type(response) =='table') and #response > 0 then
                print(fn .. "successes and failures for filling mags for loadout on " .. tostring(v.name) .. ":");
                print(response);
                scounter = scounter +1
            else
                print(fn.. "A call to ScenEdit_FillMagsForLoadout seriously failed for entry " .. tostring(v.name));
                if type(response) == "table" then print(response); else print(tostring(response)); end
            end
            retval,unit = false,nil; --explicitly release unit
        else
            print(fn.."The unit " ..tostring(v.name) .. ' no longer exists or its guid changed and will be skipped.');
        end
        counter = counter + 1
    end
    print("A total of " .. tostring(counter) .. " units were processed, and " .. tostring(scounter) .. " processed successfully.");
end



--- Function to process a units to attempt to top all it's mags wepaon reconds on.
--- requires 1147.44+ or 125x+ I think.
--- the magguid and qpnguid params are optional and can be used in concert together or seperate.
---@param u CMO__UnitWrapper @ the active unit wrapper 
---@param magguid string @ optional a string representing the only magguid you want processed.
---@param wpnguid string @ optional a string reprsenting the only wpnguid you want processed.
---@param quantity number @ integer representing what you want the value set too, if missing other max capactity will be attempted.
---@returns true|false on success\fail as well as a mag count and a wpn count of things it thinks it touched without serious error.
---example: topUpUnitsMags(unitvar,nil,nil,24)
function gKH.Magazines:topUpUnitsMags(u,magguid,wpnguid,quantity)
    local fn = "topUpUnitsMags(): ";
    if u == nil then print('Unit wrapper parameter missing. call aborted.'); return false,0,0; end
    local totalmags,totalwpns = 0,0;
    if #u.magazines < 1 then return true,0,0; end -- no mags to process, maybe they got blown up.
    local magmatch,wpnmatch,doquant = false,false,false
    if (magguid ~=nil) and type(magguid) == "string" then magmatch = true; end
    if (wpnguid ~=nil) and type(wpnguid) == "string" then wpnmatch = true; end
    if (quantity ~=nil) and type(quantity) == "number" then doquant = true; end
    for k,v in ipairs(u.magazines) do --run through the mags.
        if (magmatch) and v.mag_guid ~= magguid then
            goto skip_to_next_label_XI8FA
            --ugly but functional without rewritting this differently.
        end
        local retval,m = pcall(u.getUnitMagazine,u,v.mag_guid);  -- get each mag itself.
        if (retval ==true) and m ~= nil then
            for i,j in ipairs(v.mag_weapons) do  --loop through each weapon record per mag.
                if (wpnmatch) and j.wpn_guid ~= wpnguid then
                    goto skip_to_next_label_XI8GG;
                    --ugly but functional without rewritting this differently.
                end
                local qty = j.wpn_maxcap; if doquant==true then qty=quantity; end
                local retval2 = m:setExactWeaponQuantity(j.wpn_guid, qty); --set to max capacity. 
                if retval2 ~= qty then --likely a maxcap issue user will need to adjust or add logic and maybe config options in entries.
                    print(fn.. 'Adding weapons to weapon record ' .. tostring(j.wpn_name) ..' on mag ' ..tostring(v.mag_name)
                    .. ' on unit '.. tostring(u.name) ..' may have failed, likely because the mag itself reached its cap of '
                    .. tostring(v.mag_capacity));
                end
                totalwpns = totalwpns +1;
                ::skip_to_next_label_XI8GG::
            end
            totalmags = totalmags +1;
        else
            print(fn .. "Could not obtain mag via getUnitMagazine() for mag ".. tostring(v.mag_name)
            .. " on unit ".. tostring(u.name));
        end
        retval,m = nil,nil;
        ::skip_to_next_label_XI8FA::
    end
    return true,totalmags,totalwpns;
end

---Function to process the a table list of units to attempt to process all mags and wpn records in the mags.
---@param tbl 
---@returns true|false on general success failure, true doesn't mean there were not problems just that it could finish.
function gKH.Magazines:TopUpAllExistingMags(tbl)
    local fn = "TopUpAllExistingMags(): " -- for less typing in print statements.
    if (tbl ==nil) or type(tbl) ~= "table" then print(fn ..'Table parameter is missing or not a table. aborting'); return false; end
    local counter,scounter,totalmags,totalwprec = 0,0,0,0; --running totals if you want them.
    for k,v in pairs(tbl) do -- k= index, v = the list entry
        local retval,u = pcall(SE_GetUnit,{guid=v.guid}); --get unit, will fail when does not exist.
        if (retval == true) and u ~=nil then -- unit exists so let's proceed. 
            local retval2,mags,wpns = gKH.Magazines:topUpUnitsMags(u,v.specific_magguid,v.specific_wpnrecguid,v.quantity); -- call the func to do thee work. pass in the unit wrapper, and params even if they don't exist.
            if retval2 == false then 
                print(fn.. 'There was problem processing unit with entry named ' .. tostring(v.name) .. " (unitname: "..tostring(u.name) ..") continuing to next.");
            else
                if mags ==nil then mags = 0;end
                if wpns ==nil then wpns = 0;end 
                print(fn.. 'Finished processing entry ' ..tostring(v.name) .. '  # of mags processed: '..tostring(mags)
                .. " # of wpns processed: ".. tostring(wpns));
                scounter=scounter+1
                totalmags = totalmags + mags;
                totalwprec = totalwprec + wpns;
            end
        else
            print(fn.. "The unit " ..tostring(v.name) .. ' no longer exists or its guid changed and will be skipped.');
        end
        counter = counter +1
        retval,retval2,mags,wpns,u = nil,nil,nil,nil,nil; --explicity release all these for garbage collection.
    end
    print(fn.." Done.");
    print("Total entries processed was ".. tostring(counter).. ", total successfully was "..tostring(scounter));
    print("Total mags processed was " ..tostring(totalmags) .. ", total weapon records touched was "..tostring(totalwprec));
end


--- end loading global functions  ---
print('gKH.Magazines library loaded.');  -- if this is in the log we know we loaded ok.
-----------

