------------------------------
--      Are you local?      --
------------------------------

local boss = BB["Kil'jaeden"]
local L = AceLibrary("AceLocale-2.2"):new("BigWigs"..boss)
local CheckInteractDistance = CheckInteractDistance

local db = nil
local started = nil
local deaths = 0
local pName = UnitName("player")
local bloomed = {}
local phase = nil
local sinister1 = nil
local sinister2 = nil
local sinister3 = nil
local focusAlerts = {}
local orbseen = nil
local twominuteaudioStarted = nil

----------------------------
--      Localization      --
----------------------------

L:RegisterTranslations("enUS", function() return {
	cmd = "KilJaeden",

	bomb = "Darkness",
	bomb_desc = "Warn when Darkness of a Thousand Souls is being cast.",
	bomb_cast = "Darkness of a Thousand Souls!",
	bomb_bar = "Explosion!",
	bomb_nextbar = "Next Darkness",
	bomb_warning5 = "Darkness in 5 sec",
	bombwarn10 = "Bomb in 10 sec",
	bombwarn10_desc = "Warn 10 seconds before a Bomb.",
	bombwarn5 = "Darkness 5 sec warning",
	bombwarn5_desc = "Warn 5 seconds before Darkness of a Thousand Souls.",
	kalec_yell = "I will channel my powers into the orbs! Be ready!",
	kalec_yell2 = "I have empowered another orb! Use it quickly!",
	kalec_yell3 = "Another orb is ready! Make haste!",
	kalec_yell4 = "I have channeled all I can! The power is in your hands!",

	orb = "Shield Orb",
	orb_desc = "Warn when a Shield Orb is shadowbolting.",
	orb_shooting = "DPS Orbs",
	orbaudio = "DPS Orbs Audio",
	orbaudio_desc = "Play a local-only sound 1.5 seconds before the next Shield Orb spawn.",
	shieldorbbar = "Shield Orb Bars",
	shieldorbbar_desc = "Timer bars for upcoming Shield Orbs.",
	shieldorb_bar = "Next Shield Orb",
	shieldorbwarn5 = "Shield Orb 5 sec warning",
	shieldorbwarn5_desc = "Warn 5 seconds before the next Shield Orb.",
	shieldorb_warning5 = "Shield Orb in 5 sec",
	shieldorbcountdown = "Shield Orb countdown",
	shieldorbcountdown_desc = "Countdown 3-2-1 before the next Shield Orb.",
	shieldorb_countdown = "Shield Orb in %d",

	bloom = "Fire Bloom",
	bloom_desc = "Tells you who has been hit by Fire Bloom.",
	bloompredict = "Fire Bloom Bars",
	bloompredict_desc = "Timer bars for upcoming Fire Blooms.",
	bloom_cd_bar = "Next Fire Bloom",
	bloom_other = "Fire Bloom on %s!",
	bloom_bar = "Fire Blooms",
	bloom_message = "Next Fire Bloom in 5 seconds!",
	bloomwarn = "Fire Bloom Soon",
	bloomwarn_desc = "Warn when Fire Bloom is about to happen.",

	bloomsay = "Fire Bloom Say",
	bloomsay_desc = "Place a msg in say notifying that you have Fire Bloom",
	bloom_say = "Fire Bloom on "..strupper(pName).."!",

	bloomwhisper = "Fire Bloom Whisper",
	bloomwhisper_desc = "Whisper players with Fire Bloom.",
	bloom_you = "Fire Bloom on YOU!",

	icons = "Bloom Icons",
	icons_desc = "Place random Raid Icons on players with Fire Bloom (requires promoted or higher)",

	shadow = "Shadow Spike",
	shadow_desc = "Raid warn of casting of Shadow Spike.",
	shadow_message = "Dodge Shadow Spikes!",
	shadow_bar = "Shadow Spikes Expire",
	shadow_debuff_bar = "Reduced Healing on %s",

	shadowdebuff = "Disable Shadow Bars",
	shadowdebuff_desc = "Timer bars for players affected by the Shadow Debuff",

	flame = "Flame Dart",
	flame_desc = "Show Flame Dart timer bar.",
	flame_bar = "Next Flame Dart",
	flame_message = "Next Flame Dart in 5 seconds!",
	flamewarn = "Flame Dart Soon",
	flamewarn_desc = "Warn when Flame Dart is about to happen.",

	sinister = "Sinister Reflections",
	sinister_desc = "Warns on Sinister Reflection spawns.",
	sinister_warning = "Sinister Reflections Soon!",
	sinister_warning_percent = "Reflections Soon - %d%%",
	sinister_message = "Sinister Reflections Up!",
	twominuteaudio = "Two-Minute Audio",
	twominuteaudio_desc = "Play a local-only two-minute cooldown reminder every 2 minutes, starting 2:08 after the first Sinister Reflections spawn.",
	focushealth = "Focus Health Callouts",
	focushealth_desc = "Local focus-based Kil'jaeden health callouts.",
	focushealth_menu = "Focus Percentages",
	focushealth_menu_desc = "Enable specific local Kil'jaeden percentage sound callouts.",
	focushealth55 = "55% Lust Reminder",
	focushealth55_desc = "Play the 55% bloodlust reminder locally.",

	blueorb = "Dragon Orb",
	blueorb_desc = "Warns on Blue Dragonflight Orb spawns.",
	blueorb_message = "Dragon Orb ready!",
	blueorb_warning = "Dragon Orb in ~5 Sec!",
	blueorbwarn = "Dragon Orb Soon",
	blueorbwarn_desc = "Warn when the Dragon Orb is about to be ready.",

	shield_up = "Shield is UP!",

	deceiver_dies = "Deciever #%d Killed",
	["Hand of the Deceiver"] = true,

	phase = "Phase",
	phase_desc = "Warn for phase changes.",
	phase2_message = "Phase 2 - Kil'jaeden incoming!",
	kjcountdown = "Kil'jaeden Countdown",
	kjcountdown_desc = "Countdown 5-1 before Kil'jaeden becomes active.",
	kj_countdown = "Kil'jaeden in %d",
	phase3_trigger = "I will not be denied! This world shall fall!",
	phase3_message = "Phase 3 - add Darkness",
	phase4_trigger = "Do not harbor false hope. You cannot win!",
	phase4_message = "Phase 4 - add Meteor",
	phase5_trigger = "Aggghh! The powers of the Sunwell... turn... against me! What have you done? What have you done???",
	phase5_message = "Phase 5 - Sacrifice of Anveena",
} end )

