require("debug")

include("class.lua")
include("turretControl.lua")

TurretControlHUD = class(TurretHookListener)

local function pack(...)
    arg.n = nil
    return arg
end

function TurretControlHUD:init(script)
    self.script = script

    self.script:addListener(self)

    self.hudFiles = {
        "objectDisplay.lua",
        "crosshairs.lua",
        "bankInfo.lua",
        "turretStatus.lua",
        "generalInfo.lua",
        "mapGauge.lua",
        "shipStatus.lua",
        "helpScreen.lua",
    }

    self.hudClasses = {}
    self.hudGauges = {}

    self.hotKeyActions = {}
    self.hotkeyStrings = {}
end

function TurretControlHUD:addKeybind(key, desc, func, ...)
    local action = Globals.HotKeyManager:addKeyTyped(key, func, ...)

    if (action ~= nil) then
        table.insert(self.hotKeyActions, action)
        table.insert(self.hotkeyStrings, {
            key = key,
            description = desc
        })
    end
end

function TurretControlHUD:initHotKeys()
    -- Map control keybindings
    self:addKeybind("Pad +", "Zoom into map", self.hudConfig.changeMapScale, self.hudConfig, true)
    self:addKeybind("Pad -", "Zoom out of map", self.hudConfig.changeMapScale, self.hudConfig, false)
    self:addKeybind("a", "Enable/Disable automatic controls", self.script.setManual, self.script)
    self:addKeybind("F5", "Show/Hide help screen", self.hudConfig.setShowingHelp, self.hudConfig)
end

function TurretControlHUD:onMissionInit()
    self.hudClasses = {}
    self.hudGauges = {}

    self.hudConfig = TurretHudConfig(self)

    self:loadGauges()

    self:initHotKeys()
end

function TurretControlHUD:onUpdate()
    self:drawHud()
end

function TurretControlHUD:onMissionEnd()
    while (#self.hotKeyActions > 0) do
        Globals.HotKeyManager:removeAction(self.hotKeyActions[1])
        table.remove(self.hotKeyActions, 1)
    end

    self.hotkeyStrings = {}
end

function TurretControlHUD:loadGauges()
    for __, v in ipairs(self.hudFiles) do
        self:loadGauge(v)
    end
end

function TurretControlHUD:loadGauge(filename)
    local func, err = loadLuaFile(filename)

    if (func == nil) then
        if (err) then
            error(err)
        else
            stackErrorf("Unknown error happened while loading gauge file %q!", filename)
        end
    else
        local vals = pack(xpcall(func, function(err)
            return string.format("Error while executing external lua file %q:\n%s\n\n%s", filename, err, debug.traceback())
        end))

        if (not vals[1]) then
            error(vals[2])
        else
            for i = 2, #vals do
                table.insert(self.hudClasses, vals[i])

                table.insert(self.hudGauges, vals[i](self))
            end
        end
    end
end

function TurretControlHUD:drawHud()
    if (not self:isDrawing()) then
        return
    end

    for __, v in ipairs(self.hudGauges) do
        if (v:shouldDraw()) then
            v:render()
        end
    end
end

function TurretControlHUD:setDrawing(bool)
    self.drawing = bool
end

function TurretControlHUD:getScript()
    return self.script
end

function TurretControlHUD:getConfig()
    return self.hudConfig
end

function TurretControlHUD:isDrawing()
    if (not self:isValid()) then
        return false
    end

    if (not self.script:isActive()) then
        return false
    end

    return self.drawing
end

function TurretControlHUD:isValid()
    if (self.script == nil) then
        return false
    end

    return self.script:isValid()
end

TurretHudConfig = class()

function TurretHudConfig:init(hudScript)
    self.hudScript = hudScript

    self.mapScale = 1.0

    self.modelFraction = 0.5

    self.maxSubsysColumns = 2

    self.showingHelp = false

    self.crosshairNumber = 5
end

function TurretHudConfig:setShowingHelp(show)
    if (show == nil) then
        show = not self.showingHelp
    end

    self.showingHelp = show
end

function TurretHudConfig:setCrosshairNumber(num)
    if (num < 0) then
        return
    end

    self.crosshairNumber = num
end

function TurretHudConfig:isShowingHelp()
    return self.showingHelp
end

function TurretHudConfig:changeMapScale(zoomIn)
    if (zoomIn) then
        self.mapScale = self.mapScale * 0.9
    else
        self.mapScale = self.mapScale * 1.1
    end
end

function TurretHudConfig:getMaximumTurretColumns()
    return self.maxSubsysColumns
end

function TurretHudConfig:getCrosshairNumber()
    return self.crosshairNumber
end

function TurretHudConfig:getMapScale()
    return self.mapScale
end

function TurretHudConfig:getModelFraction()
    return self.modelFraction
end
