local dewdrop = DewdropLib:GetInstance('1.0')
local tablet = TabletLib:GetInstance('1.0')
local metro = Metrognome:GetInstance('1')
local compost = CompostLib:GetInstance('compost-1')

ToFu = FuBarPlugin:new({
	name          = ToFuLocals.NAME,
	description   = ToFuLocals.DESCRIPTION,
	version       = "1.1." .. string.sub("$Revision: 1517 $", 12, -3),
	releaseDate   = string.sub("$Date: 2006-05-06 15:13:01 -0700 (Sat, 06 May 2006) $", 8, 17),
	aceCompatible = 103,
	fuCompatible  = 102,
	author        = "Kemayo",
	email         = "kemayo@gmail.com",
	website       = "http://kemayo.wowinterface.com/",
	category      = "others", -- Set this to the appropriate category.
	db            = AceDatabase:new("ToFuDB"),
	defaults      = {
	},
	fullDefaults  = {
		paths = {},
	},
	cmd           = AceChatCmd:new(ToFuLocals.COMMANDS, ToFuLocals.CMD_OPTIONS),
	loc           = ToFuLocals,
	hasIcon       = "Interface\\TaxiFrame\\UI-Taxi-Icon-Green",
	showOnRight   = false,
})

function ToFu:Initialize()
	-- put something that would be run only once, at the start
	-- you can check if self.data.version is a previous version here, and if you do provide adequate steps for backwards-compatibiliy.
	self.start = nil
	self.destination = nil
	self.inFlight = false
	self.timeFlown = 0
	self.last = {}
	if self.fullData.paths[ace.char.faction] == nil then self.fullData.paths[ace.char.faction] = {} end
end

function ToFu:Enable()
	self:RegisterEvent("TAXIMAP_OPENED")
	self:Hook("TakeTaxiNode", "TakeTaxiNode")
	self:Hook("TaxiNodeOnButtonEnter", "TaxiNodeOnButtonEnter")
	metro:Register(self.name, self.OnUpdate, 1, self)
end

function ToFu:Disable()
	metro:Unregister(self.name)
end

function ToFu:UpdateText()
	if self.inFlight then
		if self.fullData.paths[ace.char.faction][self.start][self.destination].time ~= 0 then
			--Time remaining, if we've taken this path before.
			self:SetText(FuBarUtils.FormatDurationCondensed(self.fullData.paths[ace.char.faction][self.start][self.destination].time - self.timeFlown, true))
		else
			--Time flown so far.
			self:SetText(FuBarUtils.FormatDurationCondensed(self.timeFlown, true))
		end
	else
		self:SetText(FuBarUtils.White(self.loc.TEXT_NOTINFLIGHT))
	end
end

function ToFu:UpdateTooltip()
	local cat = tablet:AddCategory('id', 'CURRENT', 'text', self.loc.TOOLTIP_CURRENT)
	if self.inFlight then
		cat:AddLine('text', self.loc.TOOLTIP_FROM .. ": " .. self.start)
		cat:AddLine('text', self.loc.TOOLTIP_TO .. ": " .. self.destination)
		cat:AddLine('text', self.loc.TOOLTIP_TIMEFLOWN .. ": " .. FuBarUtils.FormatDurationCondensed(self.timeFlown, true))
		cat:AddLine('text', self.loc.TOOLTIP_AVERAGETIME .. ": " .. FuBarUtils.FormatDurationCondensed(self.fullData.paths[ace.char.faction][self.start][self.destination].time, true))
		cat:AddLine('text', self.loc.TOOLTIP_COST .. ": " .. FuBarUtils.FormatMoneyCondensed(self.fullData.paths[ace.char.faction][self.start][self.destination].cost, true))
	else
		cat:AddLine('text', self.loc.TOOLTIP_NOTINFLIGHT)
	end
	cat = tablet:AddCategory('id', 'PREVIOUS', 'text', self.loc.TOOLTIP_PREVIOUS)
	if self.last.start ~= nil then
		cat:AddLine('text', self.loc.TOOLTIP_FROM .. ": " .. self.last.start)
		cat:AddLine('text', self.loc.TOOLTIP_TO .. ": " .. self.last.destination)
		cat:AddLine('text', self.loc.TOOLTIP_TIMEFLOWN .. ": " .. FuBarUtils.FormatDurationCondensed(self.last.time, true))
		cat:AddLine('text', self.loc.TOOLTIP_COST .. ": " .. FuBarUtils.FormatMoneyCondensed(self.last.cost, true))
	else
		cat:AddLine('text', self.loc.TOOLTIP_NOPREVIOUSFLIGHT)
	end
	
	if self.inFlight then
		tablet:SetHint(self.loc.HINT)
	end
