NUiTimer = {}

local function FormatTime(t)
	t = math.max(0, math.floor(t))
	local s = t % 60
	local m = math.floor(t / 60) % 60
	local h = math.floor(t / 3600)
	if h > 0 then
		return string.format("%d:%02d:%02d", h, m, s)
	else
		return string.format("%02d:%02d", m, s)
	end
end

function NUiTimer:SetupUI()
	require("nui-hud")
	self.Active = false
	self:ParseConfig("nui-hud.tbl")
end

function NUiTimer:ParseConfig(file)
	NUi:ParseGeneralSettings(file, self)
	NUi:ParseConfigSection(file, "#Mission Timer Settings", function() self:ConfigMissionTimer() end)
end

function NUiTimer:ConfigMissionTimer()
	local t = { Graphic = {}, Colors = {} }

	if parse.optionalString("$Frame Positioning:") then
		t.Graphic.Frame = NUi:ParseGraphicBlock(self.ScaleFactor)
		t.Graphic.Frame.Position.x = t.Graphic.Frame.Position.x - t.Graphic.Frame.Width / 2
	end

	if parse.optionalString("$Frame Colors:") then
		t.Colors.Frame = NUi:ParseColorBlock()
	else
		t.Colors.Frame = { Mode = "lerp", Colors = {{7, 39, 1, 217}} }
	end

	if parse.optionalString("$Text Color:") then
		local rgba = NUi:GetCSV(parse.getString())
		t.Colors.Text = {rgba[1], rgba[2], rgba[3], rgba[4] or 255}
	else
		t.Colors.Text = {255, 255, 255, 255}
	end

	if parse.optionalString("$Text Offset Y:") then
		t.TextOffsetY = parse.getFloat() * self.ScaleFactor
	else
		t.TextOffsetY = 0
	end

	if parse.optionalString("$Font Scale:") then
		t.FontScale = parse.getFloat() * self.ScaleFactor
	else
		t.FontScale = self.ScaleFactor
	end

	parse.requiredString("#End")
	self.MissionTimer = t
	self.Active = true
end

function NUiTimer:GetTimerTexture(timeStr)
	if self.TimerTexture and self.TimerTextureStr == timeStr then
		return self.TimerTexture
	end

	if self.TimerTexture then
		self.TimerTexture.tex:unload()
		self.TimerTexture = nil
	end

	if not self.TimerFont then return nil end

	gr.CurrentFont = self.TimerFont
	local tw = gr.getStringWidth(timeStr)
	local th = self.TimerFont.Height
	local pad = th
	local texW = tw + pad * 2
	local texH = th + pad * 2

	local tex = gr.createTexture(texW, texH, TEXTURE_STATIC)
	gr.CurrentRenderTarget = tex
	gr.setColor(0, 0, 0, 255)
	gr.drawRectangle(0, 0, texW, texH, true)
	gr.setColor(255, 255, 255, 255)
	gr.CurrentFont = self.TimerFont
	gr.drawString(timeStr, pad, pad)
	gr.CurrentRenderTarget = nil
	tex:destroyRenderTarget()

	self.TimerTexture = { tex = tex, tw = tw, th = th, pad = pad }
	self.TimerTextureStr = timeStr
	return self.TimerTexture
end

function NUiTimer:Draw()
	if not self.Active or not self.MissionTimer then return end
	local mt = self.MissionTimer

	if mt.Graphic.Frame then
		local frameEl = {
			Position   = { x = mt.Graphic.Frame.Position.x, y = mt.Graphic.Frame.Position.y },
			Offset     = { x = mt.Graphic.Frame.Offset[1], y = mt.Graphic.Frame.Offset[2] },
			Dimensions = { Width = mt.Graphic.Frame.Width, Height = mt.Graphic.Frame.Height },
			Image      = mt.Graphic.Frame.File,
			Color      = NUi:ResolveColor(mt.Colors.Frame, 1),
			Direction  = NUi.Direction.RIGHT,
			Percentage = 1
		}
		NUi:DrawHudElement(frameEl)
	end

	if not self.TimerFont then
		for i = 1, #gr.Fonts do
			if gr.Fonts[i].Name == "CommChatMedium" then
				self.TimerFont = gr.Fonts[i]
				break
			end
		end
	end

	local elapsed = math.max(0, mn.getMissionTime())
	local timeStr = FormatTime(elapsed)
	local ne = self:GetTimerTexture(timeStr)
	if ne then
		local fs = mt.FontScale
		local sw, sh, sp = ne.tw * fs, ne.th * fs, ne.pad * fs
		local fp = mt.Graphic.Frame.Position
		local frameCenterX = fp.x + mt.Graphic.Frame.Width / 2
		local tx = frameCenterX - sw / 2
		local ty = fp.y + mt.TextOffsetY
		local tc = mt.Colors.Text
		gr.setColor(tc[1], tc[2], tc[3], tc[4])
		gr.drawImage(ne.tex, tx - sp, ty - sp, tx + sw + sp, ty + sh + sp, 0, 0, 1, 1, 1, true, 0)
	end
end
