GladiatorlosSA = LibStub("AceAddon-3.0"):NewAddon("GladiatorlosSA", "AceEvent-3.0","AceConsole-3.0","AceTimer-3.0")

local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local AceConfig = LibStub("AceConfig-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("GladiatorlosSA")
local self , GladiatorlosSA = GladiatorlosSA , GladiatorlosSA
local GSA_TEXT= "GladiatorlosSA"
local GSA_VERSION= " r410.01"
local GSA_AUTHOR= " updated by superk"
local GSA_LOCALEPATH = {
	enUS = "Voice_enUS",
	zhTW = "Voice",
	zhCN = "Voice"
}
local GSA_LANGUAGE = {
	Voice = L["漢語(女聲)"],
	Voice_enUS = L["英語(女聲)"],
}
local gsadb
local PlaySoundFile = PlaySoundFile
local dbDefaults = {
	profile = {
		all = false,
		arena = true,
		battleground = true,
		field = true,
		path = GSA_LOCALEPATH[GetLocale()] or "Voice_enUS",
		
		aruaApplied = false,
		aruaRemoved = false,
		castStart = false,
		castSuccess = false,
		interrupt = false,
		
		onlyTarget = false,
		class = false,

		thorns = false,
		desh = false,
		waterShield = false,
		lichborneDown = false,
		iceboundFortitudeDown = false,
		onlySelf = false,
		bindElemental = false,
		ringOfFrost = false,
	}	
}

local function log(msg) DEFAULT_CHAT_FRAME:AddMessage(msg) end

function GladiatorlosSA:OnInitialize()
	if not self.spellList then
		self.spellList = self:GetSpellList()
	end
	for _,v in pairs(self.spellList) do
		for _,spell in pairs(v) do
			if dbDefaults.profile[spell] == nil then dbDefaults.profile[spell] = true end
		end
	end
	
	self.db1 = LibStub("AceDB-3.0"):New("GladiatorlosSADB",dbDefaults, "Default");
	DEFAULT_CHAT_FRAME:AddMessage(GSA_TEXT .. GSA_VERSION .. GSA_AUTHOR .."  - /gsa ");
	--LibStub("AceConfig-3.0"):RegisterOptionsTable("GladiatorlosSA", GladiatorlosSA.Options, {"GladiatorlosSA", "SS"})
	self:RegisterChatCommand("GladiatorlosSA", "ShowConfig")
	self:RegisterChatCommand("gsa", "ShowConfig")
	self.db1.RegisterCallback(self, "OnProfileChanged", "ChangeProfile")
	self.db1.RegisterCallback(self, "OnProfileCopied", "ChangeProfile")
	self.db1.RegisterCallback(self, "OnProfileReset", "ChangeProfile")
	gsadb = self.db1.profile
	GladiatorlosSA.options = {
		name = "GladiatorlosSA",
		desc = L["PVP技能語音提示"],
		type = 'group',
		icon = [[Interface\Icons\Spell_Nature_ForceOfNature]],
		args = {},
	}
	local bliz_options = CopyTable(GladiatorlosSA.options)
	bliz_options.args.load = {
		name = L["加載配置"],
		desc = L["加載配置選項"],
		type = 'execute',
		func = "ShowConfig",
		handler = GladiatorlosSA,
	}
	LibStub("AceConfig-3.0"):RegisterOptionsTable("GladiatorlosSA_bliz", bliz_options)
	AceConfigDialog:AddToBlizOptions("GladiatorlosSA_bliz", "GladiatorlosSA")
end
function GladiatorlosSA:OnEnable()
	GladiatorlosSA:RegisterEvent("PLAYER_ENTERING_WORLD")
	GladiatorlosSA:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
end
function GladiatorlosSA:OnDisable()
end
local function initOptions()
	if GladiatorlosSA.options.args.general then
		return
	end

	GladiatorlosSA:OnOptionsCreate()

	for k, v in GladiatorlosSA:IterateModules() do
		if type(v.OnOptionsCreate) == "function" then
			v:OnOptionsCreate()
		end
	end
	AceConfig:RegisterOptionsTable("GladiatorlosSA", GladiatorlosSA.options)
end
function GladiatorlosSA:ShowConfig()
	initOptions()
	AceConfigDialog:Open("GladiatorlosSA")
end
function GladiatorlosSA:ChangeProfile()
	gsadb = self.db1.profile
	for k,v in GladiatorlosSA:IterateModules() do
		if type(v.ChangeProfile) == 'function' then
			v:ChangeProfile()
		end
	end
end
function GladiatorlosSA:AddOption(key, table)
	self.options.args[key] = table
end

local function setOption(info, value)
	local name = info[#info]
	gsadb[name] = value
end
local function getOption(info)
	local name = info[#info]
	return gsadb[name]
end
local function spellOption(order, spellID, ...)
	return {
		type = 'toggle',
		name = GetSpellInfo(spellID),									
		desc = function () 
			GameTooltip:SetHyperlink(GetSpellLink(spellID));
			--GameTooltip:Show();
		end,
		descStyle = "custom",
		order = order,
	}
end
local function listOption(spellList, listType, ...)
	local args = {}
	for k,v in pairs(spellList) do
		rawset (args, self.spellList[listType][v] ,spellOption(k, v))
	end
	return args
end
function GladiatorlosSA:OnOptionsCreate()
	
	self:AddOption("profiles", LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db1))
	self.options.args.profiles.order = -1
	self:AddOption('genaral', {
		type = 'group',
		name = L["一般"],
		desc = L["一般選項"],
		set = setOption,
		get = getOption,
		order = 1,
		args = {
			enableArea = {
				type = 'group',
				inline = true,
				name = L["當何時啟用"],
				order = 1,
				args = {
					all = {
						type = 'toggle',
						name = L["總是啟用"],
						desc = L["在任何地方GladiatorlosSA都處於開啟狀態"],
						order = 1,
					},
					arena = {
						type = 'toggle',
						name = L["競技場"],
						desc = L["在競技場中啟用GladiatorlosSA"],
						disabled = function() return gsadb.all end,
						order = 2,
					},
					battleground = {
						type = 'toggle',
						name = L["戰場"],
						desc = L["在戰場中啟用GladiatorlosSA"],
						disabled = function() return gsadb.all end,
						order = 3,
					},
					field = {
						type = 'toggle',
						name = L["野外"],
						desc = L["除了戰場、競技場和副本的任何地方都啟用GladiatorlosSA"],
						disabled = function() return gsadb.all end,
						order = 4,
					}
				},
			},
			voice = {
				type = 'group',
				inline = true,
				name = L["聲音設置"],
				order = 1,
				args = {
					path = {
						type = 'select',
						name = L["語言類型"],
						desc = L["選擇通報所用語音"],
						values = GSA_LANGUAGE,
						order = 1,
					},
				},
			},
		}
	})
	self:AddOption('spell', {
		type = 'group',
		name = L["技能"],
		desc = L["技能選項"],
		set = setOption,
		get = getOption,
		order = 2,
		args = {
			spellGeneral = {
				type = 'group',
				name = L["技能模組控制"],
				desc = L["技能各個模組禁用選項"],
				inline = true,
				order = -1,
				args = {
					aruaApplied = {
						type = 'toggle',
						name = L["禁用敵方增益技能"],
						desc = L["勾選此選項以關閉敵方增益型技能通報"],
						order = 1,
					},
					aruaRemoved = {
						type = 'toggle',
						name = L["禁用敵方增益結束"],
						desc = L["勾選此選項以關閉敵方增益結束通報"],
						order = 2,
					},
					castStart = {
						type = 'toggle',
						name = L["禁用敵方讀條技能"],
						desc = L["勾選此選項以關閉敵方對友方讀條技能通報"],
						order = 3,
					},
					castSuccess = {
						type = 'toggle',
						name = L["禁用敵方有害技能"],
						desc = L["勾選此選項以關閉敵方對友方有害技能通報"],
						order = 4,
					},
					interrupt = {
						type = 'toggle',
						name = L["禁用友方打斷技能"],
						desc = L["勾選此選項以關閉友方對敵方打斷技能成功的通報"],
						order = 5,
					}
				},
			},
			spellAuraApplied = {
				type = 'group',
				--inline = true,
				name = L["敵方增益技能"],
				disabled = function() return gsadb.aruaApplied end,
				order = 1,
				args = {
					onlyTarget = {
						type = 'toggle',
						name = L["僅目標獲得時啟用"],
						desc = L["僅當敵對增益法術在你的目標身上時才啟用語音提示"],
						order = 1,
					},
					class = {
						type = 'toggle',
						name = L["徽章職業提示"],
						desc = L["在競技場中,通報徽章的同時提示使用徽章的職業"],
						disabled = function() return not gsadb.trinket end,
						order = 2,
					},
					general = {
						type = 'group',
						inline = true,
						name = L["通用技能"],
						order = 3,
						args = listOption({42292,20594,7744},"auraApplied"),
					},
					druid = {
						type = 'group',
						inline = true,
						name = L["|cffFF7D0A德魯伊|r"],
						order = 4,
						args = listOption({467,61336,29166,22812,17116,16689,22842,5229,1850,50334},"auraApplied"),	
					},
					paladin = {
						type = 'group',
						inline = true,
						name = L["|cffF58CBA聖騎士|r"],
						order = 5,
						args = listOption({31821,1022,1044,642,6940,70940,54428,85696},"auraApplied"),
					},
					rogue = {
						type = 'group',
						inline = true,
						name = L["|cffFFF569盜賊|r"],
						order = 6,
						args = listOption({51713,2983,31224,13750,5277,74001},"auraApplied"),
					},
					warrior	= {
						type = 'group',
						inline = true,
						name = L["|cffC79C6E戰士|r"],
						order = 7,
						args = listOption({55694,871,18499,20230,23920,12328,46924,85730,12292,1719},"auraApplied"),	
					},
					preist	= {
						type = 'group',
						inline = true,
						name = L["|cffFFFFFF牧師|r"],
						order = 8,
						args = listOption({33206,37274,6346,47585,89485},"auraApplied"),
					},
					shaman	= {
						type = 'group',
						inline = true,
						name = L["|cff0070DE薩滿|r"],
						order = 9,
						args = listOption({30823,974,16188,52127},"auraApplied"),
					},
					mage = {
						type = 'group',
						inline = true,
						name = L["|cff69CCF0法師|r"],
						order = 10,
						args = listOption({45438,12042,12472},"auraApplied"),
					},
					dk	= {
						type = 'group',
						inline = true,
						name = L["|cffC41F3B死亡騎士|r"],
						order = 11,
						args = listOption({49039,48792,55233,49016},"auraApplied"),
					},
					hunter = {
						type = 'group',
						inline = true,
						name = L["|cffABD473獵人|r"],
						order = 12,
						args = listOption({34471,19263},"auraApplied"),
					},
				},
			},
			spellAuraRemoved = {
				type = 'group',
				--inline = true,
				name = L["敵方增益結束"],
				disabled = function() return gsadb.aruaRemoved end,
				order = 2,
				args = {
					paladin = {
						type = 'group',
						inline = true,
						name = L["|cffF58CBA聖騎士|r"],
						order = 4,
						args = listOption({1022,642},"auraRemoved"),
					},
					rogue = {
						type = 'group',
						inline = true,
						name = L["|cffFFF569盜賊|r"],
						order = 5,
						args = listOption({31224,5277,74001},"auraRemoved"),
					},
					warrior	= {
						type = 'group',
						inline = true,
						name = L["|cffC79C6E戰士|r"],
						order = 6,
						args = listOption({871},"auraRemoved"),
					},
					preist	= {
						type = 'group',
						inline = true,
						name = L["|cffFFFFFF牧師|r"],
						order = 7,
						args = listOption({33206,47585},"auraRemoved"),
					},
					mage = {
						type = 'group',
						inline = true,
						name = L["|cff69CCF0法師|r"],
						order = 9,
						args = listOption({45438},"auraRemoved"),
					},
					dk = {
						type = 'group',
						inline = true,
						name = L["|cffC41F3B死亡騎士|r"],
						order = 10,
						args = listOption({48792,49039},"auraRemoved"),
					},
					hunter = {
						type = 'group',
						inline = true,
						name = L["|cffABD473獵人|r"],
						order = 12,
						args = listOption({34471,19263},"auraRemoved"),
					},
				},
			},
			spellCastStart = {
				type = 'group',
				--inline = true,
				name = L["敵方讀條技能"],
				disabled = function() return gsadb.castStart end,
				order = 2,
				args = {
					general = {
						type = 'group',
						inline = true,
						name = L["通用技能"],
						order = 2,
						args = {
							bigHeal = {
								type = 'toggle',
								name = L["大型治療法術"],
								desc = L["強效治療術 神聖之光 強效治療波 治療之觸"],
								order = 1,
							},
							resurrection = {
								type = 'toggle',
								name = L["復活技能"],
								desc = L["復活術 救贖 先祖之魂 復活"],
								order = 2,
							},
						}
					},
					druid = {
						type = 'group',
						inline = true,
						name = L["|cffFF7D0A德魯伊|r"],
						order = 3,
						args = listOption({2637,33786},"castStart"),
					},
					preist	= {
						type = 'group',
						inline = true,
						name = L["|cffFFFFFF牧師|r"],
						order = 6,
						args = listOption({8129,9484,605},"castStart"),
					},
					shaman	= {
						type = 'group',
						inline = true,
						name = L["|cff0070DE薩滿|r"],
						order = 7,
						args = listOption({51514,76780},"castStart"),
					},
					mage = {
						type = 'group',
						inline = true,
						name = L["|cff69CCF0法師|r"],
						order = 8,
						args = listOption({118},"castStart"),
					},
					hunter = {
						type = 'group',
						inline = true,
						name = L["|cffABD473獵人|r"],
						order = 10,
						args = listOption({982,1513},"castStart"),
					},
					warlock	= {
						type = 'group',
						inline = true,
						name = L["|cff9482C9術士|r"],
						order = 11,
						args = listOption({5782,5484,710},"castStart"),
					},
				},
			},
			spellCastSuccess = {
				type = 'group',
				--inline = true,
				name = L["敵方有害技能"],
				disabled = function() return gsadb.castSuccess end,
				order = 3,
				args = {
					general = {
						type = 'group',
						inline = true,
						name = L["通用技能"],
						order = 1,
						args = listOption({58984},"castSuccess"),
					},
					druid = {
						type = 'group',
						inline = true,
						name = L["|cffFF7D0A德魯伊|r"],
						order = 2,
						args = listOption({80964},"castSuccess"),
					},
					paladin = {
						type = 'group',
						inline = true,
						name = L["|cffF58CBA聖騎士|r"],
						order = 3,
						args = listOption({96231,20066},"castSuccess"),
					},
					rogue = {
						type = 'group',
						inline = true,
						name = L["|cffFFF569盜賊|r"],
						order = 4,
						args = listOption({51722,2094,1766,14185,1856},"castSuccess"),
					},
					warrior	= {
						type = 'group',
						inline = true,
						name = L["|cffC79C6E戰士|r"],
						order = 5,
						args = listOption({676,5246,6552,85388},"castSuccess"),	
					},
					preist	= {
						type = 'group',
						inline = true,
						name = L["|cffFFFFFF牧師|r"],
						order = 6,
						args = listOption({8122,34433,64044,15487},"castSuccess"),
					},
					shaman	= {
						type = 'group',
						inline = true,
						name = L["|cff0070DE薩滿|r"],
						order = 7,
						args = listOption({8177,16190,8143},"castSuccess"),
					},
					mage = {
						type = 'group',
						inline = true,
						name = L["|cff69CCF0法師|r"],
						order = 8,
						args = listOption({11958,44572,2139,66},"castSuccess"),
					},
					dk	= {
						type = 'group',
						inline = true,
						name = L["|cffC41F3B死亡騎士|r"],
						order = 9,
						args = listOption({47528,47476,47568,49206,49203,77606},"castSuccess"),
					},
					hunter = {
						type = 'group',
						inline = true,
						name = L["|cffABD473獵人|r"],
						order = 10,
						args = listOption({19386,51755},"castSuccess"),
					},
					warlock = {
						type = 'group',
						inline = true,
						name = L["|cff9482C9術士|r"],
						order = 11,
						args = listOption({5484,19647,48020},"castSuccess"),
					},
				},
			},
			spellInterrupt = {
				type = 'group',
				--inline = true,
				name = L["友方打斷技能"],
				disabled = function() return gsadb.interrupt end,
				order = 4,
				args = {
					lockout = {
						type = 'toggle',
						name = L["友方打斷技能"],
						desc = L["法術封鎖 法術反制 腳踢 拳擊 盾擊 心智冰封 碎顱猛擊 責難"],
						order = 1,
					},
				}
			},
		}
	})
end

function GladiatorlosSA:PlayTrinket()
	PlaySoundFile("Interface\\Addons\\GladiatorlosSA\\"..gsadb.path.."\\Trinket.mp3")
end
function GladiatorlosSA:ArenaClass(id)
	for i = 1 , 5 do
		if id == UnitGUID("arena"..i) then
			return select(2, UnitClass ("arena"..i))
		end
	end
end
function GladiatorlosSA:PLAYER_ENTERING_WORLD()
	CombatLogClearEntries()
end
function GladiatorlosSA:PlaySpell(list, spellID, ...)
	if not list[spellID] then return end
	if not gsadb[list[spellID]] then return	end
	PlaySoundFile("Interface\\Addons\\GladiatorlosSA\\"..gsadb.path.."\\"..list[spellID]..".mp3");
end
function GladiatorlosSA:COMBAT_LOG_EVENT_UNFILTERED(event , ...)
	local _,currentZoneType = IsInInstance()
	if (not ((currentZoneType == "none" and gsadb.field) or (currentZoneType == "pvp" and gsadb.battleground) or (currentZoneType == "arena" and gsadb.arena) or gsadb.all)) then
		--print (currentZoneType,gsadb.field,gsadb.battleground,gsadb.arena,gsadb.all)
		return
	end
	local timestamp,_,event,sourceGUID,sourceName,sourceFlags,destGUID,destName,destFlags,spellID,spellName= select ( 1 , ... );
	--print(sourceName,destName,destFlags,event,spellName,spellID);
	local toEnemy,fromEnemy,toSelf,toTarget = false , false , false , false
	if (destName and not CombatLog_Object_IsA(destFlags, COMBATLOG_OBJECT_NONE) ) then
		toEnemy = CombatLog_Object_IsA(destFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS)
	end
	if (sourceName and not CombatLog_Object_IsA(sourceFlags, COMBATLOG_OBJECT_NONE) ) then
		fromEnemy = CombatLog_Object_IsA(sourceFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS)
	end
	if (destName and not CombatLog_Object_IsA(destFlags, COMBATLOG_OBJECT_NONE) ) then
		toSelf = CombatLog_Object_IsA(destFlags, COMBATLOG_FILTER_MINE)
	end
	if (destName and not CombatLog_Object_IsA(destFlags, COMBATLOG_OBJECT_NONE) ) then
		toFriend = CombatLog_Object_IsA(destFlags, COMBATLOG_FILTER_FRIENDLY_UNITS)
	end
	if (destName and not CombatLog_Object_IsA(destFlags, COMBATLOG_OBJECT_NONE) ) then
		toTarget = (UnitGUID("target") == destGUID)
	end
	--print (toTarget,sourceName,destName)
	--[[debug
	if (spellID == 80964 or spellID == 80965 or spellID == 85285) then 
		print (sourceName,destName,event,spellName,spellID)
	end
	enddebug]]--
	if (event == "SPELL_AURA_APPLIED" and toEnemy and (not gsadb.onlyTarget or toTarget) and not gsadb.aruaApplied) then
		if (spellID == 42292 or spellID == 59752) and gsadb.class and currentZoneType == "arena" then
			local c = self:ArenaClass(destGUID)
			PlaySoundFile("Interface\\Addons\\GladiatorlosSA\\"..gsadb.path.."\\"..c..".mp3");
			self:ScheduleTimer("PlayTrinket", 0.3)
		else	
			self:PlaySpell (self.spellList.auraApplied,spellID)
		end
	end
	if (event == "SPELL_AURA_REMOVED" and toEnemy and not gsadb.auraRemoved) then
		self:PlaySpell (self.spellList.auraRemoved,spellID)
	end
	if (event == "SPELL_CAST_START" and fromEnemy and not gsadb.castStart) then
		self:PlaySpell (self.spellList.castStart,spellID)
	end
	if (event == "SPELL_CAST_SUCCESS" and fromEnemy and not gsadb.castSuccess) then
		self:PlaySpell (self.spellList.castSuccess,spellID)
	end
	if (event == "SPELL_INTERRUPT" and toEnemy and not gsadb.interrupt) then 
		self:PlaySpell (self.spellList.friendlyInterrupt,spellID)
	end
end