end

function ToFu:OnClick()
	-- Paste time remaining to chatbox.
	if ChatFrameEditBox:IsVisible() and self.inFlight then
		local text = ""
		if self.fullData.paths[ace.char.faction][self.start][self.destination].time ~= 0 then
			--Time remaining, if we've taken this path before.
			text = FuBarUtils.FormatDurationFull(self.fullData.paths[ace.char.faction][self.start][self.destination].time - self.timeFlown, true)
		else
			--Time flown so far.
			text = string.format("??? (%s %s)", FuBarUtils.FormatDurationFull(self.timeFlown, true), self.loc.TEXT_SOFAR)
		end
		ChatFrameEditBox:Insert(text)
	end
end

function ToFu:OnUpdate(timeSinceLast)
	self.timeFlown = self.timeFlown + timeSinceLast
	if (UnitOnTaxi("player") ~= 1) and (self.timeFlown > 5) then
		-- Cheap test to make sure that we don't do all this right at the beginning of a flight
		metro:Stop(self.name)
		self.inFlight = false
		self.fullData.paths[ace.char.faction][self.start][self.destination].used = self.fullData.paths[ace.char.faction][self.start][self.destination].used + 1
		--Average time this route has taken:
		if self.fullData.paths[ace.char.faction][self.start][self.destination].time ~= 0 then
			self.fullData.paths[ace.char.faction][self.start][self.destination].time = (self.fullData.paths[ace.char.faction][self.start][self.destination].time + self.timeFlown) / 2
		else
			self.fullData.paths[ace.char.faction][self.start][self.destination].time = self.timeFlown
		end
		
		self.last.start = self.start
		self.last.destination = self.destination
		self.last.time = self.timeFlown
		self.last.cost = self.fullData.paths[ace.char.faction][self.start][self.destination].cost
	end
	self:UpdateDisplay()
end

function ToFu:TAXIMAP_OPENED()
	local numNodes = NumTaxiNodes()
	local i = 1
	local slots = compost:Acquire()
	
	-- Have to scan all the slots first to get the "CURRENT" slot.
	while i <= numNodes do
		--local slot = {type=TaxiNodeGetType(i), cost=TaxiNodeCost(i), name=TaxiNodeName(i), position=TaxiNodePosition(i)}
		local slot = compost:AcquireHash('cost',TaxiNodeCost(i), 'name',TaxiNodeName(i))
		if TaxiNodeGetType(i) == "CURRENT" then
			self.start = slot.name
			if self.fullData.paths[ace.char.faction][self.start] == nil then self.fullData.paths[ace.char.faction][self.start] = {} end
		else
			slots[i] = slot
		end
		i = i + 1
	end
	
	for _,path in slots do
		if self.fullData.paths[ace.char.faction][self.start][path.name] == nil then
			self.fullData.paths[ace.char.faction][self.start][path.name] = {cost=path.cost, name=path.name, time=0, used=0}
		else
			self.fullData.paths[ace.char.faction][self.start][path.name].cost = path.cost
		end
	end
	
	compost:Reclaim(slots,1)
end

function ToFu:TakeTaxiNode(slot)
	if TaxiNodeGetType(slot) == "REACHABLE" then
		self.destination = TaxiNodeName(slot)
		self.timeFlown = 0
		self.inFlight = true
		metro:Start(self.name)
	end
	self.Hooks["TakeTaxiNode"].orig(slot)
end

function ToFu:TaxiNodeOnButtonEnter(button)
	self.Hooks["TaxiNodeOnButtonEnter"].orig(button)
	
	local index = button:GetID()
	if TaxiNodeGetType(index) == "REACHABLE" then
		GameTooltip:AddLine("Takes: "..FuBarUtils.FormatDurationCondensed(self.fullData.paths[ace.char.faction][self.start][TaxiNodeName(index)].time), 1, 1, 1)
		GameTooltip:AddLine("Flown "..self.fullData.paths[ace.char.faction][self.start][TaxiNodeName(index)].used.." times", 1, 1, 1)
		GameTooltip:SetHeight(GameTooltip:GetHeight() + 28)
	end
end

function ToFu:DataDump()
	printFull(self.fullData)
	print("start", self.start, "destination", self.destination)
end

function ToFu:ClearData()
	self.fullData.paths[ace.char.faction] = {}
end

ToFu:RegisterForLoad()