--[[---------------------------------------------------------------------------------
 locals
------------------------------------------------------------------------------------]]

local Compost           = AceLibrary("Compost-2.0")
local L                 = AceLibrary("AceLocale-2.0"):new("Squishy")
local RL                = AceLibrary("RosterLib-2.0")
local proximity         = ProximityLib:GetInstance("1")

local titlebuttonheight       = 21
local footerheight            = 05
local footerspacer            = 03
local unitframeheight         = 12

local textures = {
	[L["Default"]]	  = "Interface\\AddOns\\Squishy\\textures\\default",
	[L["Smooth"]]	  = "Interface\\AddOns\\Squishy\\textures\\smooth",
	[L["Blizzard"]]   = "Interface\\TargetingFrame\\UI-StatusBar",
}

--[[---------------------------------------------------------------------------------
 stuff
------------------------------------------------------------------------------------]]

function Squishy:GetRaidColors(class)
	if RAID_CLASS_COLORS[class] then
		local color = RAID_CLASS_COLORS[class]
		return color.r, color.g, color.b
	else
		return 0.5, 0.5, 0.5
	end
end


function Squishy:GetHealthColor(pct)
	local pct = floor(pct) / 100
	if pct > .5 then
		return (1-pct)*2, 1, 0
	else
		return 1, pct*2, 0
	end
end


function Squishy:ScreenAlert(percent, msg)
	local r,g,b = self:GetHealthColor(percent)
	self.frames.message:AddMessage(msg, r, g, b, 1)
	self.frames.header:Hide()
	self:CancelScheduledEvent("ResetHeader")
	self:ScheduleEvent("ResetHeader", self.ResetHeader, 3.5, self)
end


function Squishy:ResetHeader()
	self.frames.header:Show()
end


function Squishy:UpdateFrameData(num, u)
	local f = self.frames.units[num]
	f.unit = u.unitid
	
	local pct       = UnitHealth(u.unitid)/UnitHealthMax(u.unitid)*100
	local range,time= proximity:GetUnitRange(u.unitid)
	local lastseen  = GetTime() - (time or 100)
	local alpha     = ( range == 45 and lastseen > 2 and 1 - (lastseen-2)/5 ) or 1
	
	f:SetAlpha(alpha)

	f.Name:SetText(u.name)
	f.Name:SetTextColor(self:GetRaidColors(u.class))

	f.Bar:SetValue(pct)
	local r,g,b = self:GetHealthColor(pct)
	f.Bar:SetStatusBarColor(r,g,b,alpha)
	
	local dmg = UnitHealthMax(u.unitid) - UnitHealth(u.unitid)
	if dmg > 0 and self.OptionHealthDeficit then
		f.Deficit:SetText(0-dmg)
		f.Deficit:Show()
	else
		f.Deficit:Hide()
	end
	
	if self.priority[1].name == u.name then
		f.Status:SetAlpha(1)
		f.Status:SetTextColor(1,0,0)
	elseif u.name == UnitName("player") then
		f.Status:SetAlpha(1)
		f.Status:SetTextColor(1,1,1)
	elseif GetNumRaidMembers() > 0 and UnitInParty(u.unitid) then
		f.Status:SetAlpha(1)
		f.Status:SetTextColor(0.5,0.5,1)
	else
		f.Status:SetAlpha(0)
	end

	if u.healstart and GetTime() - u.healstart < 2 and not u.aggro then 
		f.Prefix:SetText("|cFF00FF00H|r")
	elseif u.healstart and GetTime() - u.healstart < 2 and u.aggro then 
		f.Prefix:SetText("|cFF00FF00H|cFFFF0000A|r")
	elseif u.aggro then 
		f.Prefix:SetText("|cFFFF0000A|r")
	else 
		f.Prefix:SetText("")
	end
