local Root = CoolLevelUp;

local Trainer = Root.GetOrNewModule("Trainer");

-- --------------------------------------------------------------------
-- **							 Locals							 **
-- --------------------------------------------------------------------

local EMPTY_TABLE = { };

-- --------------------------------------------------------------------
-- **							Methods							 **
-- --------------------------------------------------------------------

Trainer.GetNumResults = function(self)
	return #self.list;
end

Trainer.GetResultInfo = function(self, index)
	local info = self.list[index] or EMPTY_TABLE;
	return info.name or nil, info.rank or 0, info.tree or nil, info.level or 0;
end

Trainer.ListSkillsAtLevel = function(self, level)
	if not self or not self.list then
		Trainer:OnStart()
	end
	wipe(self.list);

	local myClass = select(2, UnitClass("player"));
	local classDB = Root.Database.Get("trainer", myClass);

	if ( not classDB ) then return; end
	
	local i;
	--[[
	for i=1, #classDB do
		local skillInfo = classDB[i];
		if ( skillInfo.level ) and ( skillInfo.level == level ) then
			tinsert(self.list, skillInfo);
		end
	end]]
	
	for k,v in pairs(classDB) do
		if type(v) == "table" then
			if GetSpecialization() and k == select(2,GetSpecializationInfo(GetSpecialization())) then
				for i = 1, #v do
					local skillInfo = v[i];
					if ( skillInfo.level ) and ( skillInfo.level == level ) then
						tinsert(self.list, skillInfo);
					end
				end
			elseif k == UnitClass("player") then
				for i = 1, #v do
					local skillInfo = v[i];
					if ( skillInfo.level ) and ( skillInfo.level == level ) then
						tinsert(self.list, skillInfo);
					end
				end
			end
		end
	end
	
end

-- --------------------------------------------------------------------
-- **							Handlers							**
-- --------------------------------------------------------------------

Trainer.OnStart = function(self)
	self.list = { };
end

Trainer.OnTrainerVisit = function(self, forceupdate)

	--if IsTradeskillTrainer() then return; end

	-- Reveal all available services by nullifying the filter
	--[[
	local availableStatus   = GetTrainerServiceTypeFilter("available");
	local unavailableStatus = GetTrainerServiceTypeFilter("unavailable");
	local alreadyStatus	 = GetTrainerServiceTypeFilter("used");

	SetTrainerServiceTypeFilter("available", 1);
	SetTrainerServiceTypeFilter("unavailable", 1);
	SetTrainerServiceTypeFilter("used", 1);]]

	-- Expand all (done by default).

		--changed from ExpandTrainerSkillLine(0);

	-- Prepare database update

	local myClass = select(2, UnitClass("player"));
	local classDB = Root.Database.Get("trainer", myClass) or { };

	local wowVersion = select(1, GetBuildInfo());
	local locale = GetLocale()
	if ( not classDB.version ) or ( classDB.version ~= wowVersion ) or ( classDB.locale ~= locale ) or forceupdate then
		wipe(classDB);
		classDB.version = wowVersion;
		classDB.locale = locale
		for i=1,GetNumSpellTabs() do
			local name = GetSpellTabInfo(i) or i
			classDB[name] = {}
			classDB[name].lookup = { };
		end
	end

	-- Now grab infos

	local i, name, rank, category, expanded, classTree;
	--[[
	for i=1, GetNumTrainerServices() do
		name, rank, category, expanded = GetTrainerServiceInfo(i);
		classTree = GetTrainerServiceSkillLine(i);
		_, _, rank = string.find(rank, "(%d+)");
		rank = tonumber(rank) or 0;
		if ( category ~= "header" and classTree ) then
			local reqLevel = GetTrainerServiceLevelReq(i) or 0;
			if ( reqLevel > 0 ) then
				-- Potential skill.
				local lookupString = name.."|"..rank;
				if ( not classDB.lookup[lookupString] ) then
					local num = #classDB+1;
					classDB[num] = {name = name, rank = rank, tree = classTree, level = reqLevel};
					classDB.lookup[lookupString] = num;
				end
			end
		end
	end]]
	--[[
	local i = 1
	while true do
		local spellName, spellSubName = GetSpellBookItemName(i, BOOKTYPE_SPELL)
		if not spellName then
			do break end
		end
		-- use spellName and spellSubName here
		print( spellName, spellSubName, GetSpellBookItemInfo(spellName or index, bookType))
		
		local reqLevel = GetSpellAvailableLevel(i, BOOKTYPE_SPELL)
		
		if reqLevel and reqLevel > 0 then
			local name = spellName
			local rank = 0;
			local lookupString = name.."|"..rank;
			local classTree = ""
			if ( not classDB.lookup[lookupString] ) then
				local num = #classDB+1;
				classDB[num] = {name = name, rank = rank, tree = classTree, level = reqLevel};
				classDB.lookup[lookupString] = num;
			end
		end
		
		i = i + 1
	end]]
	
	for i = 1, GetNumSpellTabs() do
		local tabname, texture, offset, numSpells, isGuild = GetSpellTabInfo(i)
		
		for s = offset + 1, offset + numSpells do
			local spellName, subSpellName = GetSpellBookItemName(s, BOOKTYPE_SPELL)
			
			local reqLevel = GetSpellAvailableLevel(s, BOOKTYPE_SPELL)
			if reqLevel and reqLevel > 0 then
				local name = spellName
				local rank = 0;
				local lookupString = name.."|"..rank;
				local classTree = ""
				if not classDB[tabname] then classDB[tabname] = {lookup = {},} end
				if ( not classDB[tabname].lookup[lookupString] ) then
					local num = #classDB[tabname]+1;
					classDB[tabname][num] = {name = name, rank = rank, tree = classTree, level = reqLevel};
					classDB[tabname].lookup[lookupString] = num;
				end
			end
			--[[
			if subSpellName and subSpellName ~= "" then
				spellName = spellName.." ("..subSpellName..")"
			end
			print(tabname..": "..spellName)]]
		end
	end
	

	-- Terminate database update

	Root.Database.Set("trainer", myClass, classDB);

	-- Restore old filters
	--[[
	SetTrainerServiceTypeFilter("available", availableStatus or 0);
	SetTrainerServiceTypeFilter("unavailable", unavailableStatus or 0);
	SetTrainerServiceTypeFilter("used", alreadyStatus or 0);]]
end

function CLU_test()
	Trainer:OnTrainerVisit(true)
	Trainer:ListSkillsAtLevel(87)
	print("Results: ", Trainer:GetNumResults())
	for i = 1,Trainer:GetNumResults() do
		print(Trainer:GetResultInfo(i))
	end
end