GHU_Trainer = {}
GHU_Trainer.trainers = {};

-- 	standard
function GHU_Trainer:Create(name)
		
	local obj = setmetatable({},{__index = GHU_Trainer});
	
	-- initialize variables
	obj.name = name; -- example
		

	HookObj = obj;
	obj:InitHooks("HookObj");
	HookObj = nil;  


	return obj
end
	
function GHU_Trainer:Hook(funcName,varName)
	
	if not(type(self.orig)=="table") then self.orig ={}; end
	assert(type(self[funcName])=="function","No function found for "..funcName);
	self.orig[funcName] = _G[funcName];
		
	RunScript("local t = _G[\""..varName.."\"); t[\"hooked\"][\""..funcName.."\"] = function(...) gself = _G[\""..varName.."\"); local f = _G[\""..varName.."\"); return f:"..funcName.."(...); end _G[\""..varName.."\"]=t; ");
	_G[funcName]=_G[varName]["hooked"][funcName];
end

function GHU_Trainer:InitHooks(varName)
	if not(self.isHooked) then
		local obj = _G[varName];
		
		-- list of functions to hook
		-- self:Hook("GetTradeSkillLine",varName)
		   self:Hook("GetNumTrainerServices",varName)
		   self:Hook("GetTrainerGreetingText",varName)
		   self:Hook("GetTrainerSelectionIndex",varName)
		   self:Hook("GetTrainerServiceAbilityReq",varName)
		   self:Hook("GetTrainerServiceCost",varName)
		   self:Hook("GetTrainerServiceDescription",varName)
		   self:Hook("GetTrainerServiceIcon",varName)
		   self:Hook("GetTrainerServiceInfo",varName)
		   self:Hook("GetTrainerServiceItemLink",varName)
		   self:Hook("GetTrainerServiceLevelReq",varName)
		   self:Hook("GetTrainerServiceSkillLine",varName)
		   self:Hook("GetTrainerServiceSkillReq",varName)
		   self:Hook("GetTrainerServiceTypeFilter",varName)
		   self:Hook("IsTradeskillTrainer",varName)
		   self:Hook("SetTrainerServiceTypeFilter",varName)
	

				
		self.isHooked = true;
	end
end

-- =================	Control of display  ==============
--[[These functions is used to decide if the quest information from this.
	Quest Log object is being shown, or if the original values is being shown.
	
	When the self.shown value is true, then the hooked function should return 
	the modified value. Otherwise it should return the original function.
--]]
function GHU_Trainer:Show() 
	GHU_Trainer.shown = true;
	--unsure of the update func for this
end

function GHU_Trainer:Hide()
	GHU_Trainer.shown = nil;
	
end

-- =========== Hook functions ==================

function GHU_Trainer:GetNumTrainerServices()
	--called as numServices = GetNumTrainerServices() returns number
	
	self=gself;
	
	if self.shown then
	
		local services = 0;
		
		for i=1,#self.trainers do
		
			if type(self.trainers[i]) == table then
				for x=1,#self.trainers[i] do
					if type(self.trainers[i][x])== table then
						for y=1,#self.trainers[i][x][y] do
							services = y;
						end
					end
				end
			end
		end
	
		return services;
	end
	
	return self.orig.GetNumTrainerServices()
end

function GHU_Trainer:GetTrainerGreetingText()
--akin to gossip text before clicking 'train me',often skipped but useful to have.
self=gself;

if self.shown then

end

return self.orig.GetTrainerGreetingText()

end


function GHU_Trainer:GetTrainerSelectionIndex()
--returns the number index of the selected trainder service(skill)

self=gself;

if self.shown then

end

return self.orig.GetTrainerSelectionIndex()

end

function GHU_Trainer:GetTrainerServiceAbilityReq(trainerIndex,reqIndex)
--[[Gets the name of a requirement for training a skill and whether the player meets the requirement.

local ability, hasReq = GetTrainerServiceAbilityReq(trainerIndex, reqIndex)
this means if a service/skill on the trainer requires you to know another spell it will return the name of the spell
needed and nil
otherwise, nil and 1(meaning no requirment and hasreq is 1)
]]--

self=gself;

if self.shown then
--get slected skill set to refID