L:RegisterTranslations("koKR", function() return {
	bomb = "어둠의 영혼",
	bomb_desc = "무수한 어둠의 영혼 시전 시 알립니다.",
	bomb_cast = "잠시 후 폭탄!",
	bomb_bar = "폭발!",
	bomb_nextbar = "~폭탄 가능",
	bomb_warning = "10초 후 폭탄!",
	bomb_warning5 = "5초 후 폭탄!",
	bombwarn10 = "폭탄 10초 전",
	bombwarn10_desc = "폭탄 10초 전 경고합니다.",
	bombwarn5 = "폭탄 5초 전",
	bombwarn5_desc = "폭탄 5초 전 경고합니다.",
	kalec_yell = "수정구에 힘을 쏟겠습니다! 준비하세요!",
	kalec_yell2 = "다른 수정구에 힘을 불어넣었습니다! 어서요!",
	kalec_yell3 = "다른 수정구가 준비됐습니다! 서두르세요!",	--check
	kalec_yell4 = "모든 힘을 수정구에 실었습니다! 이제 그대들의 몫입니다!",

	orb = "보호의 구슬",
	orb_desc = "보호의 구슬의 어둠 화살을 알립니다.",
	orb_shooting = "구슬 활동 - 어활 공격!",
	shieldorbbar = "보호의 구슬 바",
	shieldorbbar_desc = "다음 보호의 구슬 타이머 바를 표시합니다.",
	shieldorb_bar = "다음 보호의 구슬",
	shieldorbwarn5 = "보호의 구슬 5초 경고",
	shieldorbwarn5_desc = "다음 보호의 구슬 5초 전에 알립니다.",
	shieldorb_warning5 = "5초 후 보호의 구슬!",
	shieldorbcountdown = "보호의 구슬 카운트다운",
	shieldorbcountdown_desc = "다음 보호의 구슬 3-2-1 카운트다운.",
	shieldorb_countdown = "%d초 후 보호의 구슬",

	bloom = "화염 불꽃",
	bloom_desc = "화염 불꽃에 걸린 플레이어를 알립니다.",
	bloompredict = "화염 불꽃 바",
	bloompredict_desc = "다음 화염 불꽃 타이머 바를 표시합니다.",
	bloom_cd_bar = "다음 화염 불꽃",
	bloom_other = "%s 화염 불꽃!",
	bloom_bar = "화염 불꽃",
	bloom_message = "5초 후 다음 화염 불꽃!",
	bloomwarn = "화염 불꽃 예고",
	bloomwarn_desc = "화염 불꽃이 곧 발생할 때 알립니다.",

	bloomsay = "화염 불꽃 대화",
	bloomsay_desc = "자신이 화염 불꽃에 걸렸을시 일반 대화로 출력합니다.",
	bloom_say = ""..strupper(pName).." 화염 불꽃!",

	bloomwhisper = "화염 불꽃 귓속말",
	bloomwhisper_desc = "화염 불꽃에 걸린 플레이어에게 귓속말로 알립니다.",
	bloom_you = "당신은 화염 불꽃!",

	icons = "불꽃 전술 표시",
	icons_desc = "화염 불꽃에 걸린 플레이어에게 전술 표시를 지정합니다. (승급자 이상 권한 필요)",

	shadow = "어둠의 쐐기",
	shadow_desc = "어둠의 쐐기에 대하여 공격대에 알립니다.",
	shadow_message = "어둠의 쐐기를 피하세요!",
	shadow_bar = "어둠의 쐐기 종료",
	shadow_debuff_bar = "%s 치유효과 감소",

	shadowdebuff = "치유 감소바 비활성",
	shadowdebuff_desc = "치유효과 감소 디버프가 걸린 플레이어의 타이머바를 사용하지 않습니다.",

	flame = "불꽃 화살",
	flame_desc = "불꽃 화살 타이머 바를 표시합니다.",
	flame_bar = "다음 불꽃 화살",
	flame_message = "5초 이내 다음 불꽃 화살!",
	flamewarn = "불꽃 화살 예고",
	flamewarn_desc = "불꽃 화살이 곧 발생할 때 알립니다.",

	sinister = "사악한 환영",
	sinister_desc = "사악한 환영 생성을 알립니다.",
	sinister_warning = "잠시 후 사악한 환영!",
	sinister_warning_percent = "사악한 환영 곧 등장 - %d%%",
	sinister_message = "사악한 환영!",
	focushealth = "Focus Health Callouts",
	focushealth_desc = "Local focus-based Kil'jaeden health callouts.",
	focushealth_menu = "Focus Percentages",
	focushealth_menu_desc = "Enable specific local Kil'jaeden percentage sound callouts.",
	focushealth55 = "55% Lust Reminder",
	focushealth55_desc = "Play the 55% bloodlust reminder locally.",
	
	blueorb = "푸른용군단의 수정구",
	blueorb_desc = "푸른용군단의 수정구의 생성을 알립니다.",
	blueorb_message = "용군단 수정구 준비됨!",
	blueorb_warning = "약 5초 이내 용군단 수정구!",
	blueorbwarn = "푸른용군단 수정구 예고",
	blueorbwarn_desc = "푸른용군단 수정구가 곧 준비될 때 알립니다.",

	shield_up = "푸른용의 보호막!",

	deceiver_dies = "심복 #%d 처치",
	["Hand of the Deceiver"] = "기만자의 심복",

	phase = "단계",
	phase_desc = "단계 변경을 알립니다.",
	phase2_message = "2 단계 - 킬제덴!",
	kjcountdown = "킬제덴 카운트다운",
	kjcountdown_desc = "킬제덴 등장 5~1초 전 카운트다운을 표시합니다.",
	kj_countdown = "킬제덴 %d초 전",
	phase3_trigger = "나를 부정할 수는 없다! 이 세계는 멸망하리라!",
	phase3_message = "3 단계 - 어둠의 영혼 추가",
	phase4_trigger = "헛된 꿈을 꾸고 있구나! 너흰 이길 수 없어!",
	phase4_message = "4 단계 - 유성 추가",
	phase5_trigger = "으아! 태양샘의 마력이... 나를... 거부한다! 무슨 짓을 한 거지? 무슨 짓을 한 거냐???",
	phase5_message = "5 단계 - 안비나의 희생",
} end )

