--[[ oCastingBar
	Hello Mr. Localizer / Bug fixer,
	
	If you want to localize this add on, feel free to send me a diff/patch on troeks@gmail.com.
	Don't commit however, since that puts me out of control regarding changes, and it's very
	common that the add on breaks with  syntax errors or incorrectly added externals.
	
	I'm very tired of thsi happening, so the consequences of this will be that I removed the
	add on from the SVN as people think they can tinker with everything without asking.
	
	This is the final warning.
	
	(This also yields for every other type of commit that effects this add on.)
]]
local delay, holdTime, fadeOut = 0

--[[ UNIT_SPELLCAST_SUCCEEDED
		a1: "player"
		a2: spell
		a3: rank
]]
function oCB:CastSucceeded(a1, a2, a3)
	if(a1 ~= "player") then return end

	if(self.frames.CastingBar:IsShown() and self.casting) then
		local c = self.db.profile.Colors.Complete
		self.frames.CastingBar.Spark:Hide()
		self.frames.CastingBar.Time:Hide()
		self.frames.CastingBar.Bar:SetValue(self.maxValue)
		
		if ( AceLibrary("AceEvent-2.0").currentEvent == "UNIT_SPELLCAST_STOP" ) then
			self.frames.CastingBar.Bar:SetStatusBarColor(c.r, c.g, c.b)
			self.casting = nil
		end
		
		fadeOut = 1
		holdTime = 0
	end
end

--[[ UNIT_SPELLCAST_START
	a1: unit
]]
function oCB:CastStart(a1)
	if(a1 ~= "player") then return end
	
	local name, nameSubtext, text, texture, startTime, endTime = UnitCastingInfo("player")
	if(not name) then return end
	local c = self.db.profile.Colors.Casting
	
	self.frames.CastingBar.Bar:SetStatusBarColor(c.r, c.g, c.b)
	
	self.startTime = startTime / 1000
	self.maxValue = endTime / 1000
	
	self.frames.CastingBar.Bar:SetStatusBarColor(c.r, c.g, c.b)
	self.frames.CastingBar.Bar:SetMinMaxValues(self.startTime, self.maxValue )
	self.frames.CastingBar.Bar:SetValue(self.startTime)
	self.frames.CastingBar.Spell:SetText(text)
	self.frames.CastingBar:SetAlpha(1)
	self.frames.CastingBar.Time:SetText("")
	
	holdTime 		= 0
	delay 			= 0
	self.casting 		= 1
	self.channeling 	= nil
	fadeOut 		= nil
	
	self.frames.CastingBar:Show()
	self.frames.CastingBar.Time:Show()
	self.frames.CastingBar.Spark:Show()
end

--[[ UNIT_SPELLCAST_FAILED / UNIT_SPELLCAST_INTERRUPTED
	a1: unit
]]
function oCB:CastFailed(a1)
	if(a1 ~= "player") then return end

	if ( self.frames.CastingBar:IsShown() and not self.channeling ) then
		local c = self.db.profile.Colors.Failed
		self.frames.CastingBar.Bar:SetValue(self.maxValue)
		self.frames.CastingBar.Bar:SetStatusBarColor(c.r, c.g, c.b)
		self.frames.CastingBar.Spark:Hide()
		
		if (AceLibrary("AceEvent-2.0").currentEvent == "UNIT_SPELLCAST_FAILED") then
			self.frames.CastingBar.Spell:SetText(FAILED)
		else
			self.frames.CastingBar.Spell:SetText(INTERRUPTED)
		end
		
		self.casting 		= nil
		self.channeling 	= nil
		fadeOut			= 1
		holdTime 		= GetTime() + 1
	end
end

--[[ UNIT_SPELLCAST_DELAYED
	a1: unit
]]
function oCB:CastDelayed(a1)
	if(a1 ~= "player") then return end
	if(self.frames.CastingBar:IsShown()) then
		local _, _, _, _, startTime, endTime, _, oldStart = UnitCastingInfo("player")
		
		oldStart = self.startTime
		self.startTime = startTime / 1000
		self.maxValue = endTime / 1000
		delay = (delay or 0) + (self.startTime-oldStart)
		self.frames.CastingBar.Bar:SetMinMaxValues(self.startTime, self.maxValue)
	end
end

