-- FATCOW script by Don Rudi/C. Gurk 
-- Edition human fatcow
-- © 11/2024
local FATCOW_VERSION = "1.0.5"

-- User adaptable values
local PLAYER = "FATCOW"			-- Player Unit Name
local FARP_ERECT_DELAY = 60 	-- how long it takes to erect the farp after landing in seconds

local nFuel = 5000										-- default how many kilograms of jetfuel and av gas are in the warehouse
local nHellfire = 2										-- default how many Hellfires of each type are in the Warehouse
local nHydra = 38										-- default how many Hydras of each available type are in the Warehouse
local nAPKWS = 7										-- default how many APKWS Hydras are in the Warehouse

-- default values
local FARP_COUNTRY_ID = country.id.CJTF_BLUE 

local heloNum = "19"							-- string for the number in the helicopter. My birthday, don't you dare change that
local FATCOW_SOLDIER = "Soldier M4 GRG"
local FATCOW_MANPAD = "Soldier stinger"

local hasLanded = false							-- has Fat Cow landed?
local groupId
local group

-- Helper function to convert nautical miles to meters
local function nauticalMilesToMeters(nm)
    return nm * 1852
end

-- helo position
local function getHelicopterPosition(heliName)
    local heli = Unit.getByName(heliName)
    if heli and heli:isExist() then
        local position = heli:getPosition()
        local heading = math.atan2(position.x.z, position.x.x)
        return heli:getPoint(), heading
    end
    return nil, nil
end

-- Fill FARP Warehouse
local function FARP_FILL()
	
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setLiquidAmount(0, 5000)		-- 5000 Liters Jetfuel
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setLiquidAmount(1, 5000)		-- 5000 Liters Av Gas
	
	--optional armament section
	
	--Apache
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,4,8,59}, nHellfire)						-- AGM-114L radar Hellfires
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,6,10,2}, 600)							-- 200 rounds 30mm (Apache)
	
	--Kiowa
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem("weapons.missiles.AGM_114K", nHellfire)		-- AGM-114L radar Hellfires
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,7,33,147}, nHydra)						-- Hydra-70 M151
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,7,33,148}, nHydra)						-- Hydra-70 M156
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem("weapons.missiles.AGR_20A", nAPKWS)			-- Hydra-70 APKWS
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem("weapons.bombs.OH58D_Red_Smoke_Grenade", 4)	-- four Smoke Grenade Red
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem("weapons.bombs.OH58D_Blue_Smoke_Grenade", 4)	-- four Smoke Grenade Blue
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem("weapons.bombs.OH58D_Green_Smoke_Grenade", 4)	-- four Smoke Grenade Green
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem("weapons.bombs.OH58D_Violet_Smoke_Grenade", 4)-- four Smoke Grenade Violet
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem("weapons.bombs.OH58D_Yellow_Smoke_Grenade", 4)-- four Smoke Grenade Yellow
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem("weapons.bombs.OH58D_White_Smoke_Grenade", 4)	-- four Smoke Grenade White
	
	--Chinook
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,2476}, 1)	-- M60 port
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,2477}, 1)	-- M60 starboard
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,2478}, 1)	-- M60 aft
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,2479}, 1)	-- M240 port
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,2480}, 1)	-- M240 starboard
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,2481}, 1)	-- M240 aft
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,2482}, 1)	-- M134 port
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,2483}, 1)	-- M134 starboard
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,2484}, 1)	-- M3M aft
	
	--Huey
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,160}, 1)	-- M134 port pylon
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,161}, 1)	-- M134 starboard pylon
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,174}, 1)	-- M134 port door
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,175}, 1)	-- M134 starboard door
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,176}, 1)	-- M60 port door
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,177}, 1)	-- M60 starboard door
	--Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,7,33,164}, 14)	-- 14 Hydra-70 M151
	--Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,7,33,165}, 14)	-- 14 Hydra-70 M156
	
	--Gazelle
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem("weapons.missiles.HOT3_MBDA", 4)			-- four HOT3 missiles
	Airbase.getByName("FATCOW_FARP"):getWarehouse():setItem({4,15,46,1767}, 1)							-- GIAT SAPHEI
	
end