L:RegisterTranslations("frFR", function() return {
	bomb = "Ténèbres des mille âmes",
	bomb_desc = "Prévient quand les Ténèbres des mille âmes sont incantés.",
	bomb_cast = "Arrivée de la bombe !",
	bomb_bar = "Explosion !",
	bomb_nextbar = "~Bombe probable",
	bomb_warning = "Bombe dans 10 sec.",
	bomb_warning5 = "Bombe dans 5 sec.",
	bombwarn10 = "Bombe dans 10 sec",
	bombwarn10_desc = "Prévient 10 secondes avant une Bombe.",
	bombwarn5 = "Bombe dans 5 sec",
	bombwarn5_desc = "Prévient 5 secondes avant une Bombe.",
	kalec_yell = "Je vais canaliser mon énergie vers les orbes ! Préparez-vous !", -- à vérifier
	kalec_yell2 = "J'ai chargé un autre orbe ! Utilisez-le vite !", -- à vérifier
	kalec_yell3 = "Un autre orbe est prêt ! Hâtez-vous !", -- à vérifier
	kalec_yell4 = "J'ai envoyé tout ce que je pouvais ! La puissance est entre vos mains !", -- à vérifier

	orb = "Orbe bouclier",
	orb_desc = "Prévient quand un Orbe bouclier lance des Traits de l'ombre.",
	orb_shooting = "Orbe en vie - Bombardement de traits !",
	shieldorbbar = "Barres des Orbes bouclier",
	shieldorbbar_desc = "Affiche des barres pour les prochains Orbes bouclier.",
	shieldorb_bar = "Prochain Orbe bouclier",
	shieldorbwarn5 = "Alerte 5 sec Orbe bouclier",
	shieldorbwarn5_desc = "Prévient 5 secondes avant le prochain Orbe bouclier.",
	shieldorb_warning5 = "Orbe bouclier dans 5 sec.",
	shieldorbcountdown = "Compte à rebours Orbe bouclier",
	shieldorbcountdown_desc = "Compte à rebours 3-2-1 avant le prochain Orbe bouclier.",
	shieldorb_countdown = "Orbe bouclier dans %d",

	bloom = "Fleurs du feu",
	bloom_desc = "Prévient quand des joueurs subissent les effets de la Fleur du feu.",
	bloompredict = "Barres Fleur du feu",
	bloompredict_desc = "Affiche des barres pour les prochaines Fleurs du feu.",
	bloom_cd_bar = "Prochaine Fleur du feu",
	bloom_other = "Fleur du feu sur %s !",
	bloom_bar = "Fleurs du feu",
	bloom_message = "Prochaines Fleurs du feu dans 5 sec. !",
	bloomwarn = "Fleurs du feu bientôt",
	bloomwarn_desc = "Prévient quand les Fleurs du feu vont se produire.",

	bloomsay = "Dire - Fleur du feu",
	bloomsay_desc = "Fait dire à votre personnage qu'il subit les effets de la Fleur du feu quand c'est le cas, afin d'aider les membres proches ayant les bulles de dialogue activées.",
	bloom_say = "Fleur du feu sur "..strupper(pName).." !",

	bloomwhisper = "Chuchoter",
	bloomwhisper_desc = "Prévient par chuchotement les derniers joueurs affectés par la Fleur du feu (nécessite d'être promu ou mieux).",
	bloom_you = "Fleur du feu sur VOUS !",

	icons = "Icônes",
	icons_desc = "Place une icône de raid sur les derniers joueurs affectés par la Fleur du feu (nécessite d'être promu ou mieux).",

	shadow = "Pointes de l'ombre",
	shadow_desc = "Prévient quand les Pointes de l'ombre sont incantées.",
	shadow_message = "Évitez les Pointes de l'ombre !",
	shadow_bar = "Fin des Pointes",
	shadow_debuff_bar = "Soins réduits sur %s",

	shadowdebuff = "Pas de barres des Pointes",
	shadowdebuff_desc = "Désactive les barres temporelles des joueurs affectés par les Pointe de l'ombre si coché.",

	flame = "Fléchettes des flammes",
	flame_desc = "Affiche une barre temporelle pour les Flèchettes des flammes.",
	flame_bar = "Prochaines Fléchettes",
	flame_message = "Prochaines Fléchettes des flammes dans 5 sec. !",
	flamewarn = "Fléchettes des flammes bientôt",
	flamewarn_desc = "Prévient quand les Fléchettes des flammes vont se produire.",

	sinister = "Reflets sinistres",
	sinister_desc = "Prévient quand les Reflets sinistres apparaissent.",
	sinister_warning = "Reflets sinistres imminents !",
	sinister_warning_percent = "Reflets imminents - %d%%",
	sinister_message = "Reflets sinistres actifs !",
	focushealth = "Focus Health Callouts",
	focushealth_desc = "Local focus-based Kil'jaeden health callouts.",
	focushealth_menu = "Focus Percentages",
	focushealth_menu_desc = "Enable specific local Kil'jaeden percentage sound callouts.",
	focushealth55 = "55% Lust Reminder",
	focushealth55_desc = "Play the 55% bloodlust reminder locally.",

	blueorb = "Orbe du Vol bleu",
	blueorb_desc = "Prévient quand un Orbe du Vol bleu est prêt.",
	blueorb_message = "Orbe du Vol prêt !",
	blueorb_warning = "Orbe du Vol bleu dans ~5 sec. !",
	blueorbwarn = "Orbe du Vol bleu bientôt",
	blueorbwarn_desc = "Prévient quand l'Orbe du Vol bleu est bientôt prêt.",

	shield_up = "Bouclier ACTIF !",

	deceiver_dies = "Trompeur #%d tué",
	["Hand of the Deceiver"] = "Main du Trompeur", -- à vérifier

	phase = "Phases",
	phase_desc = "Prévient quand la rencontre entre dans une nouvelle phase.",
	phase2_message = "Phase 2 - Arrivée de Kil'jaeden !",
	kjcountdown = "Compte à rebours de Kil'jaeden",
	kjcountdown_desc = "Compte à rebours 5-1 avant l'activation de Kil'jaeden.",
	kj_countdown = "Kil'jaeden dans %d s",
	phase3_trigger = "Rien ne m'arrêtera ! Ce monde va tomber !", -- à vérifier
	phase3_message = "Phase 3 - Ajout des Ténèbres des mille âmes",
	phase4_trigger = "Assez de faux espoirs. Vous ne pouvez pas gagner !", -- à vérifier
	phase4_message = "Phase 4 - Ajout des Météores",
	phase5_trigger = "Nooon ! Les pouvoirs du Puits de soleil se retournent contre moi ! Qu'avez-vous fait ? Qu'avez-vous fait ?!", -- à vérifier
	phase5_message = "Phase 5 - Sacrifice d'Anveena",
} end )

