local Tablet = AceLibrary("Tablet-2.0")
local L = Rock("LibRockLocale-1.0"):GetTranslationNamespace("FuBar_ClockFu")

ClockFu = Rock:NewAddon("ClockFu", "LibRockTimer-1.0", "LibRockConfig-1.0", "LibRockDB-1.0", "LibFuBarPlugin-3.0")

ClockFu:SetDatabase("ClockFuDB")
ClockFu:SetDatabaseDefaults('profile', {
	twentyFour = false,
	showSeconds = false,
	localTime = false,
	bothTimes = false,
	bubble = false,
	r = 1,
	g = 1,
	b = 1,
})

ClockFu.version = "2.0." .. string.sub("$Revision: 60070 $", 12, -3)
ClockFu.date = string.sub("$Date: 2008-02-02 19:05:52 -0500 (Sat, 02 Feb 2008) $", 8, 17)
ClockFu:SetFuBarOption('hasIcon', false)
ClockFu:SetFuBarOption('defaultPosition', "RIGHT")
ClockFu:SetFuBarOption('tooltipType', "Tablet-2.0")
ClockFu:SetFuBarOption('hideWithoutStandby', true)

function ClockFu:OnInitialize()
	if GroupCalendar_OnLoad then
		self.db.profile.bubble = true
	end
	
	local optionsTable = {
		name = "FuBar_ClockFu",
		desc = self.notes,
		handler = ClockFu,
		type = 'group',
		args = {
			twentyFour = {
				type = 'toggle',
				name = L["24-hour format"],
				desc = L["Toggle between 12-hour and 24-hour format"],
				get = "IsTwentyFour",
				set = "ToggleTwentyFour",
			},
			seconds = {
				type = 'toggle',
				name = L["Show seconds"],
				desc = L["Show seconds"],
				get = "IsShowingSeconds",
				set = "ToggleShowingSeconds",
			},
			["local"] = {
				type = 'toggle',
				name = L["Local time"],
				desc = L["Toggle between local time and server time"],
				get = "IsLocalTime",
				set = "ToggleLocalTime",
			},
			both = {
				type = 'toggle',
				name = L["Both times"],
				desc = L["Toggle between showing two times or just one"],
				get = "IsBothTimes",
				set = "ToggleBothTimes",
			},
			bubble = {
				type = 'toggle',
				name = L["Show day/night bubble"],
				desc = L["Show the day/night bubble on the upper-right corner of the minimap"],
				get = "IsShowingBubble",
				set = "ToggleShowingBubble",
			},
			color = {
				type = 'color',
				name = COLOR or "Color",
				desc = L["Set the color of the text"],
				get = "GetColor",
				set = "SetColor",
				disabled = function()
					return not ClockFu:IsFuBarTextColored()
				end
			}
		}
	}
	ClockFu:SetConfigTable(optionsTable)
	ClockFu.OnMenuRequest = optionsTable
end

function ClockFu:OnEnable()
	self.timeSinceLastUpdate = 0
	self.secondsDifference = 0
	local _
	_,self.lastMinute = GetGameTime()
	if not self:IsShowingBubble() then
		self.db.profile.bubble = true
		self:ToggleShowingBubble()
	end
	self:AddRepeatingTimer(1, "UpdateFuBarPlugin")
end

function ClockFu:OnDisable()
	if not self:IsShowingBubble() then
		self:ToggleShowingBubble()
		self.db.profile.bubble = not self.db.profile.bubble
	end
end

function ClockFu:GetColor()
	return self.db.profile.r, self.db.profile.g, self.db.profile.b
end

function ClockFu:GetHexColor()
	return string.format("%02x%02x%02x", self.db.profile.r * 255, self.db.profile.g * 255, self.db.profile.b * 255)
end

function ClockFu:SetColor(r, g, b)
	self.db.profile.r = r
	self.db.profile.g = g
	self.db.profile.b = b
	self:UpdateFuBarText()
end

function ClockFu:IsTwentyFour()
	return self.db.profile.twentyFour
end

function ClockFu:ToggleTwentyFour()
	self.db.profile.twentyFour = not self.db.profile.twentyFour
	self:UpdateFuBarPlugin()
	return self.db.profile.twentyFour
end

function ClockFu:IsShowingSeconds()
	return self.db.profile.showSeconds
end

function ClockFu:ToggleShowingSeconds()
	self.db.profile.showSeconds = not self.db.profile.showSeconds
	self:UpdateFuBarPlugin()
	return self.db.profile.showSeconds
end

function ClockFu:IsLocalTime()
	return self.db.profile.localTime
end

function ClockFu:ToggleLocalTime()
	self.db.profile.localTime = not self.db.profile.localTime
	self:UpdateFuBarPlugin()
	return self.db.profile.localTime
end

function ClockFu:IsBothTimes()
	return self.db.profile.bothTimes
end

function ClockFu:ToggleBothTimes()
	self.db.profile.bothTimes = not self.db.profile.bothTimes
	self:UpdateFuBarPlugin()
	return self.db.profile.bothTimes
end

function ClockFu:IsShowingBubble()
	return self.db.profile.bubble
end

function ClockFu:ToggleShowingBubble()
	self.db.profile.bubble = not self.db.profile.bubble
	if not self.db.profile.bubble then
		GameTimeFrame:Hide()
	else
		GameTimeFrame:Show()
	end
	return self.db.profile.bubble
end