--[[	
not working:
	local t = getglobal("SquishyFrameTexture"..num)
	if t then
		if UnitName("target") == u.name then
			t:SetVertexColor(1,1,1,1)
			f:SetNormalTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
			--f:SetButtonState("PUSHED")
		else
			t:SetVertexColor(1,1,1,0)
			--f:SetButtonState("NORMAL")
			f:SetNormalTexture(nil)
		end
	end
]]
	f:Show()
end


function Squishy:UpdateFrameSize(num)
	-- auto-scale emergency frame by number of shown units
	if num == 0 and self.frames.main:GetAlpha() < 0.1 then
		self.frames.main:Hide()
	elseif num == 0 then
		self.frames.main:SetHeight( titlebuttonheight + footerheight )
		self.frames.bg:SetHeight( titlebuttonheight + footerheight )
		self.frames.main:Show()
	else
		self.frames.main:SetHeight( titlebuttonheight + footerheight + footerspacer + ( unitframeheight * num ) )
		self.frames.bg:SetHeight( titlebuttonheight + footerheight + footerspacer + ( unitframeheight * num ) )
		self.frames.main:Show()
	end
end


function Squishy:UpdateVisibilitySquishyFrame()
	self:CancelScheduledEvent("UpdateEmergencyFrame")
	self:CancelScheduledEvent("UpdateAllUnits")
	if not self.frames then return end
	self.showFrame = ( RL.roster[UnitName("player")] and Squishy.db.profile.FrameDisplay == L["always"] or (Squishy.db.profile.FrameDisplay == L["grouped"] and ( GetNumPartyMembers() > 0 or GetNumRaidMembers() > 0 ) ) ) and true or false	
	if self.showFrame then
		self.frames.main:Show()
		self.frames.bg:SetAlpha(Squishy.db.profile.Alpha or 1)
		self:ScaleSquishyFrame(Squishy.db.profile.ScaleSize)
		self:ScheduleRepeatingEvent("UpdateEmergencyFrame", self.UpdateEmergencyFrame, 0.2, self)
		self:ScheduleRepeatingEvent("UpdateAllUnits", self.UpdateAllUnits, 5, self)
	else
		self.frames.main:Hide()
	end
	self.frames.main:EnableMouse(not Squishy.db.profile.FrameLock)
end

function Squishy:CreateFrames()
	-- thanks Cladhaire, this code would never exist without PerfectRaid. 
	-- Well, maybe it would, but it saved me a few hours. :)
	self.frames  = Compost:Acquire()
	self:CreateEmergencyFrame()
	self:CreateEmergencyBackgroundTexture()
	self:CreateHeaderButton()
	self:CreateUnitFrames()
	self:CreateMessageFrame()
	self.frames.main:Hide()
	self.frames.main:SetClampedToScreen(false)
end


function Squishy:CreateEmergencyFrame()
	local f = CreateFrame("Frame", "SquishyFrame", UIParent)
	f:EnableMouse(true)
	f:SetMovable(true)
	f:SetWidth(180)
	f:SetHeight(titlebuttonheight + footerheight)
	f:SetPoint("CENTER", UIParent, "CENTER")
	self.frames.main = f
end


function Squishy:CreateEmergencyBackgroundTexture()
	local bg = CreateFrame("Frame", "SquishyBackground", SquishyFrame)
	bg:SetFrameStrata("BACKGROUND")
	bg:SetWidth(180)
	bg:SetHeight(titlebuttonheight + footerheight)
	bg:SetPoint("CENTER", SquishyFrame, "CENTER")
	bg:SetBackdrop({
		bgFile = "Interface\\ChatFrame\\ChatFrameBackground", tile = true, tileSize = 16,
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 16,
		insets = {left = 4, right = 4, top = 4, bottom = 4},
	})
	bg:SetBackdropBorderColor(.5, .5, .5, 1)
	bg:SetBackdropColor(0,0,0,0.75)
	bg.tfade = bg:CreateTexture(nil, "BORDER")
	bg.tfade:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
	bg.tfade:SetPoint("TOPLEFT", bg, "TOPLEFT", 4, -4)
	bg.tfade:SetPoint("BOTTOMRIGHT", bg, "BOTTOMRIGHT", -4, 4)
	bg.tfade:SetBlendMode("ADD")
	bg.tfade:SetGradientAlpha("VERTICAL", .1, .1, .1, 0, .25, .25, .25, 1)
	self.frames.bg = bg