L:RegisterTranslations("zhCN", function() return {
	bomb = "千魂之暗",
	bomb_desc = "当千魂之暗开始施放时发出警报。",
	bomb_cast = "即将 爆炸！",
	bomb_bar = "<千魂之暗>",
	bomb_nextbar = "<可能 千魂之暗>",
	bomb_warning = "10秒后，千魂之暗！",
	bomb_warning5 = "5秒后，千魂之暗！",
	bombwarn10 = "炸弹 10 秒",
	bombwarn10_desc = "在炸弹发生前 10 秒警报。",
	bombwarn5 = "炸弹 5 秒",
	bombwarn5_desc = "在炸弹发生前 5 秒警报。",
	kalec_yell = "我会将我的力量导入宝珠中！准备好！",
	kalec_yell2 = "我又将能量灌入了另一颗宝珠！快去使用它！",
	kalec_yell3 = "又有一颗宝珠准备好了！快点行动！",
	kalec_yell4 = "这是我所能做的一切了！力量现在掌握在你们的手中！",

	orb = "护盾宝珠",
	orb_desc = "当护盾宝珠施放暗影箭时发出警报。",
	orb_shooting = "护盾宝珠 - 暗影箭！",
	shieldorbbar = "护盾宝珠计时条",
	shieldorbbar_desc = "显示下一次护盾宝珠计时条。",
	shieldorb_bar = "下一护盾宝珠",
	shieldorbwarn5 = "护盾宝珠5秒预警",
	shieldorbwarn5_desc = "在下一次护盾宝珠前5秒警报。",
	shieldorb_warning5 = "5秒后，护盾宝珠！",
	shieldorbcountdown = "护盾宝珠倒计时",
	shieldorbcountdown_desc = "下一次护盾宝珠前3-2-1倒计时。",
	shieldorb_countdown = "护盾宝珠 %d 秒",

	bloom = "火焰之花",
	bloom_desc = "当玩家中了火焰之花时发出警报。",
	bloompredict = "火焰之花计时条",
	bloompredict_desc = "显示下一次火焰之花计时条。",
	bloom_cd_bar = "下一火焰之花",
	bloom_other = "火焰之花：>%s<！",
	bloom_bar = "<火焰之花>",
	bloom_message = "5秒后，火焰之花！",
	bloomwarn = "火焰之花预警",
	bloomwarn_desc = "当火焰之花即将发生时发出警报。",

	bloomsay = "火焰之花提醒",
	bloomsay_desc = "当你中了火焰之花时通知周围的玩家。",
	bloom_say = ">"..strupper(pName).."< 中了火焰之花！",

	bloomwhisper = "火焰之花密语",
	bloomwhisper_desc = "当玩家中了火焰之花时密语提示他离开。",
	bloom_you = ">你< 中了火焰之花！",

	icons = "团队标记",
	icons_desc = "为中了火焰之花的玩家随机打上一个团队标记。（需要权限）",

	shadow = "暗影之刺",
	shadow_desc = "当施放暗影之刺时发出警报。",
	shadow_message = "躲开暗影之刺！",
	shadow_bar = "<暗影之刺>",
	shadow_debuff_bar = "<降低治疗：%s>",

	shadowdebuff = "禁用暗影减益计时条",
	shadowdebuff_desc = "玩家中了暗影减益效果计时条。",

	flame = "烈焰之刺",
	flame_desc = "显示烈焰之刺记时条。",
	flame_bar = "<下一烈焰之刺>",
	flame_message = "5秒后，烈焰之刺！",
	flamewarn = "烈焰之刺预警",
	flamewarn_desc = "当烈焰之刺即将发生时发出警报。",

	sinister = "邪恶镜像",
	sinister_desc = "当邪恶镜像时发出警报。",
	sinister_warning = "即将 邪恶镜像！",
	sinister_warning_percent = "邪恶镜像即将出现 - %d%%",
	sinister_message = "邪恶镜像 出现！",
	focushealth = "Focus Health Callouts",
	focushealth_desc = "Local focus-based Kil'jaeden health callouts.",
	focushealth_menu = "Focus Percentages",
	focushealth_menu_desc = "Enable specific local Kil'jaeden percentage sound callouts.",
	focushealth55 = "55% Lust Reminder",
	focushealth55_desc = "Play the 55% bloodlust reminder locally.",

	blueorb = "蓝龙宝珠",
	blueorb_desc = "当蓝龙宝珠可用时发出警报。",
	blueorb_message = "龙宝珠已准备好！",
	blueorb_warning = "约5秒后，蓝龙宝珠可以使用！",
	blueorbwarn = "蓝龙宝珠预警",
	blueorbwarn_desc = "当蓝龙宝珠即将可用时发出警报。",

	shield_up = ">蓝龙之盾< 启用！",

	deceiver_dies = "已杀死基尔加丹之手#%d",
	["Hand of the Deceiver"] = "基尔加丹之手",

	phase = "阶段",
	phase_desc = "当进入不同阶段时发出警报。",
	phase2_message = "第二阶段 - 基尔加丹来临！",
	kjcountdown = "基尔加丹倒计时",
	kjcountdown_desc = "基尔加丹激活前 5-1 秒倒计时。",
	kj_countdown = "基尔加丹 %d 秒",
	phase3_trigger = "我是不会失败的！这个世界注定要毁灭！",
	phase3_message = "第三阶段 - 注意千魂之暗！",
	phase4_trigger = "别再抱有幻想了！你们不可能赢！",
	phase4_message = "第四阶段 - 注意流星！",
	phase5_trigger = "啊啊啊！太阳之井的能量……开始……对抗我！你们都做了些什么？你们都做了些什么？？",
	phase5_message = "第五阶段 - 牺牲安薇娜！",
} end )