-- Function to spawn the FARP and associated objects
local function spawnFARP(heliName)

	timer.scheduleFunction(function()
	
	local heliPos, heliHeading = getHelicopterPosition(heliName)
		if heliPos and heliHeading then
			-- Spawn Invisible FARP 100m aft of helicopter
			local farpX = heliPos.x - 100 * math.cos(heliHeading)
			local farpZ = heliPos.z - 100 * math.sin(heliHeading)
			
			-- Calculate position for APFC Fuel 50m aft of helicopter
			local apfcFuelX = heliPos.x - 35 * math.cos(heliHeading)
			local apfcFuelZ = heliPos.z - 35 * math.sin(heliHeading)
			
			-- Calculate position for Fuel Truck 30m left of helicopter
			local fuelX = apfcFuelX - 30 * math.sin(heliHeading)
			local fuelZ = apfcFuelZ + 30 * math.cos(heliHeading)
			
			-- Calculate position for Ammo 30m left of helicopter
			--local ammoX = fuelX - 10 * math.sin(heliHeading)
			--local ammoZ = fuelZ + 10 * math.cos(heliHeading)
			
			-- Calculate position for Humvee as FARP command vehicle
			--local humveeX = heliPos.x + 20 * math.cos(heliHeading)
			--local humveeZ = heliPos.z - 20 * math.sin(heliHeading)

			-- FARP Data
			local farpGroupData = {
				visible = false,
				groupId = nil,
				hidden = false,
				units = {
					[1] = {
						category = "Heliports",
						type = "Invisible FARP",
						shape_name = "invisiblefarp",
						--type = "FARP_T",
						--shape_name = "FARP_T",
						name = "FATCOW_FARP",
						x = farpX,
						y = farpZ,
						heading = heliHeading                    
					}
				},
				name = "FATCOW_FARP_GROUP",
				task = nil
			}
			coalition.addGroup(FARP_COUNTRY_ID, -1, farpGroupData)
			
			-- Static objects
			
			 -- Spawn Fuel (FARP Fuel Depot)
			local fuelTruck = {
				category = "Fortifications",
				type = "FARP Fuel Depot",
				name = "FATCOW_FUEL",
				x = fuelX,
				y = fuelZ,
				heading = heliHeading
			}
			coalition.addStaticObject(FARP_COUNTRY_ID, fuelTruck)
			
			-- Spawn APFC Fuel 
			local apfcFuel = {
				category = "Fortifications",
				type = "APFC fuel",
				name = "FATCOW_APFC_FUEL",
				x = apfcFuelX,
				y = apfcFuelZ,
				heading = heliHeading
			}
			coalition.addStaticObject(FARP_COUNTRY_ID, apfcFuel)
			 
			-- Calculate position for Fire Extinguisher 70m aft of helicopter
			local extinguisherX = heliPos.x - 70 * math.cos(heliHeading)
			local extinguisherZ = heliPos.z - 70 * math.sin(heliHeading)

			-- Spawn Fire Extinguisher
			local fireExtinguisher = {
				category = "Fortifications",
				shape_name = "M92_FireExtinguisher01",
				type = "FireExtinguisher01",
				name = "FATCOW_FIRE_EXTINGUISHER",
				x = extinguisherX,
				y = extinguisherZ,
				heading = heliHeading
			}
			coalition.addStaticObject(FARP_COUNTRY_ID, fireExtinguisher)

		   --Calculate generator and hose
			local hoseX = heliPos.x - 50 * math.cos(heliHeading)
			local hoseZ = heliPos.z - 50 * math.sin(heliHeading)

			-- Spawn generator and hose
			local hose1 = {
				category = "Fortifications",
				shape_name = "M92_M32-10C_01",
				type = "M32-10C_01",
				name = "FATCOW_HOSE1",
				x = hoseX,
				y = hoseZ,
				heading = heliHeading
			}
			coalition.addStaticObject(FARP_COUNTRY_ID, hose1)
			
			-- Spawn Infantry next to Fire Extinguisher (left and right)
			local personnelHeading = (heliHeading + math.pi) % (2 * math.pi)  -- Facing 180 degrees away from helicopter
			local personnelPositions = {
				{ x = extinguisherX - 2 * math.cos(heliHeading + math.pi / 2), z = extinguisherZ - 2 * math.sin(heliHeading + math.pi / 2) },  -- 2 meters left of extinguisher
				{ x = extinguisherX + 2 * math.cos(heliHeading + math.pi / 2), z = extinguisherZ + 2 * math.sin(heliHeading + math.pi / 2) }   -- 2 meters right of extinguisher
			}

			for i, pos in ipairs(personnelPositions) do
				local personnel = {
					category = "Infantry",
					type = FATCOW_SOLDIER,
					name = "FATCOW_INFANTRY_PERSONNEL_" .. i,
					x = pos.x,
					y = pos.z,
					heading = personnelHeading
				}
				coalition.addStaticObject(FARP_COUNTRY_ID, personnel)
			end

			-- Define the infantry group data with 6 infantry and 1 MANPAD
			local infantryGroupData = {
				visible = true,
				name = "FATCOW_INFANTRY_GROUP",
				country = FARP_COUNTRY_ID,
				category = Group.Category.GROUND,
				task = "Ground Nothing",
				units = {
					[1] = {
						type = FATCOW_SOLDIER,
						x = heliPos.x - 20,
						y = heliPos.z - 5,
						heading = heliHeading,
						name = "FATCOW_INFANTRY_1"
					},
					[2] = {
						type = FATCOW_SOLDIER,
						x = heliPos.x - 20,
						y = heliPos.z + 5,
						heading = heliHeading,
						name = "FATCOW_INFANTRY_2"
					},
					[3] = {
						type = FATCOW_SOLDIER,
						x = heliPos.x + 5,
						y = heliPos.z + 20,
						heading = heliHeading,
						name = "FATCOW_INFANTRY_3"
					},
					[4] = {
						type = FATCOW_SOLDIER,
						x = heliPos.x - 5,
						y = heliPos.z + 20,
						heading = heliHeading,
						name = "FATCOW_INFANTRY_4"
					},
					[5] = {
						type = FATCOW_SOLDIER,
						x = heliPos.x + 20,
						y = heliPos.z + 10,
						heading = heliHeading,
						name = "FATCOW_INFANTRY_5"
					},
					[6] = {
						type = FATCOW_SOLDIER,
						x = heliPos.x + 20,
						y = heliPos.z - 10,
						heading = heliHeading,
						name = "FATCOW_INFANTRY_6"
					},
					[7] = {
						type = FATCOW_MANPAD,
						x = heliPos.x + 50 * math.cos(heliHeading),
						y = heliPos.z + 50 * math.sin(heliHeading),
						heading = heliHeading,
						name = "FATCOW_INFANTRY_7"
					}
				}
			}

			-- Spawn the infantry group using coalition.addGroup
			coalition.addGroup(FARP_COUNTRY_ID, Group.Category.GROUND, infantryGroupData)
				
			-- fill FARP Warehouse 2 seconds after spawn
			timer.scheduleFunction(FARP_FILL, {}, timer.getTime() + 2)
		else
			trigger.action.outText("FATCOW helicopter not found!", 10)
		end
	end, {}, timer.getTime() + FARP_ERECT_DELAY)
