include("class.lua")
include("luaGraphics.lua")

HudGauge = class()

function HudGauge:init(hudInst)
    self.hudScript = hudInst
    self.hudConfig = hudInst:getConfig()
    self.script = hudInst:getScript()
    self.scriptConfig = self.script:getConfig()

    self.x = 0
    self.y = 0

    self.r = 0
    self.g = 255
    self.b = 0
    self.a = 120

    self.margin = 5

    self.maxX = -1
    self.maxY = -1

    self.drawBox = true

    self.lastStringDrawX = -1
    self.lastStringDrawY = -1

    self.width = nil
    self.height = nil

    self.clipped = false
end

function HudGauge:__transform(x, y, force)
    return self:__transformX(x, force), self:__transformY(y, force)
end

function HudGauge:__transformX(x, force)
    if (type(x) == "number") then
        if (self.clipped and not force) then
            return x
        else
            return self.x + x
        end
    else
        stackErrorf("Requiring an argument of type \"number\" but got %q!", type(x))
        return 0
    end
end

function HudGauge:__transformY(y, force)
    if (type(y) == "number") then
        if (self.clipped and not force) then
            return y
        else
            return self.y + y
        end
    else
        stackErrorf("Requiring an argument of type \"number\" but got %q!", type(y))
        return 0
    end
end

function HudGauge:getName()
    return "Unfinished gague"
end

function HudGauge:getDescription()
    return "Unfinished gauge"
end

function HudGauge:render()
    -- nothing
end

function HudGauge:setDrawBox(bool)
    self.drawBox = bool
end

function HudGauge:setClipping(bool)
    self.needsClipping = bool
end

function HudGauge:move(x, y)
    if (x < 1) then
        x = gr.getScreenWidth() * x
    end
    self.x = x

    if (y < 1) then
        y = gr.getScreenHeight() * y
    end
    self.y = y
end

function HudGauge:resize(width, height)
    if (width < 1) then
        width = gr.getScreenWidth() * width
    end
    self.width = width

    if (height < 1) then
        height = gr.getScreenHeight() * height
    end
    self.height = height
end

function HudGauge:setClip()
    if (self.height == nil or self.width == nil) then
        warningf("Can't set clipping region without having size parameters for gauge %q.", self:getName())
        return
    end

    gr.setClip(self.x, self.y, self.width, self.height)

    self.clipped = true
end

function HudGauge:resetClip()
    gr.resetClip()

    self.clipped = false
end

function HudGauge:setupRendering()
    self:__colorSet()

    self.maxX = -1
    self.maxY = -1

    self.lastStringDrawX = -1
    self.lastStringDrawY = -1

    if (self.needsClipping) then
        self:setClip()
    end
end

function HudGauge:doneRendering()
    if (self.needsClipping) then
        self:resetClip()
    end

    if (self.drawBox) then
        self:__colorSet()

        local x1
        local y1

        local x2
        local y2

        if (self.height and self.width) then
            x1 = self.x - self.margin
            y1 = self.y - self.margin

            x2 = self.x + self.width + self.margin
            y2 = self.y + self.height + self.margin
        else
            x1 = self.x - self.margin
            y1 = self.y - self.margin

            x2 = self.maxX + self.margin
            y2 = self.maxY + self.margin

            if (self.needsClipping) then
                -- if clipping is enabled then maxX and maxY are relative coordinates so we need to change those to absolute ones
                x2, y2 = self:__transform(x2, y2)
            end
        end

        gr.drawRectangle(x1, y1, x2, y2, false)
    end
end

function HudGauge:setColor(r, g, b, a)
    if (r) then
        self.r = r
    end

    if (g) then
        self.g = g
    end

    if (b) then
        self.b = b
    end

    if (a) then
        self.a = a
    end

    self:__colorSet()
end

function HudGauge:shouldDraw()
    return true
end

function HudGauge:__colorSet()
    if (self.r ~= nil and self.g ~= nil and self.b ~= nil) then
        if (self.a ~= nil) then
            gr.setColor(self.r, self.g, self.b, self.a)
        else
            gr.setColor(self.r, self.g, self.b)
        end
    end
end

function HudGauge:drawString(string, x, y)
    local width = gr.getStringWidth(string)

    local drawX = -1
    local drawY = -1

    if (self.lastStringDrawX < 0 and not x) then
        x = 0
    elseif (self.lastStringDrawX >= 0 and not x) then
        x = self.lastStringDrawX
    end

    if (self.lastStringDrawY < 0 and not y) then
        y = 0
    elseif (self.lastStringDrawY >= 0 and not y) then
        y = self.lastStringDrawY + gr.CurrentFont.Height
    end

    drawX, drawY = self:__transform(x, y)

    if (drawX + width > self.maxX) then
        self.maxX = drawX + width
    end
    self.lastStringDrawX = x

    if (drawY + gr.CurrentFont.Height > self.maxY) then
        self.maxY = drawY + gr.CurrentFont.Height
    end
    self.lastStringDrawY = y

    gr.drawString(string, drawX, drawY)

    return width
end

function HudGauge:drawStringf(str, x, y, ...)
    local string = string.format(str, ...)

    self:drawString(string, x, y)
end

function HudGauge:drawRectangle(x1, y1, x2, y2, fill)
    local drawX1, drawY1 = self:__transform(x1, y1)
    local drawX2, drawY2 = self:__transform(x2, y2)

    if (drawX1 > self.maxX or drawX2 > self.maxX) then
        self.maxX = math.max(drawX1, drawX2)
    end

    if (drawY1 > self.maxY or drawY2 > self.maxY) then
        self.maxY = math.max(drawY1, drawY2)
    end

    if (fill == nil) then
        fill = true
    end

    gr.drawRectangle(drawX1, drawY1, drawX2, drawY2, fill)
end

function HudGauge:drawCircle(x, y, radius)
    local drawX, drawY = self:__transform(x, y)

    if (drawX + radius > self.maxX) then
        self.maxX = drawX + radius
    end

    if (drawY + radius > self.maxY) then
        self.maxY = drawY + radius
    end

    gr.drawCircle(radius, drawX, drawY)
end

function HudGauge:drawLine(x1, y1, x2, y2)
    local drawX1, drawY1 = self:__transform(x1, y1)
    local drawX2, drawY2 = self:__transform(x2, y2)

    if (drawX1 > self.maxX or drawX2 > self.maxX) then
        self.maxX = math.max(drawX1, drawX2)
    end

    if (drawY1 > self.maxY or drawY2 > self.maxY) then
        self.maxY = math.max(drawY1, drawY2)
    end

    gr.drawLine(drawX1, drawY1, drawX2, drawY2)
end

function HudGauge:drawGradientLine(x1, y1, x2, y2)
    local drawX1, drawY1 = self:__transform(x1, y1)
    local drawX2, drawY2 = self:__transform(x2, y2)

    if (drawX1 > self.maxX or drawX2 > self.maxX) then
        self.maxX = math.max(drawX1, drawX2)
    end

    if (drawY1 > self.maxY or drawY2 > self.maxY) then
        self.maxY = math.max(drawY1, drawY2)
    end

    gr.drawGradientLine(drawX1, drawY1, drawX2, drawY2)
end

function HudGauge:drawTriangle(x1, y1, x2, y2, height)
    local outX1, outY1 = self:__transform(x1, y1)
    local outX2, outY2 = self:__transform(x2, y2)

    lGr.drawTriangle(outX1, outY1, outX2, outY2, height)
end

function HudGauge:drawPixel(x, y)
    local outX, outY = self:__transform(x, y)

    gr.drawPixel(outX, outY)
end