----------------------------------
--      Module Declaration      --
----------------------------------

local deceiver = L["Hand of the Deceiver"]
local mod = BigWigs:NewModule(boss)
mod.zonename = BZ["Sunwell Plateau"]
mod.enabletrigger = {deceiver, boss}
mod.guid = 25315
mod.toggleoptions = {"phase", "kjcountdown", -1, "bomb", "bombwarn5", "orb", "orbaudio", "shieldorbbar", "shieldorbwarn5", "shieldorbcountdown", "flame", "flamewarn", -1, "bloom", "bloompredict", "bloomwarn", "bloomwhisper", "bloomsay", "icons", -1, "sinister", "twominuteaudio", "focushealth", "blueorb", "blueorbwarn", "shadow", "shadowdebuff", "proximity", "bosskill"}
mod.revision = tonumber(("$Revision: 77383 $"):sub(12, -3))
mod.proximityCheck = function( unit ) return CheckInteractDistance( unit, 3 ) end
mod.proximitySilent = true
mod.defaultDB = {
	twominuteaudio = false,
}
mod.consoleOptions = {
	args = {
		focushealth_menu = {
			type = "group",
			order = 1000,
			name = L["focushealth_menu"],
			desc = L["focushealth_menu_desc"],
			pass = true,
			get = function(key)
				return mod.db.profile[key]
			end,
			set = function(key, value)
				mod.db.profile[key] = value
			end,
			disabled = function() return not mod.db.profile.focushealth end,
			args = {
				focushealth91 = { type = "toggle", name = "91%", desc = "Play the 91% callout locally." },
				focushealth90 = { type = "toggle", name = "90%", desc = "Play the 90% callout locally." },
				focushealth87 = { type = "toggle", name = "87%", desc = "Play the 87% callout locally." },
				focushealth61 = { type = "toggle", name = "61%", desc = "Play the 61% callout locally." },
				focushealth60 = { type = "toggle", name = "60%", desc = "Play the 60% callout locally." },
				focushealth58 = { type = "toggle", name = "58%", desc = "Play the 58% callout locally." },
				focushealth57 = { type = "toggle", name = "57%", desc = "Play the 57% callout locally." },
				focushealth55 = { type = "toggle", name = L["focushealth55"], desc = L["focushealth55_desc"] },
				focushealth30 = { type = "toggle", name = "30%", desc = "Play the 30% callout locally." },
				focushealth27 = { type = "toggle", name = "27%", desc = "Play the 27% callout locally." },
				focushealth26 = { type = "toggle", name = "26%", desc = "Play the 26% callout locally." },
				focushealth10 = { type = "toggle", name = "10%", desc = "Play the 10% callout locally." },
				focushealth5 = { type = "toggle", name = "5%", desc = "Play the 5% callout locally." },
				focushealth3 = { type = "toggle", name = "3%", desc = "Play the 3% callout locally." },
				focushealth2 = { type = "toggle", name = "2%", desc = "Play the 2% callout locally." },
				focushealth1 = { type = "toggle", name = "1%", desc = "Play the 1% callout locally." },
			},
		},
	},
}