end


function Squishy:CreateHeaderButton()	-- does this really have to be a button?
	local b = CreateFrame("Button", "SquishyHeader", SquishyFrame)
	b:EnableMouse(true)
	b:SetMovable(true)	-- does the button or the frame need to be movable?
	b:SetWidth(170)
	b:SetHeight(titlebuttonheight)
	b:SetPoint("TOP", "SquishyFrame", "TOP", 0, 0)
	b:SetScript("OnMouseUp", function()
		if SquishyFrame.isMoving then
			self.frames.main:StopMovingOrSizing()
			Squishy:SavePosition()
			self.frames.main.isMoving = false
		end
	end)
	b:SetScript("OnHide", function()
		if SquishyFrame.isMoving then
			self.frames.main:StopMovingOrSizing()
			Squishy:SavePosition()
			self.frames.main.isMoving = false
		end
	end)
	b:SetScript("OnMouseDown", function()
		if not Squishy.db.profile.FrameLock and arg1 == "LeftButton" then
			self.frames.main:StartMoving()
			self.frames.main.isMoving = true
		end
	end)
	
	local font = b:CreateFontString(nil, "ARTWORK")
	font:SetFontObject(GameFontHighlightSmall)
	font:SetText(L["Squishy Emergency"])
	font:SetJustifyH("CENTER")
	font:SetJustifyV("BOTTOM")
	font:SetWidth(170)
	font:SetHeight(12)
	font:Show()
	font:ClearAllPoints()
	font:SetPoint("TOP", "SquishyHeader", "TOP", 0, -6)
	self.frames.header = b
	self.frames.headertext = font
	self.frames.header:SetAlpha(Squishy.db.profile.Alpha)
end


function Squishy:CreateMessageFrame()
	local m = CreateFrame("ScrollingMessageFrame", nil, SquishyFrame)
	m:SetWidth(170)
	m:SetHeight(12)
	m:SetMovable(true)
	m:SetPoint("TOP", "SquishyHeader", "TOP", 0, -6)
	m:SetParent(self.frames.main)
	m:SetFadeDuration(1)
	m:SetTimeVisible(1.5)
	m:SetMaxLines(1)
--	m:SetScrollFromBottom(true)
--	m:EnableFading(true)
	m:SetFontObject(GameFontHighlightSmall)
	self.frames.message = m
end


