local spellMemory,_
local classSpellMemory
local PLAYER_CLASS = select(2,UnitClass("player"))
local spellBook = {}

local function populateSpellBook(specIndex,tabIndex)
	local _,_,offset,numSpells = GetSpellTabInfo(tabIndex)

	for x = offset+1,offset + numSpells do
		local skillType, spellId = GetSpellBookItemInfo(x, BOOKTYPE_SPELL)
		local spellName, spellSubName = GetSpellBookItemName(x, BOOKTYPE_SPELL);
		local name, rank, icon, castTime, minRange, maxRange,otherSpellId = GetSpellInfo(spellId )
		if skillType == "SPELL" then
			local spell = {}
			spell.index = x;
			spell.name = spellName
			spell.subName = spellSubName
			spell.icon = icon
			spell.castTime = castTime
			spell.minRange = minRange
			spell.maxRange = maxRange
			spell.isPassive = IsPassiveSpell(spellId);
			spellBook[specIndex][spellId] = spell						
		end
	end
end

function WhatsNext:GetSpellBook(specIndex, forceRefresh)
	specIndex = specIndex or GetSpecialization() or 1
	
	if not spellBook[specIndex] or forceRefresh then
		spellBook[specIndex]  = {}
		if specIndex == 0 then
			populateSpellBook(0,1)
		else
			local specName = select(2,GetSpecializationInfo(specIndex));
			for i=2, GetNumSpellTabs() do
				local tabName,_,offset,numSpells = GetSpellTabInfo(i)
				if specName == tabName then
					populateSpellBook(specIndex,i)
					do break end
				end
			end
		end
	end
	
	return spellBook[specIndex];
end


local function GetSpellMemory()
	if not spellMemory then
		WhatsNext.db.global.spellMemory = {}
		spellMemory = WhatsNext.db.global.spellMemory
	end
	return spellMemory
end

local function GetClassSpellMemory(class)
	classSpellMemory = GetSpellMemory()[class or PLAYER_CLASS]
	if not classSpellMemory then
		classSpellMemory = {}
		GetSpellMemory()[class or PLAYER_CLASS] = classSpellMemory
	end
	return classSpellMemory
end


function WhatsNext:GetSpellName(spellId)
	local spell = self:GetSpell(spellId)
	return spell and spell.name or select(1,GetSpellInfo(spellId)) or spellId
end

function WhatsNext:GetSpell(spellId)
	local specIndex = GetSpecialization()
	local spell = self:GetSpellBook(specIndex)[spellId]
	if spell then
		return spell;
	end
	

	local numTabs = GetNumSpellTabs()
	for i=1,numTabs do
		spell = self:GetSpellBook(i)[spellId]
		if spell then
			return spell;
		end
	end
	
	return spell
end

local tempSpellID
function WhatsNext:GetSpellID(spellName)
	if tonumber(spellName) then
		return tonumber(spellName)
	end
	
	local specIndex = GetSpecialization()
	
	
	for spellId,spell in pairs(self:GetSpellBook(specIndex)) do
		if spell.name == spellName then
			return spellId
		end
	end

	local numTabs = GetNumSpellTabs()
	for i=1,numTabs do
		for spellId,spell in pairs(self:GetSpellBook(i)) do
			if spell.name == spellName then
				return spellId
			end
		end
	end
	
	if possibleSpellId then
		return possibleSpellId;
	end
	
	possibleSpellId = select(2,GetSpellBookItemInfo(spellName))
	if possibleSpellId then
		return possibleSpellId;
	end
	
	return select(7,GetSpellInfo(spellName))
end

local events = {}
function events:PLAYER_TALENT_UPDATE(unit,spellName,_,lineID,spellID)
	spellBook = {}
end

function events:PLAYER_SPECIALIZATION_CHANGED(unit,spellName,_,lineID,spellID)
	spellBook = {}
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	