------------------------------
--      Initialization      --
------------------------------

function mod:OnEnable()
	self:AddCombatListener("SPELL_CAST_SUCCESS", "Sinister", 45892)
	self:AddCombatListener("SPELL_CAST_SUCCESS", "Shield", 45848)
	self:AddCombatListener("SPELL_DAMAGE", "Orb", 45680)
	self:AddCombatListener("SPELL_MISSED", "Orb", 45680)
	self:AddCombatListener("SPELL_AURA_APPLIED", "Bloom", 45641)
	self:AddCombatListener("SPELL_AURA_APPLIED", "Shadow", 45885)
	self:AddCombatListener("SPELL_CAST_START", "ShadowCast", 46680)
	self:AddCombatListener("UNIT_DIED", "Deaths")

	self:RegisterEvent("CHAT_MSG_RAID_BOSS_EMOTE")
	self:RegisterEvent("CHAT_MSG_MONSTER_YELL")
	self:RegisterEvent("UNIT_HEALTH")

	self:RegisterEvent("PLAYER_REGEN_ENABLED", "CheckForWipe")
	self:RegisterEvent("PLAYER_REGEN_DISABLED", "CheckForEngage")
	self:RegisterEvent("BigWigs_RecvSync")

	db = self.db.profile
	started = nil
	deaths = 0
	phase = 0
	orbseen = nil
	twominuteaudioStarted = nil
	for k in pairs(focusAlerts) do
		focusAlerts[k] = nil
	end
	for i = 1, #bloomed do bloomed[i] = nil end
end

function mod:OnDisable()
	self:StopFocusHealthWatcher("KJFocusHealth")
	self:CancelScheduledEvent("KJPhase2AbilityTimers")
	self:CancelScheduledEvent("KJTwoMinuteAudio")
end

------------------------------
--      Event Handlers      --
------------------------------

function mod:StopShieldOrbTimers()
	self:CancelScheduledEvent("KJShieldOrbWarn5")
	self:CancelScheduledEvent("KJShieldOrbCount3")
	self:CancelScheduledEvent("KJShieldOrbCount2")
	self:CancelScheduledEvent("KJShieldOrbCount1")
	self:CancelScheduledEvent("KJShieldOrbAudio")
	self:CancelScheduledEvent("KJShieldOrbRepeat")
	self:TriggerEvent("BigWigs_StopBar", self, L["shieldorb_bar"])
end

function mod:StopPredictiveBloomTimer()
	self:CancelScheduledEvent("KJBloomPredictAfterFirst")
	self:CancelScheduledEvent("KJBloomPredictRepeat")
	self:TriggerEvent("BigWigs_StopBar", self, L["bloom_cd_bar"])
end

function mod:SchedulePredictiveBloom(timer, repeatTimer)
	self:CancelScheduledEvent("KJBloomPredictRepeat")
	if db.bloompredict then
		self:Bar(L["bloom_cd_bar"], timer, 45641)
	end
	if repeatTimer then
		self:ScheduleEvent("KJBloomPredictRepeat", self.SchedulePredictiveBloom, timer, self, repeatTimer, repeatTimer)
	end
end

function mod:StartPredictiveBloomTimer()
	self:StopPredictiveBloomTimer()
	self:SchedulePredictiveBloom(18)
	self:ScheduleEvent("KJBloomPredictAfterFirst", self.SchedulePredictiveBloom, 18, self, 30, 35)
end

function mod:StartPhase2AbilityTimers()
	self:ScheduleShieldOrb(18, 35)
	self:StartPredictiveBloomTimer()
end

function mod:RepeatTwoMinuteAudio()
	self:TriggerEvent("BigWigs_Sound", "BigWigs: Two Minutes")
	self:ScheduleEvent("KJTwoMinuteAudio", self.RepeatTwoMinuteAudio, 120, self)
end

