Chivato = {}

Chivato.name = "Chivato"

local colors = {
	Gray       = "|cC5C5C5",
	XP 			   = "|c9A2ECE",
	Quest		   = "|c2E64FE",
	Place		   = "|cCC7109",
	Discovery	 = "|cCC7109"
}

-- table with the different reasons the player can get experience
-- Some entries are commented because they have different handling and don't want repetitions
local _XPReason = {}
_XPReason[PROGRESS_REASON_NONE] = "None"  -- do this one happens? I want some !
_XPReason[PROGRESS_REASON_KILL] = "Kill"
--_XPReason[PROGRESS_REASON_QUEST] = "Quest"
--_XPReason[PROGRESS_REASON_COMPLETE_POI] = "Complete POI"
--_XPReason[PROGRESS_REASON_DISCOVER_POI] = "Discover POI"
_XPReason[PROGRESS_REASON_COMMAND] = "Command"
_XPReason[PROGRESS_REASON_KEEP_REWARD] = "Keep Reward"
_XPReason[PROGRESS_REASON_BATTLEGROUND] = "Battleground"
_XPReason[PROGRESS_REASON_SCRIPTED_EVENT] = "Event"
_XPReason[PROGRESS_REASON_MEDAL] = "Medal"
_XPReason[PROGRESS_REASON_FINESSE] = "Finesse"
_XPReason[PROGRESS_REASON_LOCK_PICK] = "Lockpicking"
_XPReason[PROGRESS_REASON_COLLECT_BOOK] = "Reading a book"
_XPReason[PROGRESS_REASON_BOOK_COLLECTION_COMPLETE] = "Completing Book Collection"
_XPReason[PROGRESS_REASON_ACTION] = "Action"
_XPReason[PROGRESS_REASON_GUILD_REP] = "Guild"
_XPReason[PROGRESS_REASON_AVA] = "Ava"
_XPReason[PROGRESS_REASON_TRADESKILL] = "Tradeskill"
_XPReason[PROGRESS_REASON_REWARD] = "Reward"
_XPReason[PROGRESS_REASON_TRADESKILL_ACHIEVEMENT] = "Tradeskill Achievement"
_XPReason[PROGRESS_REASON_TRADESKILL_QUEST] = "Skill Quest"
_XPReason[PROGRESS_REASON_TRADESKILL_CONSUME] = "Consuming"
_XPReason[PROGRESS_REASON_TRADESKILL_HARVEST] = "Harvesting"
_XPReason[PROGRESS_REASON_TRADESKILL_RECIPE] = "Recipe"
_XPReason[PROGRESS_REASON_TRADESKILL_TRAIT] = "Trait"
_XPReason[PROGRESS_REASON_OVERLAND_BOSS_KILL] = "Killing the Boss"
_XPReason[PROGRESS_REASON_ACHIEVEMENT] = "Achievement"
_XPReason[PROGRESS_REASON_BOSS_KILL] = "Killing the Boss"
_XPReason[PROGRESS_REASON_EVENT] = "Event"
_XPReason[PROGRESS_REASON_DARK_ANCHOR_CLOSED] = "Closing a Dark Anchor"
_XPReason[PROGRESS_REASON_DARK_FISSURE_CLOSED] = "Closing a Fissure"
_XPReason[PROGRESS_REASON_SKILL_BOOK] = "Skill Book"
_XPReason[PROGRESS_REASON_OTHER] = "Some Reason"
_XPReason[PROGRESS_REASON_GRANT_REPUTATION] = "Reputation"
_XPReason[PROGRESS_REASON_ALLIANCE_POINTS] = "Alliance Points"
_XPReason[PROGRESS_REASON_PVP_EMPEROR] = "Emperor"
_XPReason[PROGRESS_REASON_DUNGEON_CHALLENGE] = "Dungeon Challenge"


-- show the experience. Right now only in chat
local function PrintXP(color, text)
	-- convert text to string to prevent passing nil arguments to d
	d(color .. tostring(text))
end


-- -----------------------------------------------------------------

-- Generic handler
local function OnXPGain(event, reason, level, prevXP, newXP)
	if _XPReason[reason] ~= nil then
		PrintXP(colors.XP, _XPReason[reason] .. ": +" .. newXP - prevXP .. " " .. _pointType)
	end
end


-- Finish a Quest
local function OnQuestCompleteXP(event, questName, level, prevXP, newXP, rank, prevVP, newVP)
	if _pointType == "VP" then
		xpGain = newVP - prevVP
	else
		xpGain = newXP - prevXP
	end

	PrintXP(colors.Quest, "Completed Quest: " .. questName ..". +" .. xpGain .. " " .. _pointType)
end


