package.loaded["draw"] = nil

require("draw")

CamShader = nil

UIState = {
	showUI = true,
}

BotState = {
	lastMessage = 0,
	cpuBattery = nil,
	cpuBatteryCorrected = nil,
	servoBattery = nil,
	servoBatteryCorrected = nil,
	camfeed = nil,

	viewX = 0,
	viewY = 0,
	viewXSent = 0,
	viewYSent = 0,
	viewLastUpdate = 0,
}

Ping = {
	timeSent = 0,
	latency = "unknown",
	payload = nil,
}

ControllerState = {
	rightX = 0,
	rightY = 0
}

function love.update2()
	local now = love.timer.getTime()
	if now - Ping.timeSent > 5 then
		Ping.payload = ""
		for i = 0, 10 do
			Ping.payload = Ping.payload .. string.char(love.math.random(65, 91))
		end
		Ping.timeSent = now
		love.mqtt.send("command/ping", Ping.payload)
		print("Sending ping")
	end

	BotState.viewX = BotState.viewX + ControllerState.rightX * 0.02
	BotState.viewY = BotState.viewY + ControllerState.rightY * 0.02

	local viewDX, viewDY = math.abs(BotState.viewX - BotState.viewXSent), math.abs(BotState.viewY - BotState.viewYSent)
	if viewDX > 0.01 or viewDY > 0.01 and (now - BotState.viewLastUpdated) >= 0.05 then
		love.mqtt.send("command/set_camera_xy", toJSON({
			x = -BotState.viewX * 0.3 + 0.5,
			y = -BotState.viewY * 0.3 + 0.5
		}))
		BotState.viewXSent = BotState.viewX
		BotState.viewYSent = BotState.viewY
		BotState.viewLastUpdated = now
	end
end

function love.joystickaxis2(joystick, axis, value)
	if axis == 3 then
		ControllerState.rightX = value
	elseif axis == 4 then
		ControllerState.rightY = value
	end
end

-- function love.joystickaxis2(joystick, axis, value)
-- 	if axis == 3 and value ~= ControllerState.viewX then
-- 		ControllerState.viewX = value
-- 		ControllerState.viewChanged = true
-- 	elseif axis == 4 and value ~= ControllerState.viewY then
-- 		ControllerState.viewY = value
-- 		ControllerState.viewChanged = true
-- 	end
-- end

function formatSafe(format, value, ...)
	if value == nil then
		return "unknown"
	end
	return string.format(format, value, ...)
end

function love.load()
	CamShader = love.graphics.newShader("client/camshader.glsl")

	love.graphics.setFont(love.graphics.newFont(20))
	love.window.setFullscreen(true)
	love.mqtt.subscribe("telemetry/#")
end

function love.mqtt.message(topic, payload)
	local oldTime = BotState.lastMessage
	BotState.lastMessage = love.timer.getTime()

	if topic == "telemetry/cpu_battery" then
		BotState.cpuBattery = tonumber(payload)
		BotState.cpuBatteryCorrected = BotState.cpuBattery / 2
	elseif topic == "telemetry/servo_battery" then
		BotState.servoBattery = tonumber(payload)
		BotState.servoBatteryCorrected = BotState.servoBattery / 2
	elseif topic == "telemetry/camfeed" then
		fileData = love.filesystem.newFileData(payload, "camfeed")
		BotState.camfeed = love.graphics.newImage(fileData)
	elseif topic == "telemetry/pong" then
		if payload == Ping.payload then
			local timeReceived = love.timer.getTime()
			Ping.latency = math.floor((timeReceived - Ping.timeSent) * 1000) .. "ms"
		end
	else
		print("Got unknown telemetry at " .. topic)
		BotState.lastMessage = oldTime
	end
end

function love.gamepadpressed2(joystick, button)
	print("Pressed gamepad button " .. button .. " on joystick " .. joystick:getName())
	if button == "back" then
		UIState.showUI = not UIState.showUI
	end
end

function toJSON(arg)
	local t = type(arg)
	if t == "number" then
		return tostring(arg)
	elseif t == "nil" then
		return "null"
	elseif t == "string" then
		return '"' .. arg .. '"'
	elseif t == "boolean" then
		return tostring(arg)
	elseif t == "table" then
		local fields = {}
		for key, value in pairs(arg) do
			fields[#fields+1] = string.format('"%s":%s', key, toJSON(value))
		end
		return '{' .. table.concat(fields, ',') .. '}'
	end
end