function mod:StartFocusHealthCheck()
	self:StartFocusHealthWatcher("KJFocusHealth", {
		interval = 0.25,
		enabledKey = "focushealth",
		expectedName = boss,
		units = {"focus", "target"},
		thresholds = {91, 90, 88, 61, 60, 59, 58, 56, 30, 28, 27, 10, 5, 3, 2, 1},
		condition = function(module)
			return phase >= 2
		end,
		onThreshold = function(module, threshold)
			local optionThreshold = threshold
			local soundThreshold = threshold
			if threshold == 88 then
				optionThreshold = 87
				soundThreshold = 87
			elseif threshold == 59 then
				optionThreshold = 58
				soundThreshold = 58
			elseif threshold == 56 then
				optionThreshold = 55
				soundThreshold = 55
			elseif threshold == 28 then
				optionThreshold = 27
				soundThreshold = 27
			end

			if soundThreshold == 55 then
				if not focusAlerts[soundThreshold] and db.focushealth55 then
					focusAlerts[soundThreshold] = true
					module:TriggerEvent("BigWigs_Sound", "BigWigs: KJ 55 Lust Reminder")
				end
			elseif not focusAlerts[soundThreshold] and db["focushealth" .. optionThreshold] then
				focusAlerts[soundThreshold] = true
				module:LocalMessage(("%s %d%%"):format(boss, soundThreshold), soundThreshold <= 27 and "Urgent" or "Attention", nil, ("BigWigs: KJ %d"):format(soundThreshold))
			end

			if soundThreshold == 87 and not sinister1 then
				sinister1 = true
				if db.sinister then
					module:Message(L["sinister_warning_percent"]:format(87), "Attention")
				end
			elseif soundThreshold == 58 and not sinister2 then
				sinister2 = true
				if db.sinister then
					module:Message(L["sinister_warning_percent"]:format(58), "Attention")
				end
			elseif soundThreshold == 27 and not sinister3 then
				sinister3 = true
				if db.sinister then
					module:Message(L["sinister_warning_percent"]:format(27), "Attention")
				end
			end
		end,
	})
end

function mod:CheckSinisterHealth(health, maxHealth)
	if not health or not maxHealth or maxHealth <= 0 then return end

	local percent = (health / maxHealth) * 100
	if not sinister1 and percent <= 87 then
		sinister1 = true
		self:Message(L["sinister_warning_percent"]:format(87), "Attention")
	elseif not sinister2 and percent <= 58 then
		sinister2 = true
		self:Message(L["sinister_warning_percent"]:format(58), "Attention")
	elseif not sinister3 and percent <= 27 then
		sinister3 = true
		self:Message(L["sinister_warning_percent"]:format(27), "Attention")
	end
end

function mod:ScheduleShieldOrb(timer, nextTimer)
	self:StopShieldOrbTimers()
	if phase >= 5 then return end
	if db.shieldorbbar then
		self:Bar(L["shieldorb_bar"], timer, 45680)
	end
	if db.shieldorbwarn5 and timer > 5 then
		self:ScheduleEvent("KJShieldOrbWarn5", "BigWigs_Message", timer - 5, L["shieldorb_warning5"], "Attention")
	end
	if db.orbaudio and timer > 1.5 then
		self:ScheduleEvent("KJShieldOrbAudio", "BigWigs_Sound", timer - 1.5, "BigWigs: KJ Orbs")
	end
	if db.shieldorbcountdown then
		if timer > 3 then
			self:ScheduleEvent("KJShieldOrbCount3", "BigWigs_Message", timer - 3, L["shieldorb_countdown"]:format(3), "Urgent")
		end
		if timer > 2 then
			self:ScheduleEvent("KJShieldOrbCount2", "BigWigs_Message", timer - 2, L["shieldorb_countdown"]:format(2), "Urgent")
		end
		if timer > 1 then
			self:ScheduleEvent("KJShieldOrbCount1", "BigWigs_Message", timer - 1, L["shieldorb_countdown"]:format(1), "Urgent")
		end
	end
	if nextTimer then
		self:ScheduleEvent("KJShieldOrbRepeat", self.ScheduleShieldOrb, timer, self, nextTimer, nextTimer)
	end
end

function mod:Sinister()
	self:CancelScheduledEvent("BombWarn")
	self:CancelScheduledEvent("BombWarn10")
	self:CancelScheduledEvent("BombWarn5")
	self:TriggerEvent("BigWigs_StopBar", self, L["bomb_nextbar"])
	if db.twominuteaudio and not twominuteaudioStarted then
		twominuteaudioStarted = true
		self:ScheduleEvent("KJTwoMinuteAudio", self.RepeatTwoMinuteAudio, 128, self)
	end
	if db.sinister then
		self:IfMessage(L["sinister_message"], "Attention", 45892)
	end
	if db.flame then
		self:Bar(L["flame_bar"], 59, 45737)
		if db.flamewarn then
			self:DelayedMessage(54, L["flame_message"], "Attention")
		end
	end
	if db.blueorb then
		-- 23018, looks like a Blue Dragonflight Orb :)
		local timer = (phase == 4) and 45 or 37
		local warn = (phase == 4) and 40 or 32
		self:Bar(L["blueorb"], timer, 23018)
		if db.blueorbwarn then
			self:DelayedMessage(warn, L["blueorb_warning"], "Urgent")
		end
	end
	if phase < 5 then
		self:ScheduleShieldOrb(58, 35)
	end
	self:SchedulePredictiveBloom(67, 35)
end

function mod:Shield()
	self:IfMessage(L["shield_up"], "Urgent", 45848)
end

local last = 0
function mod:Orb()
	local time = GetTime()
	if (time - last) > 10 then
		last = time
		if db.orb then
			self:IfMessage(L["orb_shooting"], "Attention", 45680, "Alert")
		end
		if not orbseen and phase < 5 then
			orbseen = true
			self:ScheduleShieldOrb(35, 35)
		end
	end
end