-- Complete a subzone or POI
local function OnObjectiveCompleted(event, zoneIndex, poiIndex, level, prevXP, newXP, rank, prevVP, newVP)
	if _pointType == "VP" then
		xpGain = newVP - prevVP
	else
		xpGain = newXP - prevXP
	end

	local objectiveName, objectiveLevel, startDescription, finishedDescription = GetPOIInfo(zoneIndex, poiIndex)

	if (objectiveName ~= nil and objectiveName:len() > 0) then
		PrintXP(colors.Place, "Cleared " .. objectiveName .. ": +" .. xpGain .. " " .. _pointType)
		d("1")
	else
		PrintXP(colors.Place, "POI: +" .. xpGain .. " " .. _pointType)
		d("2")
	end
end

-- discovering new places
local function OnDiscoveryExperienceGain(event, name, level, prevXP, newXP, dos, tres)
	xpGain = newXP - prevXP
	PrintXP(colors.Place, "Discovering experience (" .. name .. "): +" .. xpGain .. " " .. _pointType)
end

-- ------------------------------------------------

local function OnSkillXPUpdate(event, skillType, skillIndex, reason, rank, prevXP, newXP)

	-- Inspiration
	if skillType == SKILL_TYPE_TRADESKILL then
		-- the skill name can be obtained with GetSkillLineInfo
		PrintXP(colors.XP, GetSkillLineInfo(skillType, skillIndex) .. ": +" .. newXP - prevXP .. " inspiration")
	else
		-- non crafting skills
		PrintXP(colors.XP, GetSkillLineInfo(skillType, skillIndex) ..": +".. newXP - prevXP .. " XP")
	end
end

local function OnSkillRankUpdate(event, skillType, skillIndex, rank)
	PrintXP(colors.XP, "New " .. GetSkillLineInfo(skillType, skillIndex) .. " rank: ".. rank)
end

-- Skill Points
local function OnSkillPointsChanged(event, prevSP, newSP, prevPartial, newPartial)
	local _dif = newSP - prevSP
	-- I don't know if you can get or spend more than 1 point at a time, but just in case...
	if _dif ==  1 then
		PrintXP(colors.XP, "You got 1 skillpoint")
	elseif _dif > 1 then
		PrintXP(colors.XP, "You got " .. _dif .. " skillpoints")
	elseif _dif == -1 then
		PrintXP(colors.XP, "You spent 1 skillpoint")
	elseif _dif < -1 then
		PrintXP(colors.XP, "You spent ".. _dif .. " skillpoints")
	else
		-- no change in skillpoints -> collect a skyshard
		PrintXP(colors.XP, "you got a Skyshard: " .. newPartial .. "/3")
	end
end


-- ------------------------------------------------------

local function OnLootReceived(event, lootedBy, item, count, itemSound, lootType, toMe)
	d(colors.Gray .. "Loot received: ( " .. item .. " ) x" .. count)
end
local function OnMoneyUpdate(event, newGold, oldGold, reason)
	if newGold > oldGold then
		d(colors.Gray .. "You got " .. newGold - oldGold .. " gold.")
	elseif newGold < oldGold then
		d(colors.Gray .. "You spent " .. oldGold - newGold .. " gold.")
	end
end


-- debug function. Dumps event arguments to chat
local function test(...)
	d(...)
end


-- -----------------------------------------------------
-- Some events are different between veteran and normal players. Only register the proper ones
function Chivato.RegisterVeteran()
	-- Register veteran only events
	EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_VETERAN_POINTS_GAIN, OnXPGain)
end
function Chivato.RegisterNormal()
	-- Register normal only events
	EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_EXPERIENCE_GAIN, OnXPGain)
end

function Chivato.OnPlayerActivated()
	if (IsUnitVeteran("player")) then
		_pointType = "VP"
		Chivato.RegisterVeteran()
	else
		_pointType = "XP"
		Chivato.RegisterNormal()
	end
end


function Chivato.OnAddOnLoaded(event, addonName)
	if addonName == Chivato.name then
	end
end

-- Finish a Quest
EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_QUEST_COMPLETE, OnQuestCompleteXP)
-- Complete a subzone or POI
EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_OBJECTIVE_COMPLETED, OnObjectiveCompleted)
-- Discovering new places
EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_DISCOVERY_EXPERIENCE, OnDiscoveryExperienceGain)

-- Skill experience
EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_SKILL_XP_UPDATE, OnSkillXPUpdate)
EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_SKILL_RANK_UPDATE, OnSkillRankUpdate)

-- Skill Points
EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_SKILL_POINTS_CHANGED, OnSkillPointsChanged)

-- Loot
EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_LOOT_RECEIVED, OnLootReceived)
EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_MONEY_UPDATE, OnMoneyUpdate)


--- start the magic
EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_ADD_ON_LOADED, Chivato.OnAddOnLoaded)
EVENT_MANAGER:RegisterForEvent(Chivato.name, EVENT_PLAYER_ACTIVATED, Chivato.OnPlayerActivated)