-- ====================================================================================
-- TUM.MISSION - HANDLES THE MAIN MISSION
-- ====================================================================================
-- ====================================================================================

TUM.mission = {}

TUM.mission.status = {
    NONE = 0,
    IN_PROGRESS = 1,
    COMPLETED = 2,
    FAILED = 3,
}

TUM.mission.endCause = { -- Why did the mission end?
    ABORTED = 1,
    COMPLETED = 2,
    FAILED = 3
}

do
    local OBJECTIVES_REMINDER_INTERVAL = 5
    local missionStatus = TUM.mission.status.NONE
    local objectivesReminderIntervalLeft = OBJECTIVES_REMINDER_INTERVAL

    function TUM.mission.getStatus()
        return missionStatus
    end

    local function closeMission(removeAllUnits)
        if removeAllUnits then
            TUM.wingmen.removeAll()
            TUM.airForce.removeAll()
            TUM.ambientWorld.removeAll()
            TUM.enemyAirDefense.removeAll()
            TUM.objectives.removeAll()
        end

        missionStatus = TUM.mission.status.NONE
        TUM.intermission.createMenu()
    end

    function TUM.mission.checkMissionStatus(silent)
        silent = silent or false
        if missionStatus ~= TUM.mission.status.IN_PROGRESS then return end

        if TUM.objectives.areAllCompleted() then
            missionStatus = TUM.mission.status.COMPLETED

            DCSEx.dcs.outPicture("Pic-MissionComplete.png", 5, true, 0, 1, 1, 25, 1)
            trigger.action.outSound("UI-MissionEnd.ogg")

            if not silent then
                TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "commandMissionComplete", nil, "Command", true)
            end
        end
    end

    function TUM.mission.beginMission(silent)
        silent = silent or false

        closeMission(true)
        TUM.intermission.removeMissionZonesMarkers()

        for _=1,TUM.settings.getValue(TUM.settings.id.TARGET_COUNT) do
            TUM.objectives.add()
        end

        if TUM.objectives.getCount() == 0 then
            TUM.log("Couldn't create any objective, mission creation failed.", TUM.logLevel.WARNING)
            closeMission(true)
            return
        end

        TUM.supportAWACS.create() -- Create the AWACS aircraft if it wasn't airborne already
        TUM.enemyAirDefense.create() -- Must be called once objectives have been created
        TUM.airForce.create() -- Must be called once objectives have been created
        TUM.missionMenu.create() -- Must be called once objectives have been created

        local briefingOrder = DCSEx.table.shuffle({1, 2, 3, 4, 5}) -- Just to make sure the same description is used twice

        local briefingText = ""
        for i=1,TUM.objectives.getCount() do
            local obj = TUM.objectives.getObjective(i)
            briefingText = briefingText.."Objective "..obj.name..":\n"
            local descriptions = Library.tasks[obj.taskID].description.briefing

            briefingText = briefingText..descriptions[DCSEx.math.clamp(briefingOrder[i], 1, #descriptions)]
            if i < TUM.objectives.getCount() then
                briefingText = briefingText.."\n\n"
            end
        end

        DCSEx.envMission.setBriefing(TUM.settings.getPlayerCoalition(), briefingText)
        DCSEx.envMission.setBriefing(TUM.settings.getEnemyCoalition(), "")

        missionStatus = TUM.mission.status.IN_PROGRESS

        if not silent then
            DCSEx.dcs.outPicture("Pic-MissionStart.png", 5, true, 0, 1, 1, 25, 1)
            trigger.action.outSound("UI-MissionStart.ogg")
        end

        trigger.action.outText("MISSION OBJECTIVES:\n\n"..TUM.mission.getSummaryString(), 10)

        objectivesReminderIntervalLeft = OBJECTIVES_REMINDER_INTERVAL
    end

    function TUM.mission.getPlayerCallsign()
        local player = world.getPlayer()
        if player then return player:getCallsign() end
        return "Flight"
    end

    function TUM.mission.getSummaryString(onlyShowIncomplete, doublePercentage)
        onlyShowIncomplete = onlyShowIncomplete or false
        if missionStatus == TUM.mission.status.NONE then return "" end

        local missionSummary = ""
        local validObjCount = 1
        for i=1,TUM.objectives.getCount() do
            local o = TUM.objectives.getObjective(i)

            if o then
                if not o.completed or not onlyShowIncomplete then
                    local bulletCharacter = "⬤"
                    if validObjCount == 1 then bulletCharacter = "❶"
                    elseif validObjCount == 2 then bulletCharacter = "❷"
                    elseif validObjCount == 3 then bulletCharacter = "❸"
                    elseif validObjCount == 4 then bulletCharacter = "❹"
                    elseif validObjCount == 5 then bulletCharacter = "❺"
                    elseif validObjCount == 6 then bulletCharacter = "❻"
                    elseif validObjCount == 7 then bulletCharacter = "❼"
                    elseif validObjCount == 8 then bulletCharacter = "❽"
                    elseif validObjCount == 9 then bulletCharacter = "❾"
                    elseif validObjCount == 10 then bulletCharacter = "❿"
                    end

                    missionSummary = missionSummary..bulletCharacter.." Objective "..o.name..": "..Library.tasks[o.taskID].description.short
                    if not o.completed then
                        missionSummary = missionSummary.." ("..TUM.objectives.getObjectiveProgress(i, doublePercentage)..")"
                    else
                        missionSummary = missionSummary.." [DONE!]"
                    end

                    if i < TUM.objectives.getCount() then
                        missionSummary = missionSummary.."\n"
                    end

                    validObjCount = validObjCount + 1
                end
            end
        end

        return missionSummary
    end

    function TUM.mission.endMission(endCause)
        endCause = endCause or TUM.mission.endCause.ABORTED

        if endCause == TUM.mission.endCause.ABORTED then
            DCSEx.dcs.outPicture("Pic-MissionAborted.png", 5, true, 0, 1, 1, 25, 1)
            TUM.playerScore.reset(true, "mission aborted")
        elseif endCause == TUM.mission.endCause.COMPLETED then
            DCSEx.dcs.outPicture("Pic-MissionComplete.png", 5, true, 0, 1, 1, 25, 1)
        elseif endCause == TUM.mission.endCause.FAILED then
            DCSEx.dcs.outPicture("Pic-MissionFailed.png", 5, true, 0, 1, 1, 25, 1)
        end
        trigger.action.outSound("UI-MissionEnd.ogg")

        closeMission(true)
    end

    ----------------------------------------------------------
    -- Called on every mission update tick (every 15 seconds)
    -- @return True if a radio message or other output was triggered, false otherwise
    ----------------------------------------------------------
    function TUM.mission.onClockTick()
        if TUM.mission.getStatus() == TUM.mission.status.NONE then return false end -- Not currenly in a mission
        if TUM.objectives.getCount() <= 0 then return false end -- No objectives

        objectivesReminderIntervalLeft = objectivesReminderIntervalLeft - 1
        if objectivesReminderIntervalLeft > 0 then return false end

        objectivesReminderIntervalLeft = OBJECTIVES_REMINDER_INTERVAL

        TUM.mission.playMissionSummaryRadioMessage(true, false)
        return true
    end

    -------------------------------------
    -- Called when an event is raised
    -- @param event The DCS World event
    -------------------------------------
    function TUM.mission.onEvent(event)
        if missionStatus == TUM.mission.status.NONE then return end
        if not event.initiator then return end
        if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end
        if not event.initiator:getPlayerName() then return end

        -- All objectives complete and all players on the ground? Mission is complete
        if event.id == world.event.S_EVENT_RUNWAY_TOUCH or event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT or event.id == world.event.S_EVENT_PLAYER_LEAVE_UNIT then
            if TUM.objectives.areAllCompleted() and #DCSEx.world.getPlayersInAir(TUM.settings.getPlayerCoalition()) == 0 then
                TUM.mission.endMission(TUM.mission.endCause.COMPLETED)
            end
        end

        if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end

        -- When player dies in single-player, fail the mission
        if event.id == world.event.S_EVENT_CRASH or event.id == world.event.S_EVENT_EJECTION or event.id == world.event.S_EVENT_PILOT_DEAD then
            TUM.mission.endMission(TUM.mission.endCause.FAILED)
        end
    end

    function TUM.mission.playMissionSummaryRadioMessage(onlyShowIncomplete, delayed)
        onlyShowIncomplete = onlyShowIncomplete or false
        delayed = delayed or false

        local incompleteObjectives = TUM.objectives.getCount() - TUM.objectives.getCompletedCount()

        local messageID = "commandMissionComplete"
        if incompleteObjectives > 1 then
            messageID = "commandObjectivesManyLeft"
        elseif incompleteObjectives == 1 then
            messageID = "commandObjectivesOneLeft"
        end

        TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), messageID, { TUM.mission.getSummaryString(onlyShowIncomplete, true) }, "COMMAND", delayed)
    end
end