radio_ops.watcher = {}
-- holsd all handler functions
radio_ops.watcher.eventHandler = {}

--- start radio transmission for a static objects, does loop
---@param zone_name string name of the trigger zone (determins signal position)
---@param opts table config table, used for transmission details
function radio_ops.watcher.enable_trigger_radio(zone_name, opts)
    local zone = trigger.misc.getZone(zone_name)

        if zone ~= nil then
            local p = zone.point
            local file = opts["file"]
            local freq = opts["frequency"]
            local pwr = opts["power"]
            local duration = opts["duration"]
            local modulation

            if opts["modulation"] == "FM" then
                modulation = radio.modulation.FM
            else
                modulation = radio.modulation.AM
            end

            trigger.action.radioTransmission(file, p, modulation, false, freq, pwr, zone_name.."_transmit")
            radio_ops.DATA.active_zones[zone_name] = (timer.getTime() + duration)
        end
end

--- start radio transmission for moving target, does not loop, requires re-queue
---@param group_name string name of the group (determins signal position and stop conditions)
---@param opts table config table, used for transmission details
function radio_ops.watcher.enable_group_radio(group_name, opts)
    local group = Group.getByName(group_name)

    if group ~= nil then    
        -- first set the frequency of the group
        -- this is not required, but makes it more authentic
        local unit = group:getUnit(1)
        local p = unit:getPoint()

        if p ~= nil then
            local file = opts["file"]
            local freq = opts["frequency"]
            local pwr = opts["power"]
            local duration = opts["duration"]
            local modulation

            if opts["modulation"] == "FM" then
                modulation = radio.modulation.FM
            else
                modulation = radio.modulation.AM
            end

            -- aswell remember this unit as an active unit
            trigger.action.radioTransmission(file, p, modulation, false, freq, pwr, group_name.."_transmit")
            radio_ops.DATA.active_units[group_name] = (timer.getTime() + duration)
        end   
    end
end

--- enable all configured transmissions
function radio_ops.watcher.enable_radio()

    for k, v in pairs(radio_ops.DATA.transmissions) do
        radio_ops.watcher.enable_trigger_radio(k, v)
    end

    for k, v in pairs(radio_ops.DATA.unit_transmissions) do
        radio_ops.watcher.enable_group_radio(k, v)
    end
end

--- stop all registerede transmissions
function radio_ops.watcher.disable_radio()

    for k, v in pairs(radio_ops.DATA.active_zones) do
        trigger.action.stopRadioTransmission(k.."_transmit")
        radio_ops.DATA.active_zones[k] = nil
    end

    for k, v in pairs(radio_ops.DATA.active_units) do
        trigger.action.stopRadioTransmission(k.."_transmit")
        radio_ops.DATA.active_units[k] = nil
    end
end

--- Requeue the transmission for moving targets. 
--- Requires duration parameter set by mission author, 
--- otherwise transmission might stop early or might have gaps between loops
function radio_ops.watcher.TaskTimer()
    -- update the transmission location for moving transmitters like planes

    for k, v in pairs(radio_ops.DATA.active_zones) do
        if v ~= nil then
            if timer.getTime() > v then
                -- first delete the current transmission, before starting a new one
                radio_ops.DATA.active_zones[k] = nil
                trigger.action.stopRadioTransmission(k.."_transmit")
                local opts = radio_ops.DATA.transmissions[k]
                radio_ops.watcher.enable_trigger_radio(k, opts)
            end
        end
    end


    for k, v in pairs(radio_ops.DATA.active_units) do
        if v ~= nil then
            if timer.getTime() > v then
                -- first delete the current transmission, before starting a new one
                radio_ops.DATA.active_units[k] = nil
                trigger.action.stopRadioTransmission(k.."_transmit")
                local opts = radio_ops.DATA.unit_transmissions[k]
                radio_ops.watcher.enable_group_radio(k, opts)
            end
        end
    end

    timer.scheduleFunction(radio_ops.watcher.TaskTimer, {}, timer.getTime() + radio_ops.DATA.TASK_UPDATE_INTVL)
end

---watch for required events to stop a dynamic transmission (e.g. engine shutdown, unit crash)
---@param event table event table
---@return boolean always true
function radio_ops.watcher.eventHandler:onEvent(event)
    -- there was an error in the dcs event engine => return with satus code false
    if event == nil or event.initiator == nil then 
        return false
    end

    -- events causing a transmission stop
    -- all these events hold a Unit in the initiator field
    if (event.id == world.event.S_EVENT_ENGINE_SHUTDOWN) or
       (event.id == world.event.S_EVENT_CRASH) or
       (event.id == world.event.S_EVENT_DEAD) then

        if event.initiator:getCategory() ~= Object.Category.UNIT then
            return true
        end

        -- get the callers group
        local group = event.initiator:getGroup()
        local name = group:getName()

        if (radio_ops.DATA.active_units[name] ~= nil) then
            -- stop the transmission and reset state variables
            trigger.action.stopRadioTransmission(name.."_transmit")
            radio_ops.DATA.active_units[name] = nil
        end
    end 

    return true
end