function Squishy:CreateUnitFrames()
	if not self.frames.units then
		self.frames.units  = Compost:Acquire()
	end
	for i in self.frames.units do
		self.frames.units[i]:Hide()
	end
	for i = 1, self.NumUnits do
		if not self.frames.units[i] then
			local frame = CreateFrame("Button", nil, SquishyFrame)
			frame:Hide()
			frame:EnableMouse(true)
			frame:SetWidth(170)
			frame:SetHeight(unitframeheight)
			frame:SetMovable(true)
			frame:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
			frame:SetScript("OnClick", self.OnClick)
			frame:SetParent(self.frames.main)

			local font = frame:CreateFontString(nil, "ARTWORK")
			font:SetFontObject(GameFontHighlightSmall)
			font:SetText("HA")
			font:SetJustifyH("CENTER")
			font:SetWidth(20)
			font:SetHeight(14)
			font:Show()
			font:ClearAllPoints()
			font:SetPoint("LEFT", frame, "LEFT", 3, 0)
			frame.Prefix = font
		
			font = frame:CreateFontString(nil, "ARTWORK")
			font:SetFontObject(GameFontHighlightSmall)
			font:SetText("DummyName")
			font:SetJustifyH("LEFT")
			font:SetWidth(65)
			font:SetHeight(12)
			font:Show()
			font:ClearAllPoints()
			font:SetPoint("LEFT", frame.Prefix, "RIGHT", 3, 0)
			frame.Name = font
				
			local barBG = CreateFrame("StatusBar", nil, frame)
			barBG:SetStatusBarTexture(textures[self.db.profile.BarTexture])
			barBG:SetMinMaxValues(0,100)
			barBG:ClearAllPoints()
			barBG:SetPoint("LEFT", frame.Name, "RIGHT", 3, 0)
			barBG:SetWidth(60)
			barBG:SetHeight(10)
			barBG:SetFrameLevel(1)
			barBG:SetStatusBarColor(0,0,0)
			barBG:Show()
			frame.BarBG = barBG
		
			local bar = CreateFrame("StatusBar", nil, frame)
			bar:SetStatusBarTexture(textures[self.db.profile.BarTexture])
			bar:SetMinMaxValues(0,100)
			bar:ClearAllPoints()
			bar:SetPoint("LEFT", frame.Name, "RIGHT", 3, 0)
			bar:SetWidth(60)
			bar:SetHeight(10)
			bar:SetFrameLevel(2)
			bar:SetFrameLevel(frame.BarBG:GetFrameLevel() + 1)
			bar:Show()
			frame.Bar = bar
		
			font = bar:CreateFontString(nil, "ARTWORK")
			font:SetFontObject(GameFontHighlightSmall)
			font:SetText("-5000")
			font:SetJustifyH("RIGHT")
			font:SetWidth(45)
			font:SetHeight(12)
			font:Show()
			font:ClearAllPoints()
			font:SetPoint("RIGHT", frame.Bar, "RIGHT", 0, 0)
			frame.Deficit = font
		
			font = frame:CreateFontString(nil, "ARTWORK")
			font:SetFontObject(GameFontHighlightSmall)
			font:SetText("<")
			font:SetTextColor(0.5, 0.5, 1)
			font:SetJustifyH("LEFT")
	--		font:SetWidth(font:GetStringWidth())
			font:SetHeight(12)
			font:Show()
			font:ClearAllPoints()
			font:SetPoint("LEFT", frame.Bar, "RIGHT", 4, 0)
			frame.Status = font
		
			frame:SetNormalTexture(1,1,1,0)
			frame:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
	--		frame:SetPushedTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
		
	--		local t = frame:CreateTexture("SquishyFrameTexture"..i)
	--		t:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
	--		frame:SetNormalTexture(t)
		
			self.frames.units[i] = frame
		end
	end
	
	self.frames.units[1]:SetPoint("TOPLEFT", self.frames.header, "BOTTOMLEFT", 0, 0)
	for i = 2, self.NumUnits do
		self.frames.units[i]:SetPoint("TOPLEFT", self.frames.units[i-1], "BOTTOMLEFT")
	end
end


function Squishy:SetBarTexture(t)
	for i = 1,self.NumUnits do
		self.frames.units[i].Bar:SetStatusBarTexture(textures[t])
	end
end


function Squishy:ScaleSquishyFrame(scale)
	self.frames.main:SetClampedToScreen(false)
	self:SavePosition()
	self.frames.main:SetScale(scale)
	self:RestorePosition()
	self.frames.main:SetClampedToScreen(true)
end


function Squishy:SavePosition()
	local f = self.frames.main
	local x,y = f:GetLeft(), f:GetTop()
	local s = f:GetEffectiveScale()
	x,y = x*s,y*s
	Squishy.db.profile.PosX = x
	Squishy.db.profile.PosY = y
end


function Squishy:RestorePosition()
	local x = Squishy.db.profile.PosX
	local y = Squishy.db.profile.PosY
	if not x or not y then return end
	local f = self.frames.main
	local s = f:GetEffectiveScale()
	x,y = x/s,y/s
	f:ClearAllPoints()
	f:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x, y)
end