if self.trainers[refID][trainerIndex].skillReq ~= nil and self.trainers[refID][trainerIndex].skillRank ~= nil then

--return skill name needed still for next rank and nil,

else
---return nil and 1

end

end

return self.orig.GetTrainerServiceAbilityReq(trainerIndex,reqIndex)

end

function GHU_Trainer:GetTrainerServiceCost(index) --number index
--returns the money cost for the selected service(IE: 2 gold 25 Silver 0 copper would return:22500
self=gself;

if self.shown then
--get slected skill set to refID
return  self.trainers[refID][index].skillCost

end

return self.orig.GetTrainerServiceCost(index)
end

function GHU_Trainer:GetTrainerServiceDescription(index) --number index
--returns a string(long string) of the service/spell at its index detailing what the spell does as it appears
--in its tooltip.
self=gself;

if self.shown then
return self.trainers[refID][index].skillDesc
end

return self.orig.GetTrainerServiceDescription(index)
end

function GHU_Trainer:GetTrainerServiceIcon(id)
--returns the path to the icon used for the skill at id/index
self=gself;

if self.shown then
return self.trainers[refID][index].skillIcon
end

return self.orig.GetTrainerServiceIcon(id)
end

function GHU_Trainer:GetTrainerServiceInfo(id)

--local serviceName, serviceSubText, serviceType, texture, reqLevel = GetTrainerServiceInfo(206)
--req level returns as 0 if not at required level, I THINK
self=gself;

if self.shown then
return self.trainers[refID][id].skillName,self.trainers[refID][id].skillSubTxt,self.trainers[refID][id].skillType,
self.trainers[refID][id].skillIcon,self.trainers[refID][id].skillLvlReq;
end

return self.orig.GetTrainerServiceInfo(id)
end

function GHU_Trainer:GetTrainerServiceItemLink(index) --number index
--returns a link for the item made by service at index NOTE: not all services return a link and may be nil
self=gself;

if self.shown then
---i dunno how this would work.
end

return self.orig.GetTrainerSelectionIndex()
end

function GHU_Trainer:GetTrainerServiceLevelReq(id)

--SHOULD return the required levle to make item at index but returns 0 to me
self=gself;

if self.shown then
return self.trainers[refID][id].skillLvlReq;
end

return self.orig.GetTrainerServiceLevelReq(id)
end

function GHU_Trainer:GetTrainerServiceTypeFilter(Type) -- String - "available" "unavailable" "used"
--returns if the selected filter is checked 1 or nil;
self=gself;

if self.shown then

end

return self.orig.GetTrainerServiceTypeFilter(Type)
end

function GHU_Trainer:IsTradeskillTrainer()
--returns if selected npc,with window up, is a tradeskill trainder.
self=gself;

if self.shown then

return self.trainers[refID][NPCID].isTrade;

end

return self.orig.IsTradeskillTrainer()
end

function GHU_Trainer:SetTrainerServiceTypeFilter(Type,status) -- String - "available"(can learn) "unavailable"(cant learn) "used"(already known)
--status is 1 for on 0 for off.
self=gself;

if self.shown then

end

return self.orig.SetTrainerServiceTypeFilter(Type,status)
end

-- =========== Internal functions ==================



-- =========== API functions ==================
function GHU_Trainer:AddTrainer(refID,NPCID,isTrade)
self = gself;
table.insert(self.trainers[refID],{
		[NPCID] = {
		isTrade=isTrade, --1/nil is tradeskill trianer.
		};
  });
  
  
end

function GHU_Trainer:AddService(refID,NPCID,prof,skillID,skillDesc,skillSubTxt,skillType,skillIcon,skillName,skillRank,skillReq,skillLvlReq,skillCost)
self = gself;
table.insert(self.trainers[refID],{
     [skillID]={
	 skillName=skillName,
	 skillIcon=skillIcon,
	 skillDesc=skillDesc,
	 skillSubTxt=SkillSubTxt,
	 skillType=skillType,
	 skillRank=skillRank,
	 skillReq=skillReq,
	 skillLvlReq=skillLvlReq,
	 skillCost=skillCost,
	 
	 },
	
	
  });
  
  
end