--[[ UNIT_SPELLCAST_CHANNEL_START
	a1: unit
]]
function oCB:ChannelStart(a1)
	if(a1 ~= "player") then return end
	
	local name, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo("player")
	local c = self.db.profile.Colors.Channel
	
	self.startTime = startTime / 1000
	self.endTime = endTime / 1000
	self.duration = self.endTime - self.startTime
	self.maxValue = self.startTime
	
	self.frames.CastingBar.Bar:SetStatusBarColor(c.r, c.g, c.b)
	self.frames.CastingBar.Bar:SetMinMaxValues(self.startTime, self.endTime)
	self.frames.CastingBar.Bar:SetValue(self.endTime)
	self.frames.CastingBar.Spell:SetText(text)
	self.frames.CastingBar.Time:SetText("")
	self.frames.CastingBar.Delay:SetText("")
	self.frames.CastingBar:SetAlpha(1.0)
	
	delay 			= 0
	holdTime 		= 0
	self.casting		= nil
	self.channeling 	= 1
	fadeOut 		= nil
	
	self.frames.CastingBar:Show()
	self.frames.CastingBar.Spark:Show()
end

--[[ UNIT_SPELLCAST_CHANNEL_UPDATE
	a1: unit
]]
function oCB:ChannelUpdate(a1)
	if(a1 ~= "player") then return end

	if(self.frames.CastingBar:IsShown()) then
		local spell, _, _, _, startTime, endTime = UnitCastingInfo("player");
		
		if (not spell) then
			self.frames.CastingBar:Hide()
			return
		end
		self.startTime = startTime / 1000
		self.endTime = endTime / 1000
		self.maxValue = self.startTime
		delay = (delay or 0) + (self.startTime-oldStart)
		self:SetMinMaxValues(self.startTime, self.endTime)
	end
end

--[[ UNIT_SPELLCAST_CHANNEL_STOP
	a1: unit
]]
function oCB:ChannelStop(a1)
	if(a1 ~= "player") then return end
	if(self.frames.CastingBar:IsShown()) then
		self.frames.CastingBar.Spark:Hide()
		self.frames.CastingBar.Time:Hide()
		self.frames.CastingBar.Bar:SetValue(self.maxValue)
		
		self.channeling = nil
		fadeOut = 1
		holdTime = 0
	end
end

function oCB:OnCasting()
	if ( oCB.casting ) then
		local status = GetTime()
		if ( status > oCB.maxValue ) then
			status = oCB.maxValue
		end
		if ( status == oCB.maxValue ) then
			local c = oCB.db.profile.Colors.Complete
			oCB.frames.CastingBar.Bar:SetStatusBarColor(c.r, c.g, c.b)
			oCB.frames.CastingBar.Bar:SetValue(oCB.maxValue)
			oCB.frames.CastingBar.Spark:Hide()
			oCB.casting = nil
			fadeOut = 1
			return
		end
		oCB.frames.CastingBar.Bar:SetValue(status)
		local sparkPosition = ((status - oCB.startTime) / (oCB.maxValue - oCB.startTime)) * oCB.frames.CastingBar.Bar:GetWidth()
		if ( sparkPosition < 0 ) then
			sparkPosition = 0
		end
		oCB.frames.CastingBar.Spark:SetPoint("CENTER", oCB.frames.CastingBar.Bar, "LEFT", sparkPosition, 0)
		if (delay > 0) then
			oCB.frames.CastingBar.Delay:SetText(string.format("+%.1f", delay ))
		else 
			oCB.frames.CastingBar.Delay:SetText("")
		end
		oCB.frames.CastingBar.Time:SetText(string.format( "%.1f", math.max(oCB.maxValue - status, 0.0)))
	elseif ( oCB.channeling ) then
		local time = GetTime()
		if ( time > oCB.endTime ) then
			time = oCB.endTime
		end
		if ( time == oCB.endTime ) then
			local c = oCB.db.profile.Colors.Complete
			oCB.frames.CastingBar.Bar:SetStatusBarColor(c.r, c.g, c.b)
			oCB.frames.CastingBar.Spark:Hide()
			oCB.channeling = nil
			fadeOut = 1
			return
		end
		if (delay > 0) then
			oCB.frames.CastingBar.Delay:SetText(string.format("+%.1f", delay ))
		else 
			oCB.frames.CastingBar.Delay:SetText("")
		end
		local barValue = oCB.startTime + (oCB.endTime - time)
		oCB.frames.CastingBar.Bar:SetValue( barValue )
		local sparkPosition = ((barValue - oCB.startTime) / (oCB.endTime - oCB.startTime)) * oCB.frames.CastingBar.Bar:GetWidth()
		oCB.frames.CastingBar.Spark:SetPoint("CENTER", oCB.frames.CastingBar.Bar, "LEFT", sparkPosition, 2)
	elseif ( GetTime() < holdTime ) then
		return
	elseif ( fadeOut ) then
		local alpha = oCB.frames.CastingBar:GetAlpha() - 0.05
		if ( alpha > 0 ) then
			oCB.frames.CastingBar:SetAlpha(alpha)
		else
			fadeOut = nil
			oCB.frames.CastingBar:Hide()
		end
	end
end