function ClockFu:GetLocalOffset()
	if self.localOffset ~= nil then
		return self.localOffset
	end
	local localHour = tonumber(date("%H"))
	local localMinute = tonumber(date("%M"))
	local utcHour = tonumber(date("!%H"))
	local utcMinute = tonumber(date("!%M"))
	local loc = localHour + localMinute / 60
	local utc = utcHour + utcMinute / 60
	self.localOffset = floor((loc - utc) * 2 + 0.5) / 2
	if self.localOffset >= 12 then
		self.localOffset = self.localOffset - 24
	end
	return self.localOffset
end

function ClockFu:GetServerOffset()
	if self.serverOffset ~= nil then
		return self.serverOffset
	end
	local serverHour, serverMinute = GetGameTime()
	local utcHour = tonumber(date("!%H"))
	local utcMinute = tonumber(date("!%M"))
	local ser = serverHour + serverMinute / 60
	local utc = utcHour + utcMinute / 60
	self.serverOffset = floor((ser - utc) * 2 + 0.5) / 2
	if self.serverOffset >= 12 then
		self.serverOffset = self.serverOffset - 24
	elseif self.serverOffset < -12 then
		self.serverOffset = self.serverOffset + 24
	end
	return self.serverOffset
end


function ClockFu:FormatTime(hour, minute, second, colorize)
	if self:IsTwentyFour() then
		if not colorize then
			if self:IsShowingSeconds() then
				return string.format("%d:%02d:%02d", hour, minute, second)
			else
				return string.format("%d:%02d", hour, minute)
			end
		else
			local color = self:GetHexColor()
			if self:IsShowingSeconds() then
				return string.format("|cff%s%d|r:|cff%s%02d|r:|cff%s%02d|r", color, hour, color, minute, color, second)
			else
				return string.format("|cff%s%d|r:|cff%s%02d|r", color, hour, color, minute)
			end
		end
	else
		local pm = floor(hour / 12) == 1
		hour = mod(hour, 12)
		if hour == 0 then
			hour = 12
		end
		if not colorize then
			if self:IsShowingSeconds() then
				return string.format("%d:%02d:%02d %s", hour, minute, second, pm and " PM" or " AM")
			else
				return string.format("%d:%02d %s", hour, minute, pm and " PM" or " AM")
			end
		else
			local color = self:GetHexColor()
			if self:IsShowingSeconds() then
				return string.format("|cff%s%d|r:|cff%s%02d|r:|cff%s%02d|r %s", color, hour, color, minute, color, second, pm and " PM" or " AM")
			else
				return string.format("|cff%s%d|r:|cff%s%02d|r %s", color, hour, color, minute, pm and " PM" or " AM")
			end
		end
	end
end

function ClockFu:GetServerTime(colorize)
	local hour, minute = GetGameTime()
	if self.lastMinute ~= minute then
		local _
		_,self.lastMinute = GetGameTime()
		self.secondsDifference = mod(time(), 60)
	end
	local second = mod(time() - self.secondsDifference, 60)
	return self:FormatTime(hour, minute, second, colorize)
end

function ClockFu:GetLocalTime(colorize)
	local hour = tonumber(date("%H"))
	local minute = tonumber(date("%M"))
	local second = tonumber(date("%S"))
	return self:FormatTime(hour, minute, second, colorize)
end

function ClockFu:GetUtcTime()
	local hour = tonumber(date("!%H"))
	local minute = tonumber(date("!%M"))
	local second = tonumber(date("!%S"))
	return self:FormatTime(hour, minute, second)
end

function ClockFu:OnUpdateFuBarText()
	local hour, minute = GetGameTime()
	if self.lastMinute ~= minute then
		local _
		_,self.lastMinute = GetGameTime()
		self.secondsDifference = mod(time(), 60)
	end
	if self:IsBothTimes() then
		if self:IsLocalTime() then
			self:SetFuBarText(string.format("%s || %s", self:GetLocalTime(true), self:GetServerTime(true)))
		else
			self:SetFuBarText(string.format("%s || %s", self:GetServerTime(true), self:GetLocalTime(true)))
		end
	elseif self:IsLocalTime() then
		self:SetFuBarText(self:GetLocalTime(true))
	else
		self:SetFuBarText(self:GetServerTime(true))
	end
end

function ClockFu:OnUpdateFuBarTooltip()
	local s = self:GetServerOffset()
	local l = self:GetLocalOffset()
	
	local cat = Tablet:AddCategory(
		'columns', 2,
		'child_textR', 1,
		'child_textG', 1,
		'child_textB', 0,
		'child_text2R', 1,
		'child_text2G', 1,
		'child_text2B', 1
	)
	cat:AddLine(
		'text', string.format(L["Local time"] .. " (%+03d:%02d)", l, mod(l * 60, 60)),
		'text2', self:GetLocalTime()
	)
	cat:AddLine(
		'text', string.format(L["Server time"] .. " (%+03d:%02d)", s, mod(s * 60, 60)),
		'text2', self:GetServerTime()
	)
	cat:AddLine(
		'text', L["UTC"],
		'text2', self:GetUtcTime()
	)
	
	local DATE = L["DATE"]
	if type(DATE) == "string" then
		DATE = date(DATE)
	else
		DATE = DATE()
	end
	Tablet:AddCategory():AddLine(
		'text', DATE,
		'textR', 1,
		'textG', 1,
		'textB', 1,
		'justify', "CENTER"
	)
end