end

-- Function to despawn the FARP and all associated objects
local function despawnFARP()
	missionCommands.removeItemForGroup(groupId, "FATCOW activate")
	missionCommands.removeItemForGroup(groupId, "FATCOW deactivate")

   local objectNames = { "FATCOW_FARP", "FATCOW_FIRE_EXTINGUISHER", "FATCOW_APFC_FUEL", "FATCOW_HOSE1", "FATCOW_FUEL", "FATCOW_INFANTRY_GROUP" }
   
    for i = 1, 2 do
        table.insert(objectNames, "FATCOW_INFANTRY_PERSONNEL_" .. i)
    end
    
    for _, name in ipairs(objectNames) do
        local obj = StaticObject.getByName(name)
        if obj and obj:isExist() then
            obj:destroy()
        end
    end
    trigger.action.outText("FATCOW FARP deactivated!", 10)
end

-- Function to deactivate FARP
local function deactivateFARP()
    
    trigger.action.setUserFlag("FATCOW_ACTIVE", 0)
    despawnFARP()

    -- Remove "FATCOW deactivate" radio item
    missionCommands.removeItemForGroup(groupId, "FATCOW deactivate")
end

-- Function to activate FARP
local function activateFARP()
    trigger.action.outText("Activating FARP - wait " .. FARP_ERECT_DELAY .. " seconds.", 10)
	
    trigger.action.setUserFlag("FATCOW_ACTIVE", 1)
    spawnFARP(PLAYER)

    -- Remove "FATCOW activate" radio item
    missionCommands.removeItemForGroup(groupId, "FATCOW activate")

    -- Add radio item for deactivating FATCOW
    missionCommands.addCommandForGroup(groupId, "FATCOW deactivate", nil, function() deactivateFARP () end)
end

-- add F10 radio menu
local function addF10menu()
    local myFatcow = Unit.getByName(PLAYER)

    if myFatcow and myFatcow:isExist() then
        group = myFatcow:getGroup()
        if group then
            groupId = group:getID()  -- Get the group ID

            -- Adding the activate command for FARP
            missionCommands.addCommandForGroup(groupId, "FATCOW activate", nil, function() activateFARP () end)

        else
            trigger.action.outText("Group not found for unit: " .. PLAYER, 10)
        end
    else
        trigger.action.outText("Unit not found: " .. PLAYER, 10)
    end
end




-- Monitor Player has landed
function onGround()
    local unit = Unit.getByName('FATCOW')
    if unit then
        if unit:inAir() == false then
            if hasLanded == false then
                addF10menu()
                hasLanded = true
                trigger.action.outText(PLAYER .. heloNum .. " has landed.", 10)
            end
        elseif unit:inAir() == true and hasLanded == true then
            hasLanded = false
            despawnFARP()
            -- trigger.action.outText("In Air", 10)
        end
    end
    -- Schedule the function to run again after 5 seconds
    timer.scheduleFunction(onGround, {}, timer.getTime() + 5)
end

-- Initial call to start the onGround function
onGround()

-- loading message
trigger.action.outText("CG FATCOW (human) script version " .. FATCOW_VERSION .. " loaded.", 5)