function mod:Deaths(unit, guid)
	if unit == deceiver then
		deaths = deaths + 1
		self:IfMessage(L["deceiver_dies"]:format(deaths), "Positive")
		if deaths == 3 then
			phase = 2
			self:Bar(boss, 10.5, "Spell_Shadow_Charm")
			self:TriggerEvent("BigWigs_ShowProximity", self)
			self:StartFocusHealthCheck()
			self:ScheduleEvent("KJPhase2AbilityTimers", self.StartPhase2AbilityTimers, 10.5, self)
			if db.kjcountdown then
				for i = 5, 1, -1 do
					self:DelayedMessage(10.5 - i, L["kj_countdown"]:format(i), "Urgent")
				end
			end
			if db.phase then
				self:Message(L["phase2_message"], "Important", nil, "Alarm")
			end
		end
	else
		self:BossDeath(nil, guid)
	end
end

function mod:CHAT_MSG_RAID_BOSS_EMOTE(_, unit)
	if unit == boss and db.bomb then
		self:CancelScheduledEvent("BombWarn5")
		self:Bar(L["bomb_bar"], 8, "Spell_Shadow_BlackPlague")
		self:IfMessage(L["bomb_cast"], "Positive")
		if phase == 3 or phase == 4 then
			self:Bar(L["bomb_nextbar"], 46, "Spell_Shadow_BlackPlague")
			if db.bombwarn5 then
				self:ScheduleEvent("BombWarn5", "BigWigs_Message", 41, L["bomb_warning5"], "Attention")
			end
		elseif phase == 5 then
			self:Bar(L["bomb_nextbar"], 25, "Spell_Shadow_BlackPlague")
			if db.bombwarn5 then
				self:DelayedMessage(20, L["bomb_warning5"], "Attention")
			end
		end
	end
end

function mod:CHAT_MSG_MONSTER_YELL(msg)
	if (msg == L["kalec_yell"] or msg == L["kalec_yell2"] or msg == L["kalec_yell3"]) then
		if db.bomb then
			self:CancelScheduledEvent("BombWarn5")
			self:Bar(L["bomb_nextbar"], 40, "Spell_Shadow_BlackPlague")
			if db.bombwarn5 then
				self:DelayedMessage(35, L["bomb_warning5"], "Attention")
			end
		end
		if db.blueorb then
			self:IfMessage(L["blueorb_message"], "Attention")
		end
	elseif msg == L["kalec_yell4"] then
		if db.bomb then
			self:CancelScheduledEvent("BombWarn5")
			self:Bar(L["bomb_nextbar"], 13, "Spell_Shadow_BlackPlague")
			if db.bombwarn5 then
				self:DelayedMessage(8, L["bomb_warning5"], "Attention")
			end
		end
		if db.blueorb then
			self:IfMessage(L["blueorb_message"], "Attention")
		end
	elseif msg == L["phase3_trigger"] then
		phase = 3
		self:CancelScheduledEvent("BombWarn5")
		if db.phase then
			self:Message(L["phase3_message"], "Important", nil, "Alarm")
		end
	elseif msg == L["phase4_trigger"] then
		phase = 4
		self:CancelScheduledEvent("BombWarn5")
		if db.phase then
			self:Message(L["phase4_message"], "Important", nil, "Alarm")
		end
	elseif msg == L["phase5_trigger"] then
		phase = 5
		self:CancelScheduledEvent("BombWarn5")
		self:StopShieldOrbTimers()
		if db.phase then
			self:Message(L["phase5_message"], "Important", nil, "Alarm")
		end
	end
end

function mod:ShadowCast(_, spellID)
	if db.shadow then
		self:Bar(L["shadow_bar"], 28.7, spellID)
		self:IfMessage(L["shadow_message"], "Attention", spellID)
	end
end

function mod:Shadow(player, spellId)
	if not db.shadowdebuff then
		self:Bar(L["shadow_debuff_bar"]:format(player), 10, spellId) 
	end
end

function mod:Bloom(player)
	if db.bloom then
		tinsert(bloomed, player)
		self:Whisper(player, L["bloom_you"], "bloomwhisper")
		self:ScheduleEvent("BWBloomWarn", self.BloomWarn, 0.4, self)
		if player == pName and db.bloomsay then
			self:LocalMessage(L["bloom_you"], "Personal", 45641, "Long")
			SendChatMessage(L["bloom_say"], "SAY")
		end
	end
end

function mod:BloomWarn()
	local msg = nil
	table.sort(bloomed)

	for i,v in ipairs(bloomed) do
		local colored = self:ColorName(v)
		if not msg then
			msg = colored
		else
			msg = msg .. ", " .. colored
		end
		if db.icons then
			SetRaidTarget(v, i)
		end
	end

	self:IfMessage(L["bloom_other"]:format(msg), "Important", 45641, "Alert")
	self:Bar(L["bloom_bar"], 20, 45641)
	if db.bloomwarn then
		self:DelayedMessage(15, L["bloom_message"], "Attention")
	end
	for i = 1, #bloomed do bloomed[i] = nil end
end

function mod:UNIT_HEALTH(msg)
	if UnitName(msg) == boss and db.sinister then
		self:CheckSinisterHealth(UnitHealth(msg), UnitHealthMax(msg))
	end
end

function mod:BigWigs_RecvSync(sync, rest, nick)
	if self:ValidateEngageSync(sync, rest) and not started then
		started = true
		phase = 1
		sinister1 = nil
		sinister2 = nil
		sinister3 = nil
		twominuteaudioStarted = nil
		for k in pairs(focusAlerts) do
			focusAlerts[k] = nil
		end
		self:ResetFocusHealthWatcher("KJFocusHealth")
		if self:IsEventRegistered("PLAYER_REGEN_DISABLED") then
			self:UnregisterEvent("PLAYER_REGEN_DISABLED")
		end
	end
end

