

--------------------
-- What's Next? ----
----- by Strucker --
--------------------

local WhatsNext = LibStub('AceAddon-3.0'):NewAddon('WhatsNext', 'AceEvent-3.0', 'AceConsole-3.0');
_G.WhatsNext = WhatsNext;
local SML = LibStub("LibSharedMedia-3.0");
local inCombat = false
WhatsNext.defaultCastSequences = {}

function WhatsNext:OnInitialize()
	self:RegisterOptions()
end

function WhatsNext:ApplyMainSettings()
	local frame = WhatsNext.frame
	if not self.db.profile.enabled or (not inCombat and self.db.profile.hideOutOfCombat) then
		frame:Hide()
	else
		frame:Show()
	end
	frame:EnableMouse(not self.db.profile.locked)
	frame:ClearAllPoints()
	local color = self.db.profile.backgroundColor
	frame.bg:SetTexture(color.r,color.g,color.b,color.a)
	
	
	frame:SetScale(self.db.profile.scale)
	
	
	local scale = frame:GetEffectiveScale()
	local pos = self.db.profile.pos
	frame:SetPoint(pos.p1,nil,pos.p2,pos.x/scale,pos.y/scale)
	scale = WhatsNext_CastLogicDisplay:GetEffectiveScale()
	pos = self.db.profile.configPos
	WhatsNext_CastLogicDisplay:ClearAllPoints()
	WhatsNext_CastLogicDisplay:SetPoint(pos.p1,nil,pos.p2,pos.x/scale,pos.y/scale)
	WhatsNext_CastBlockEditDisplay:ClearAllPoints()
	WhatsNext_CastBlockEditDisplay:SetPoint(pos.p1,nil,pos.p2,pos.x/scale,pos.y/scale)
	frame:UpdateLayout()
	
	
	color = self.db.profile.textColor
	frame.spellName:SetFont(SML:Fetch('font', self.db.profile.font), 16, self.db.profile.outline)
	frame.spellName:SetTextColor(color.r, color.g, color.b, color.a)
	
	
	local _, englishClass = UnitClass("player");
	self.castSequence = nil
	if self.db.profile.castSequences[englishClass] then
		self.castSequence = self.db.profile.castSequences[englishClass][GetSpecialization()]
	end
	self:ApplyExtensionSettings()
end

function WhatsNext_Display_Update(frame)
	local time = GetTime()
	if not frame.lastUpdate  or frame.lastUpdate + WhatsNext.db.profile.timeBetweenUpdates <= time then
		WhatsNext.next, WhatsNext.timeTill = WhatsNext:GetNextCast()
		if WhatsNext.next ~= frame.lastNext then
			if WhatsNext.next ~= "" then
				local _,_,icon = GetSpellInfo(WhatsNext.next)
				frame.spellName:SetText(WhatsNext.next)
				frame.icon:SetTexture(icon)
			else
				frame.spellName:SetText("What's Next?")
				frame.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
				frame.icon:SetTexCoord(0,1,0,1)
			end
			frame:UpdateWidth()
			frame.lastNext = WhatsNext.next
			WhatsNext:FireNextSpellChanged()
		end
		frame.castTime = WhatsNext.timeTill and WhatsNext.timeTill + time or 1.5
		frame.lastUpdate = time
		
		WhatsNext:FireNextSpellChanged()
	end
	
	frame:UpdateBorderColor(frame.castTime and frame.castTime - time or 1.5)
end
		
function LogicBlockFromString(logicBlockString)

	local func, errors = loadstring("return "..logicBlockString)
	if func then
		local logicBlock = func()
		if logicBlock then
			return logicBlock
		else
			print("No logicBlock", errors)
		end
	else
		print("No func", errors)
	end
	return {}
end
				
function WhatsNext:GetNextCast()
	self:ResetTestChecks()
	local tempTimeTillCast, timeTillCast, nextCast, start, duration = nil, 1.61, ""
	if self.castSequence then
		for i,spellEntry in ipairs(self.castSequence) do
			start, duration = GetSpellCooldown(spellEntry.spell)
			tempTimeTillCast = not start and 99 or start == 0 and 0 or start + duration - GetTime()
			if IsUsableSpell(spellEntry.spell) and tempTimeTillCast + .1 < timeTillCast and IsSpellInRange(spellEntry.spell,"target") ~= 0 and self:TestChecks(spellEntry.checks) then
				nextCast, timeTillCast = spellEntry.spell, tempTimeTillCast			
				if timeTillCast <= .1 then 
					break
				end
			end
		end	
	end
	return nextCast, timeTillCast
end

-------------------
-- Set up events
-------------------

local events = {}
function events:PLAYER_REGEN_ENABLED() 
	inCombat = false
	if WhatsNext.db.profile.hideOutOfCombat then
		WhatsNext.frame:Hide()
	end
end

function events:PLAYER_REGEN_DISABLED() 
	inCombat = true
	if WhatsNext.db.profile.enabled then
		WhatsNext.frame:Show()
	end
end

function events:PLAYER_LOGIN()
	WhatsNext:ApplyMainSettings()
end

function events:PLAYER_SPECIALIZATION_CHANGED()
	WhatsNext:ApplyMainSettings()
end

local function EventFunc(self, event, ...)
	events[event](event, ...)
end
local eventHandler = CreateFrame("Frame", nil, WorldFrame)
eventHandler:SetScript("OnEvent", EventFunc)
for eventname in pairs(events) do eventHandler:RegisterEvent(eventname) end	