/*
 * Copyright (C) 
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "ScriptedEscortAI.h"
#include "Player.h"

enum LightOfDawnSays
{
    SAY_LIGHT_OF_DAWN01               = 0, // pre text
    SAY_LIGHT_OF_DAWN02               = 1,
    SAY_LIGHT_OF_DAWN03               = 2,
    SAY_LIGHT_OF_DAWN04               = 3, // intro
    SAY_LIGHT_OF_DAWN05               = 4,
    SAY_LIGHT_OF_DAWN06               = 5,
    SAY_LIGHT_OF_DAWN07               = 6, // During the fight - Korfax, Champion of the Light
    SAY_LIGHT_OF_DAWN08               = 7, // Lord Maxwell Tyrosus
    SAY_LIGHT_OF_DAWN09               = 8, // Highlord Darion Mograine
    SAY_LIGHT_OF_DAWN25               = 24, // After the fight
    SAY_LIGHT_OF_DAWN26               = 25, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN27               = 26, // Highlord Darion Mograine
    SAY_LIGHT_OF_DAWN28               = 27, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN29               = 28, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN30               = 29, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN31               = 30, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN32               = 31, // Highlord Alexandros Mograine
    SAY_LIGHT_OF_DAWN33               = 32, // Highlord Darion Mograine
    SAY_LIGHT_OF_DAWN34               = 33, // Highlord Darion Mograine
    SAY_LIGHT_OF_DAWN35               = 34, // Darion Mograine
    SAY_LIGHT_OF_DAWN36               = 35, // Darion Mograine
    SAY_LIGHT_OF_DAWN37               = 36, // Highlord Alexandros Mograine
    SAY_LIGHT_OF_DAWN38               = 37, // Darion Mograine
    SAY_LIGHT_OF_DAWN39               = 38, // Highlord Alexandros Mograine
    SAY_LIGHT_OF_DAWN40               = 39, // Darion Mograine
    SAY_LIGHT_OF_DAWN41               = 40, // Highlord Alexandros Mograine
    SAY_LIGHT_OF_DAWN42               = 41, // Highlord Alexandros Mograine
    SAY_LIGHT_OF_DAWN43               = 42, // The Lich King
    SAY_LIGHT_OF_DAWN44               = 43, // Highlord Darion Mograine
    SAY_LIGHT_OF_DAWN45               = 44, // The Lich King
    SAY_LIGHT_OF_DAWN46               = 45, // The Lich King
    SAY_LIGHT_OF_DAWN47               = 46, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN48               = 47, // The Lich King
    SAY_LIGHT_OF_DAWN49               = 48, // The Lich King
    SAY_LIGHT_OF_DAWN50               = 49, // Lord Maxwell Tyrosus
    SAY_LIGHT_OF_DAWN51               = 50, // The Lich King
    SAY_LIGHT_OF_DAWN52               = 51, // Highlord Darion Mograine
    SAY_LIGHT_OF_DAWN53               = 52, // Highlord Darion Mograine
    SAY_LIGHT_OF_DAWN54               = 53, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN55               = 54, // The Lich King
    SAY_LIGHT_OF_DAWN56               = 55, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN57               = 56, // The Lich King
    SAY_LIGHT_OF_DAWN58               = 57, // The Lich King
    SAY_LIGHT_OF_DAWN59               = 58, // The Lich King
    SAY_LIGHT_OF_DAWN60               = 59, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN61               = 60, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN62               = 61, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN63               = 62, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN64               = 63, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN65               = 64, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN66               = 65, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN67               = 66, // Highlord Tirion Fordring
    SAY_LIGHT_OF_DAWN68               = 67, // Highlord Darion Mograine

    EMOTE_LIGHT_OF_DAWN01             = 68,  // Emotes
    EMOTE_LIGHT_OF_DAWN02             = 69,
    EMOTE_LIGHT_OF_DAWN03             = 70,
    EMOTE_LIGHT_OF_DAWN04             = 71,
    EMOTE_LIGHT_OF_DAWN05             = 72,
    EMOTE_LIGHT_OF_DAWN06             = 73,
    EMOTE_LIGHT_OF_DAWN07             = 74,
    EMOTE_LIGHT_OF_DAWN08             = 75,
    EMOTE_LIGHT_OF_DAWN09             = 76,
    EMOTE_LIGHT_OF_DAWN10             = 77,
    EMOTE_LIGHT_OF_DAWN11             = 78,
    EMOTE_LIGHT_OF_DAWN12             = 79,
    EMOTE_LIGHT_OF_DAWN13             = 80,
    EMOTE_LIGHT_OF_DAWN14             = 81,
    EMOTE_LIGHT_OF_DAWN15             = 82,
    EMOTE_LIGHT_OF_DAWN16             = 83,
    EMOTE_LIGHT_OF_DAWN17             = 84,
    EMOTE_LIGHT_OF_DAWN18             = 85
};

enum LightOfDawnEncounter
{
	// Intro Events
	EVENT_START_COUNTDOWN_1				= 1,
	EVENT_START_COUNTDOWN_2,
	EVENT_START_COUNTDOWN_3,
	EVENT_START_COUNTDOWN_4,
	EVENT_START_COUNTDOWN_5,
	EVENT_START_COUNTDOWN_6,
	EVENT_START_COUNTDOWN_7,
	EVENT_START_COUNTDOWN_8,
	EVENT_START_COUNTDOWN_9,
	EVENT_START_COUNTDOWN_10,
	EVENT_START_COUNTDOWN_11,
	EVENT_START_COUNTDOWN_12,
	EVENT_START_COUNTDOWN_13,
	EVENT_START_COUNTDOWN_14,
	// Fight Events
	EVENT_SPELL_ANTI_MAGIC_ZONE,
	EVENT_SPELL_DEATH_STRIKE,
	EVENT_SPELL_DEATH_EMBRACE,
	EVENT_SPELL_UNHOLY_BLIGHT,
	EVENT_SPELL_TALK,
	// Positioning
	EVENT_FINISH_FIGHT_1,
	EVENT_FINISH_FIGHT_2,
	EVENT_FINISH_FIGHT_3,
	EVENT_FINISH_FIGHT_4,
	EVENT_FINISH_FIGHT_5,
	// Outro
	EVENT_OUTRO_SCENE_1,
	EVENT_OUTRO_SCENE_2,
	EVENT_OUTRO_SCENE_3,
	EVENT_OUTRO_SCENE_4,
	EVENT_OUTRO_SCENE_5,
	EVENT_OUTRO_SCENE_6,
	EVENT_OUTRO_SCENE_7,
	EVENT_OUTRO_SCENE_8,
	EVENT_OUTRO_SCENE_9,
	EVENT_OUTRO_SCENE_10,
	EVENT_OUTRO_SCENE_11,
	EVENT_OUTRO_SCENE_12,
	EVENT_OUTRO_SCENE_13,
	EVENT_OUTRO_SCENE_14,
	EVENT_OUTRO_SCENE_15,
	EVENT_OUTRO_SCENE_16,
	EVENT_OUTRO_SCENE_17,
	EVENT_OUTRO_SCENE_18,
	EVENT_OUTRO_SCENE_19,
	EVENT_OUTRO_SCENE_20,
	EVENT_OUTRO_SCENE_21,
	EVENT_OUTRO_SCENE_22,
	EVENT_OUTRO_SCENE_23,
	EVENT_OUTRO_SCENE_24,
	EVENT_OUTRO_SCENE_25,
	EVENT_OUTRO_SCENE_26,
	EVENT_OUTRO_SCENE_27,
	EVENT_OUTRO_SCENE_28,
	EVENT_OUTRO_SCENE_29,
	EVENT_OUTRO_SCENE_30,
	EVENT_OUTRO_SCENE_31,
	EVENT_OUTRO_SCENE_32,
	EVENT_OUTRO_SCENE_33,
	EVENT_OUTRO_SCENE_34,
	EVENT_OUTRO_SCENE_35,
	EVENT_OUTRO_SCENE_36,
	EVENT_OUTRO_SCENE_37,
	EVENT_OUTRO_SCENE_38,
	EVENT_OUTRO_SCENE_39,
	EVENT_OUTRO_SCENE_40,
	EVENT_OUTRO_SCENE_41,
	EVENT_OUTRO_SCENE_42,
	EVENT_OUTRO_SCENE_43,
	EVENT_OUTRO_SCENE_44,
	EVENT_OUTRO_SCENE_45,
	EVENT_OUTRO_SCENE_46,
	EVENT_OUTRO_SCENE_47,
	EVENT_OUTRO_SCENE_48,
	EVENT_OUTRO_SCENE_49,
	EVENT_OUTRO_SCENE_50,
	EVENT_OUTRO_SCENE_51,
	EVENT_OUTRO_SCENE_52,
	EVENT_OUTRO_SCENE_53,
	EVENT_OUTRO_SCENE_54,
	EVENT_OUTRO_SCENE_55,
	EVENT_OUTRO_SCENE_56,
	EVENT_OUTRO_SCENE_57,
	EVENT_OUTRO_SCENE_58,
	EVENT_OUTRO_SCENE_59,
	EVENT_OUTRO_SCENE_60,
	EVENT_OUTRO_SCENE_61,

	ACTION_START_EVENT					= 1,
	ACTION_PLAY_EMOTE					= 1,
	ACTION_POSITION_NPCS				= 2,

	ENCOUNTER_START_TIME				= 5,
	ENCOUNTER_TOTAL_DEFENDERS			= 300,
    ENCOUNTER_TOTAL_SCOURGE				= 10000,

	WORLD_STATE_DEFENDERS_COUNT			= 3590,
	WORLD_STATE_SCOURGE_COUNT			= 3591,
    WORLD_STATE_SOLDIERS_ENABLE			= 3592,
    WORLD_STATE_COUNTDOWN_ENABLE		= 3603,
	WORLD_STATE_COUNTDOWN_TIME			= 3604,
    WORLD_STATE_EVENT_BEGIN_ENABLE		= 3605,

	ENCOUNTER_STATE_NONE				= 0,
	ENCOUNTER_STATE_FIGHT				= 1,
	ENCOUNTER_STATE_OUTRO				= 2,
};

enum LightOfDawnNPCs
{
	// Defenders
	NPC_DEFENDER_OF_THE_LIGHT			= 29174,
    NPC_KORFAX_CHAMPION_OF_THE_LIGHT	= 29176,
	NPC_COMMANDER_ELIGOR_DAWNBRINGER	= 29177,
    NPC_LORD_MAXWELL_TYROSUS			= 29178,
    NPC_LEONID_BARTHALOMEW_THE_REVERED	= 29179,
    NPC_DUKE_NICHOLAS_ZVERENHOFF		= 29180,
    NPC_RAYNE							= 29181,
	NPC_RIMBLAT_EARTHSHATTER			= 29182,

	// Scourge
	NPC_RAMPAGING_ABOMINATION			= 29186,
    NPC_ACHERUS_GHOUL					= 29219,
    NPC_WARRIOR_OF_THE_FROZEN_WASTES	= 29206,
    NPC_FLESH_BEHEMOTH					= 29190,

	NPC_HIGHLORD_DARION_MOGRAINE		= 29173,
	NPC_KOLTIRA_DEATHWEAVER				= 29199,
    NPC_ORBAZ_BLOODBANE					= 29204,
    NPC_THASSARIAN						= 29200,

	// Outro
	NPC_HIGHLORD_TIRION_FORDRING		= 29175,
	NPC_HIGHLORD_ALEXANDROS_MOGRAINE	= 29227, // ghost
    NPC_DARION_MOGRAINE					= 29228, // ghost
	NPC_THE_LICH_KING					= 29183,
};

enum LightOfDawnGOs
{
	GO_HOLY_LIGHTNING					= 191301,
    GO_LIGHT_OF_DAWN					= 191330
};

enum LightOfDawnSpells
{
	// Intro Spells
	SPELL_CAMERA_SHAKE_INIT				= 36455,
	SPELL_CAMERA_SHAKE					= 39983,
	SPELL_THE_MIGHT_OF_MOGRAINE			= 53642,

	// Mograine Fight
	SPELL_ANTI_MAGIC_ZONE1				= 52893,
    SPELL_DEATH_STRIKE					= 53639,
    SPELL_DEATH_EMBRACE					= 53635,
    SPELL_ICY_TOUCH1					= 49723,
    SPELL_UNHOLY_BLIGHT					= 53640,

	// Outro
	SPELL_THE_LIGHT_OF_DAWN				= 53658,
	SPELL_ALEXANDROS_MOGRAINE_SPAWN		= 53667,
	SPELL_ICEBOUND_VISAGE				= 53274,
    SPELL_SOUL_FEAST_ALEX				= 53677,
	SPELL_MOGRAINE_CHARGE				= 53679,
	SPELL_REBUKE						= 53680,
	SPELL_SOUL_FEAST_TIRION				= 53685,
	SPELL_APOCALYPSE					= 53210,
	SPELL_THROW_ASHBRINGER				= 53701,
	SPELL_REBIRTH_OF_THE_ASHBRINGER		= 53702,
	SPELL_TIRION_CHARGE					= 53705,
	SPELL_EXIT_TELEPORT_VISUAL			= 61456,
	SPELL_LAY_ON_HANDS					= 53778,
    SPELL_THE_LIGHT_OF_DAWN_Q			= 53606
};

const Position LightOfDawnPos[] =
{
	{2304.2f, -5290.7f, 82.01f, 4.56f},			// 0  First Home Pos
	{2253.5f, -5310.6f, 82.17f, 5.28f},			// 1  Second Home Pos
	{2169.1f, -5227.1f, 82.59f, 5.7f},			// 2  Orbaz Flee Pos
	{2289.259f, -5280.355f, 86.112f, 4.41f},	// 3  Koltira Loc1
    {2273.289f, -5273.675f, 86.701f, 5.01f},	// 4  Thassarian Loc1
	{2280.81f, -5284.09f, 86.608f, 4.76f},		// 5  Morgraine Loc1
	{2281.335f, -5300.409f, 85.170f, 1.528f},   // 6  Tirion Summon loc
	{2281.198f, -5257.397f, 80.224f, 4.66f},	// 7  Alexandros loc1
    {2281.156f, -5259.934f, 80.647f, 0},		// 8  Alexandros loc2
	{2281.294f, -5281.895f, 82.445f, 1.35f},	// 9  Darion loc1
    {2281.093f, -5263.013f, 81.125f, 0},		// 10 Darion loc2
	{2283.896f, -5287.914f, 83.066f, 1.55f},	// 11 Tirion Fordring loc2
	{2281.313f, -5250.282f, 79.322f, 4.69f},	// 12 Lich King spawns
    {2281.523f, -5261.058f, 80.877f, 0},		// 13 Lich king moves forward
	{2264.27f, -5267.29f, 80.16f, 0},			// 14 Tirion Fordring loc3
	{2270.99f, -5278.00f, 81.89f, 0}			// 15 Tirion Fordring loc4
};

const Position LightOfDawnFightPos[] = 
{
	{2279.68f, -5256.75f, 79.79f, 4.8f},
	{2280.40f, -5276.56f, 82.11f, 4.8f},
	{2256.43f, -5281.3f, 82.29f, 5.0f},
	{2251.87f, -5304.08f, 82.17f, 4.8f},
	{2244.88f, -5256.03f, 74.88f, 5.8f},
	{2294.29f, -5281.35f, 81.91f, 4.8f},
	{2314.2f, -5268.1f, 82.43f, 3.6f},
	{2289.72f, -5299.65f, 83.49f, 3.2f},
	{2274.02f, -5303.58f, 85.05f, 1.4f},
	{2258.42f, -5307.72f, 81.98f, 0.1f}
};

class DelayedSummonEvent : public BasicEvent
{
	public:
		DelayedSummonEvent(Unit* owner, uint32 entry, Position pos) : _owner(owner), _entry(entry), _pos(pos) { }

		bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
		{
			_owner->SummonCreature(_entry, _pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
			return true;
		}

	private:
		Unit* _owner;
		uint32 _entry;
		Position _pos;
};

class npc_highlord_darion_mograine : public CreatureScript
{
public:
    npc_highlord_darion_mograine() : CreatureScript("npc_highlord_darion_mograine") { }

    CreatureAI* GetAI(Creature* creature) const
    {
        return new npc_highlord_darion_mograineAI(creature);
    }

    bool OnGossipHello(Player* player, Creature* creature)
    {
        if (creature->IsQuestGiver())
            player->PrepareQuestMenu(creature->GetGUID());

		if (player->GetQuestStatus(12801) == QUEST_STATUS_INCOMPLETE && !creature->AI()->GetData(WORLD_STATE_SOLDIERS_ENABLE))
            player->ADD_GOSSIP_ITEM(0, "I am ready, Highlord. Let the siege of Light's Hope begin!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);

        player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());

        return true;
    }

    bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
    {
		if (action == GOSSIP_ACTION_INFO_DEF+1)
		{
			player->PlayerTalkClass->ClearMenus();
			player->CLOSE_GOSSIP_MENU();
			creature->AI()->DoAction(ACTION_START_EVENT);
		}
        return true;
    }

    struct npc_highlord_darion_mograineAI : public ScriptedAI
    {
        npc_highlord_darion_mograineAI(Creature* creature) : ScriptedAI(creature), summons(me)
        {
			battleStarted = ENCOUNTER_STATE_NONE;
			me->SetCorpseDelay(3*60);
			me->SetRespawnTime(3*60);
			resetExecuted = false;
        }

		EventMap events;
		SummonList summons;
		uint32 startTimeRemaining;
		uint32 defendersRemaining;
		uint32 scourgeRemaining;
		uint8 battleStarted;
		bool resetExecuted;

		void DoAction(int32 param)
		{
			if (param == ACTION_START_EVENT && !startTimeRemaining && events.Empty())
			{
				Talk(SAY_LIGHT_OF_DAWN01);

				startTimeRemaining = ENCOUNTER_START_TIME;
				defendersRemaining = ENCOUNTER_TOTAL_DEFENDERS;
				scourgeRemaining = ENCOUNTER_TOTAL_SCOURGE;

				SendInitialWorldStates();

				events.Reset();
				events.ScheduleEvent(EVENT_START_COUNTDOWN_1, 60000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_2, 120000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_3, 180000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_4, 240000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_5, 300000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_6, 308000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_7, 312000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_8, 316000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_9, 320000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_10, 324000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_11, 332000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_12, 335000);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_13, 337500);
				events.ScheduleEvent(EVENT_START_COUNTDOWN_14, 345000);
			}
		}

		uint32 GetData(uint32 type) const
		{
			switch (type)
			{
				case WORLD_STATE_DEFENDERS_COUNT: return defendersRemaining;
				case WORLD_STATE_SCOURGE_COUNT:	return scourgeRemaining;
				case WORLD_STATE_SOLDIERS_ENABLE: return me->IsAlive() && (startTimeRemaining || battleStarted);
				case WORLD_STATE_COUNTDOWN_ENABLE: return me->IsAlive() && startTimeRemaining;
				case WORLD_STATE_COUNTDOWN_TIME: return startTimeRemaining;
				case WORLD_STATE_EVENT_BEGIN_ENABLE: return me->IsAlive() && !startTimeRemaining && battleStarted;
			}
			return 0;
		}

		void SendUpdateWorldState(uint32 id, uint32 state)
		{
			Map::PlayerList const& players = me->GetMap()->GetPlayers();
			if (!players.isEmpty())
				for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
					if (Player* player = itr->GetSource())
						if (player->GetPhaseMask() & 128) // Xinef: client skips players without chapter 5 aura anyway, speedup
							player->SendUpdateWorldState(id, state);
		}

		void SendInitialWorldStates()
		{
			SendUpdateWorldState(WORLD_STATE_DEFENDERS_COUNT, GetData(WORLD_STATE_DEFENDERS_COUNT));
			SendUpdateWorldState(WORLD_STATE_SCOURGE_COUNT, GetData(WORLD_STATE_SCOURGE_COUNT));
			SendUpdateWorldState(WORLD_STATE_SOLDIERS_ENABLE, GetData(WORLD_STATE_SOLDIERS_ENABLE));
			SendUpdateWorldState(WORLD_STATE_COUNTDOWN_ENABLE, GetData(WORLD_STATE_COUNTDOWN_ENABLE));
			SendUpdateWorldState(WORLD_STATE_COUNTDOWN_TIME, GetData(WORLD_STATE_COUNTDOWN_TIME));
			SendUpdateWorldState(WORLD_STATE_EVENT_BEGIN_ENABLE, GetData(WORLD_STATE_EVENT_BEGIN_ENABLE));
		}

		void JustSummoned(Creature* cr)
		{
			summons.Summon(cr);

			if (me->IsInCombat() && cr->GetEntry() != NPC_HIGHLORD_TIRION_FORDRING && battleStarted == ENCOUNTER_STATE_FIGHT)
			{
				Position pos = LightOfDawnFightPos[urand(0, 9)];
				if (Unit* target = cr->SelectNearbyTarget(NULL, 10.0f))
					if (target->GetTypeId() == TYPEID_UNIT)
						target->GetMotionMaster()->MoveCharge(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), me->GetSpeed(MOVE_RUN));
				cr->GetMotionMaster()->MoveCharge(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), me->GetSpeed(MOVE_RUN));
			}

			if (battleStarted == ENCOUNTER_STATE_OUTRO && cr->GetEntry() == NPC_DEFENDER_OF_THE_LIGHT)
			{
				cr->SetReactState(REACT_PASSIVE);
				cr->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
				cr->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H);
				cr->HandleEmoteCommand(EMOTE_STATE_READY1H);
			}
		}

		void SummonedCreatureDies(Creature* creature, Unit*)
		{
			// Refill Armies and update counters
			if (battleStarted != ENCOUNTER_STATE_FIGHT)
				return;

			me->m_Events.AddEvent(new DelayedSummonEvent(me, creature->GetEntry(), *creature), me->m_Events.CalculateTime(3000));
			if (creature->GetEntry() >= NPC_RAMPAGING_ABOMINATION)
			{
				--scourgeRemaining;
				SendUpdateWorldState(WORLD_STATE_SCOURGE_COUNT, GetData(WORLD_STATE_SCOURGE_COUNT));
			}
			else
			{
				--defendersRemaining;
				SendUpdateWorldState(WORLD_STATE_DEFENDERS_COUNT, GetData(WORLD_STATE_DEFENDERS_COUNT));

				if (defendersRemaining == 200)
					FinishFight();
			}
		}

		void JustDied(Unit*)
		{
			summons.DespawnAll();
			me->SetCorpseDelay(3*60);
			me->SetRespawnTime(3*60);
		}

		void FinishFight()
		{
			if (Creature* tirion = me->SummonCreature(NPC_HIGHLORD_TIRION_FORDRING, LightOfDawnPos[6], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000))
            {
				tirion->LoadEquipment(0, true);
                tirion->AI()->Talk(SAY_LIGHT_OF_DAWN25);
				events.Reset();
				events.ScheduleEvent(EVENT_FINISH_FIGHT_1, 10000);
				events.ScheduleEvent(EVENT_FINISH_FIGHT_2, 20000);
				events.ScheduleEvent(EVENT_FINISH_FIGHT_3, 22000);
				events.ScheduleEvent(EVENT_FINISH_FIGHT_4, 23000);
				events.ScheduleEvent(EVENT_FINISH_FIGHT_5, 24000);

				tirion->SummonGameObject(GO_HOLY_LIGHTNING, 2254.84f, -5298.75f, 82.168f, 1.134f, 0, 0, 0.537102f, 0.843517f, 20);
				tirion->SummonGameObject(GO_HOLY_LIGHTNING, 2296.24f, -5296.44f, 81.9964f, 5.3398f, 0, 0, 0.454395f, -0.8908f, 20);
				tirion->SummonGameObject(GO_HOLY_LIGHTNING, 2314.29f, -5261.78f, 83.1349f, 3.05822f, 0, 0, 0.999131f, 0.0416735f, 20);
				tirion->SummonGameObject(GO_HOLY_LIGHTNING, 2278.43f, -5270.14f, 81.7247f, 0.70988f, 0, 0, 0.347534f, 0.937667f, 20);
            }
		}

		void EnterCombat(Unit*)
		{
			if (battleStarted != ENCOUNTER_STATE_FIGHT)
				return;

			events.RescheduleEvent(EVENT_SPELL_ANTI_MAGIC_ZONE, 15000);
			events.RescheduleEvent(EVENT_SPELL_DEATH_STRIKE, 8000);
			events.RescheduleEvent(EVENT_SPELL_DEATH_EMBRACE, 5000);
			events.RescheduleEvent(EVENT_SPELL_UNHOLY_BLIGHT, 10000);
			events.RescheduleEvent(EVENT_SPELL_TALK, 10000);
		}

		void Reset()
		{
			if (resetExecuted)
				return;

			resetExecuted = true;
			JustRespawned();
		}

		void JustRespawned()
        {
			events.Reset();
			summons.DespawnAll();

			me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
			me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
			me->SetStandState(UNIT_STAND_STATE_STAND);
            me->SetVisible(true);
			me->setActive(true);
			me->SetWalk(false);

			battleStarted = ENCOUNTER_STATE_NONE;
			startTimeRemaining = 0;
			defendersRemaining = 0;
			scourgeRemaining = 0;

			SendInitialWorldStates();
			me->SummonCreatureGroup(30);
		}

		Creature* GetEntryFromSummons(uint32 entry)
		{
			for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
				if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
					if (summon->GetEntry() == entry)
						return summon;
			return NULL;
		}

		void MovementInform(uint32 type, uint32 point)
		{
			if (type == POINT_MOTION_TYPE && point == 2)
			{
				me->RemoveAurasDueToSpell(SPELL_THE_LIGHT_OF_DAWN);
				Talk(EMOTE_LIGHT_OF_DAWN05);
				events.Reset();

				events.ScheduleEvent(EVENT_OUTRO_SCENE_1, 2000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_2, 19000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_3, 38000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_4, 50000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_5, 62000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_6, 68000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_7, 71000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_8, 72000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_9, 74000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_10, 77000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_11, 79000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_12, 82000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_13, 85000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_14, 92000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_15, 98000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_16, 105000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_17, 120000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_18, 131000);
				events.ScheduleEvent(EVENT_OUTRO_SCENE_19, 158000);
			}
		}

		void UpdateAI(uint32 diff)
        {
			events.Update(diff);
			uint32 eventId = events.ExecuteEvent();

			switch (eventId)
			{
				case EVENT_START_COUNTDOWN_1:
					SendUpdateWorldState(WORLD_STATE_COUNTDOWN_TIME, 4);
					break;
				case EVENT_START_COUNTDOWN_2:
					SendUpdateWorldState(WORLD_STATE_COUNTDOWN_TIME, 3);
					break;
				case EVENT_START_COUNTDOWN_3:
					SendUpdateWorldState(WORLD_STATE_COUNTDOWN_TIME, 2);
					break;
				case EVENT_START_COUNTDOWN_4:
					Talk(SAY_LIGHT_OF_DAWN02);
					SendUpdateWorldState(WORLD_STATE_COUNTDOWN_TIME, 1);
					break;
				case EVENT_START_COUNTDOWN_5:
					battleStarted = ENCOUNTER_STATE_FIGHT;
					me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
					Talk(SAY_LIGHT_OF_DAWN04); // Wrong order in DB!
					SendUpdateWorldState(WORLD_STATE_COUNTDOWN_TIME, 0);
					SendUpdateWorldState(WORLD_STATE_COUNTDOWN_ENABLE, 0);
					SendUpdateWorldState(WORLD_STATE_EVENT_BEGIN_ENABLE, 1);
					break;
				case EVENT_START_COUNTDOWN_6:
				case EVENT_START_COUNTDOWN_7:
				case EVENT_START_COUNTDOWN_8:
				case EVENT_START_COUNTDOWN_9:
				case EVENT_START_COUNTDOWN_10:
					if (eventId == EVENT_START_COUNTDOWN_6)
					{
						Talk(SAY_LIGHT_OF_DAWN05);
						me->CastSpell(me, SPELL_CAMERA_SHAKE_INIT, true);
					}
					else
						me->CastSpell(me, SPELL_CAMERA_SHAKE, true);
					me->SummonCreatureGroup(eventId - EVENT_START_COUNTDOWN_6);
					break;
				case EVENT_START_COUNTDOWN_11:
					Talk(SAY_LIGHT_OF_DAWN06);
					break;
				case EVENT_START_COUNTDOWN_12:
					summons.DoAction(ACTION_PLAY_EMOTE);
					break;
				case EVENT_START_COUNTDOWN_13:
				{
					uint8 first = 1;
					for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
					{
						if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
						{
							Position pos = LightOfDawnPos[first];
							summon->SetHomePosition(pos);
							summon->GetMotionMaster()->MovePoint(1, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true, false);
						}
						first = first == 0 ? 1 : 0;
					}
					Position pos = LightOfDawnPos[first];
					me->SetHomePosition(pos);
					me->SetWalk(false);
					me->GetMotionMaster()->MovePoint(1, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true, true);
					me->CastSpell(me, SPELL_THE_MIGHT_OF_MOGRAINE, true);
					break;
				}
				case EVENT_START_COUNTDOWN_14:
					me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
					me->SummonCreatureGroup(5);
					return;
				case EVENT_FINISH_FIGHT_1:
					summons.DespawnEntry(NPC_DEFENDER_OF_THE_LIGHT);
					battleStarted = ENCOUNTER_STATE_OUTRO;
					break;
				case EVENT_FINISH_FIGHT_2:
				{
					summons.DespawnEntry(NPC_RAMPAGING_ABOMINATION);
					summons.DespawnEntry(NPC_ACHERUS_GHOUL);
					summons.DespawnEntry(NPC_WARRIOR_OF_THE_FROZEN_WASTES);
					summons.DespawnEntry(NPC_FLESH_BEHEMOTH);
					summons.DespawnEntry(NPC_DEFENDER_OF_THE_LIGHT);					

					if (Creature* orbaz = GetEntryFromSummons(NPC_ORBAZ_BLOODBANE))
					{
						orbaz->SetReactState(REACT_PASSIVE);
						orbaz->AI()->Talk(EMOTE_LIGHT_OF_DAWN04);
						orbaz->GetMotionMaster()->MovePoint(2, LightOfDawnPos[2], true, true);
						orbaz->DespawnOrUnsummon(7000);
					}

					for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
						if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
						{
							summon->CombatStop(true);
							summon->DeleteThreatList();
							summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
							summon->SetReactState(REACT_PASSIVE);
							summon->GetMotionMaster()->Clear(false);
						}
					me->CombatStop(true);
					me->DeleteThreatList();
					me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
					me->SetReactState(REACT_PASSIVE);
					me->GetMotionMaster()->Clear(false);

					// Position main stars
					summons.DoAction(ACTION_POSITION_NPCS);

					me->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, 2276.66f, -5273.60f, 81.86f, 5.14f, TEMPSUMMON_CORPSE_DESPAWN);
					me->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, 2272.11f, -5279.08f, 82.01f, 5.69f, TEMPSUMMON_CORPSE_DESPAWN);
					me->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, 2285.11f, -5276.73f, 82.08f, 4.23f, TEMPSUMMON_CORPSE_DESPAWN);
					me->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, 2290.06f, -5286.41f, 82.51f, 3.16f, TEMPSUMMON_CORPSE_DESPAWN);
					break;
				}
				case EVENT_FINISH_FIGHT_3:
					if (Creature* koltira = GetEntryFromSummons(NPC_KOLTIRA_DEATHWEAVER))
					{
						koltira->SetWalk(true);
						koltira->SetHomePosition(*koltira);
						koltira->CastSpell(koltira, SPELL_THE_LIGHT_OF_DAWN, false);
						koltira->GetMotionMaster()->MoveCharge(LightOfDawnPos[3].GetPositionX(), LightOfDawnPos[3].GetPositionY(), LightOfDawnPos[3].GetPositionZ(), 4.0f, 2);
					}
					break;
				case EVENT_FINISH_FIGHT_4:
					if (Creature* thassarin = GetEntryFromSummons(NPC_THASSARIAN))
					{
						thassarin->SetWalk(true);
						thassarin->SetHomePosition(*thassarin);
						thassarin->CastSpell(thassarin, SPELL_THE_LIGHT_OF_DAWN, false);
						thassarin->GetMotionMaster()->MoveCharge(LightOfDawnPos[4].GetPositionX(), LightOfDawnPos[4].GetPositionY(), LightOfDawnPos[4].GetPositionZ(), 4.0f, 2);
					}
					break;
				case EVENT_FINISH_FIGHT_5:
					me->SetWalk(true);
					me->SetHomePosition(*me);
					me->RemoveAllAuras();
					me->CastSpell(me, SPELL_THE_LIGHT_OF_DAWN, false);
					me->GetMotionMaster()->MoveCharge(LightOfDawnPos[5].GetPositionX(), LightOfDawnPos[5].GetPositionY(), LightOfDawnPos[5].GetPositionZ(), 4.0f, 2);

					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN26);
					break;
				case EVENT_OUTRO_SCENE_1:
					me->SetStandState(UNIT_STAND_STATE_KNEEL);
					me->SetFacingTo(4.8f);
					Talk(SAY_LIGHT_OF_DAWN27);
					break;
				case EVENT_OUTRO_SCENE_2:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN28);
					break;
				case EVENT_OUTRO_SCENE_3:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN29);
					break;
				case EVENT_OUTRO_SCENE_4:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN30);
					break;
				case EVENT_OUTRO_SCENE_5:
					me->SetStandState(UNIT_STAND_STATE_STAND);
					Talk(SAY_LIGHT_OF_DAWN31);
					break;
				case EVENT_OUTRO_SCENE_6:
					if (Creature* alex = me->SummonCreature(NPC_HIGHLORD_ALEXANDROS_MOGRAINE, LightOfDawnPos[7].GetPositionX(), LightOfDawnPos[7].GetPositionY(), LightOfDawnPos[7].GetPositionZ(), LightOfDawnPos[7].GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000))
                    {
                        alex->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
						alex->GetMotionMaster()->MovePoint(0, LightOfDawnPos[8].GetPositionX(), LightOfDawnPos[8].GetPositionY(), LightOfDawnPos[8].GetPositionZ());
                        alex->CastSpell(alex, SPELL_ALEXANDROS_MOGRAINE_SPAWN, true);
                        //alex->AI()->Talk(EMOTE_LIGHT_OF_DAWN06);
                    }
                    break;
				case EVENT_OUTRO_SCENE_7:
                    if (Creature* alex = GetEntryFromSummons(NPC_HIGHLORD_ALEXANDROS_MOGRAINE))
                    {
                        alex->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                        alex->AI()->Talk(SAY_LIGHT_OF_DAWN32);
						me->SetFacingToObject(alex);
                    }
                    break;
				case EVENT_OUTRO_SCENE_8:
					Talk(SAY_LIGHT_OF_DAWN33);
					break;
                case EVENT_OUTRO_SCENE_9:
                    me->SetStandState(UNIT_STAND_STATE_KNEEL);
                    Talk(SAY_LIGHT_OF_DAWN34);
                    break;
                case EVENT_OUTRO_SCENE_10:
                    if (Creature* darion = me->SummonCreature(NPC_DARION_MOGRAINE, LightOfDawnPos[9].GetPositionX(), LightOfDawnPos[9].GetPositionY(), LightOfDawnPos[9].GetPositionZ(), LightOfDawnPos[9].GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000))
                    {
                        darion->AI()->Talk(SAY_LIGHT_OF_DAWN35);
                        darion->SetWalk(false);
                    }
                    break;
                case EVENT_OUTRO_SCENE_11:
                    if (Creature* darion = GetEntryFromSummons(NPC_DARION_MOGRAINE))
                    {
                        //darion->AI()->Talk(EMOTE_LIGHT_OF_DAWN07);
                        darion->GetMotionMaster()->MovePoint(0, LightOfDawnPos[10].GetPositionX(), LightOfDawnPos[10].GetPositionY(), LightOfDawnPos[10].GetPositionZ());
                    }
                    break;
                case EVENT_OUTRO_SCENE_12:
                    if (Creature* darion = GetEntryFromSummons(NPC_DARION_MOGRAINE))
                        darion->AI()->Talk(EMOTE_LIGHT_OF_DAWN08);
                    break;
				case EVENT_OUTRO_SCENE_13:
                    if (Creature* darion = GetEntryFromSummons(NPC_DARION_MOGRAINE))
                        darion->AI()->Talk(SAY_LIGHT_OF_DAWN36);
                    break;
                case EVENT_OUTRO_SCENE_14:
                    if (Creature* alex = GetEntryFromSummons(NPC_HIGHLORD_ALEXANDROS_MOGRAINE))
                        alex->AI()->Talk(SAY_LIGHT_OF_DAWN37);
                    break;
				case EVENT_OUTRO_SCENE_15:
                    if (Creature* darion = GetEntryFromSummons(NPC_DARION_MOGRAINE))
                        darion->AI()->Talk(SAY_LIGHT_OF_DAWN38);
                    break;
                case EVENT_OUTRO_SCENE_16:
                    if (Creature* alex = GetEntryFromSummons(NPC_HIGHLORD_ALEXANDROS_MOGRAINE))
                        alex->AI()->Talk(SAY_LIGHT_OF_DAWN39);

					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
                        tirion->GetMotionMaster()->MovePoint(0, LightOfDawnPos[11].GetPositionX(), LightOfDawnPos[11].GetPositionY(), LightOfDawnPos[11].GetPositionZ());
                    break;
				case EVENT_OUTRO_SCENE_17:
                    if (Creature* darion = GetEntryFromSummons(NPC_DARION_MOGRAINE))
                        darion->AI()->Talk(SAY_LIGHT_OF_DAWN40);
                    break;
                case EVENT_OUTRO_SCENE_18:
                    if (Creature* alex = GetEntryFromSummons(NPC_HIGHLORD_ALEXANDROS_MOGRAINE))
                        alex->AI()->Talk(SAY_LIGHT_OF_DAWN41);

					if (Creature* darion = GetEntryFromSummons(NPC_DARION_MOGRAINE))
						darion->DespawnOrUnsummon(3000);
                    break;
                case EVENT_OUTRO_SCENE_19:
                    if (Creature* alex = GetEntryFromSummons(NPC_HIGHLORD_ALEXANDROS_MOGRAINE))
                        alex->AI()->Talk(SAY_LIGHT_OF_DAWN42);

					events.Reset();
					events.ScheduleEvent(EVENT_OUTRO_SCENE_20, 4000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_21, 4500);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_22, 7000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_23, 9000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_24, 14000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_25, 21200);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_26, 22500);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_27, 24000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_28, 28000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_29, 34000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_30, 36000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_31, 51000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_32, 68000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_33, 73000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_34, 76000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_35, 77000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_36, 81000);
                    break;
				case EVENT_OUTRO_SCENE_20:
					if (Creature* lk = me->SummonCreature(NPC_THE_LICH_KING, LightOfDawnPos[12].GetPositionX(), LightOfDawnPos[12].GetPositionY(), LightOfDawnPos[12].GetPositionZ(), LightOfDawnPos[12].GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000))
                        lk->AI()->Talk(SAY_LIGHT_OF_DAWN43);
                    break;
				case EVENT_OUTRO_SCENE_21:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
                        lk->CastSpell(lk, SPELL_ICEBOUND_VISAGE, true);
                    break;
                case EVENT_OUTRO_SCENE_22:
                    if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
                    {
                        lk->AI()->Talk(SAY_LIGHT_OF_DAWN45);
                        if (Creature* alex = GetEntryFromSummons(NPC_HIGHLORD_ALEXANDROS_MOGRAINE))
						{
							alex->RemoveAllAuras();
                            lk->CastSpell(alex, SPELL_SOUL_FEAST_ALEX, false);
						}
                    }
                    break;
				case EVENT_OUTRO_SCENE_23:
                    if (Creature* alex = GetEntryFromSummons(NPC_HIGHLORD_ALEXANDROS_MOGRAINE))
                    {
						alex->DespawnOrUnsummon(5000);
                        alex->SetVisible(false);
                    }
                    break;
				case EVENT_OUTRO_SCENE_24:
                    me->SetStandState(UNIT_STAND_STATE_STAND);
                    Talk(SAY_LIGHT_OF_DAWN44);
                    break;
                case EVENT_OUTRO_SCENE_25:
                    if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
                        lk->GetMotionMaster()->MovePoint(0, LightOfDawnPos[13].GetPositionX(), LightOfDawnPos[13].GetPositionY(), LightOfDawnPos[13].GetPositionZ());
                    break;
				case EVENT_OUTRO_SCENE_26:
					me->CastSpell(me, SPELL_MOGRAINE_CHARGE, false);
                    break;
				case EVENT_OUTRO_SCENE_27:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
					{
						lk->AI()->Talk(SAY_LIGHT_OF_DAWN46);
						lk->CastSpell(me, SPELL_REBUKE, false);
					}
					break;
				case EVENT_OUTRO_SCENE_28:
                    me->SetStandState(UNIT_STAND_STATE_KNEEL);
                    if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
					{
                        tirion->AI()->Talk(SAY_LIGHT_OF_DAWN47);
						if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
							tirion->SetFacingToObject(lk);
					}
                    break;
				case EVENT_OUTRO_SCENE_29:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
					{
						lk->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH);
						lk->PlayDirectSound(14820);
					}
					break;
				case EVENT_OUTRO_SCENE_30:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
						lk->AI()->Talk(SAY_LIGHT_OF_DAWN48);
					break;
				case EVENT_OUTRO_SCENE_31:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
						lk->AI()->Talk(SAY_LIGHT_OF_DAWN49);
					break;
                case EVENT_OUTRO_SCENE_32:
                    if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
                    {
                        if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
                        {
                            lk->CastSpell(lk, SPELL_SOUL_FEAST_TIRION, false);
                            tirion->AI()->Talk(EMOTE_LIGHT_OF_DAWN12);
                        }

						for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
							if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
								if (summon->GetEntry() <= NPC_RIMBLAT_EARTHSHATTER && summon->GetEntry() != NPC_HIGHLORD_TIRION_FORDRING)
								{
									float o = lk->GetAngle(summon);
									summon->GetMotionMaster()->MovePoint(3, lk->GetPositionX() + 2.0f*cos(o), lk->GetPositionY() + 2.0f*sin(o), lk->GetPositionZ());
									summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_MANUAL_DESPAWN);
								}
					}
                    break;
				case EVENT_OUTRO_SCENE_33:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
					{
						lk->AI()->Talk(SAY_LIGHT_OF_DAWN51);
						lk->CastSpell(lk, SPELL_APOCALYPSE, true);
					}
					break;
				case EVENT_OUTRO_SCENE_34:
					for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
						if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
							if (summon->GetEntry() <= NPC_RIMBLAT_EARTHSHATTER && summon->GetEntry() != NPC_HIGHLORD_TIRION_FORDRING)
								Unit::Kill(summon, summon);
					break;
				case EVENT_OUTRO_SCENE_35:
					Talk(SAY_LIGHT_OF_DAWN52);
					break;
				case EVENT_OUTRO_SCENE_36:
					me->SetStandState(UNIT_STAND_STATE_STAND);
					Talk(SAY_LIGHT_OF_DAWN53);
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						me->SetFacingToObject(tirion);

					events.Reset();
					events.ScheduleEvent(EVENT_OUTRO_SCENE_37, 1000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_38, 5000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_39, 7000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_40, 9000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_41, 13000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_42, 16000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_43, 17000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_44, 19000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_45, 25000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_46, 32000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_47, 42000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_48, 52000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_49, 54000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_50, 58000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_51, 65000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_52, 70000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_53, 84000);
					break;
				case EVENT_OUTRO_SCENE_37:
					me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(EQUIP_UNEQUIP));
					me->CastSpell(me, SPELL_THROW_ASHBRINGER, true);
					break;
				case EVENT_OUTRO_SCENE_38:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
					{
						tirion->RemoveAllAuras();
						tirion->CastSpell(me, SPELL_REBIRTH_OF_THE_ASHBRINGER, true);
						tirion->SummonGameObject(GO_LIGHT_OF_DAWN, tirion->GetPositionX(), tirion->GetPositionY(), tirion->GetPositionZ(), tirion->GetOrientation(), 0, 0, 0, 0, 180);
						tirion->LoadEquipment(1, true);
					}
					me->SetStandState(UNIT_STAND_STATE_DEAD);
					break;
				case EVENT_OUTRO_SCENE_39:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
					{
						tirion->RemoveAllAuras();
						tirion->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
					}
					break;
				case EVENT_OUTRO_SCENE_40:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN54);
					break;
				case EVENT_OUTRO_SCENE_41:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
						lk->AI()->Talk(SAY_LIGHT_OF_DAWN55);
					break;
				case EVENT_OUTRO_SCENE_42:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN56);
					break;
				case EVENT_OUTRO_SCENE_43:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
					{
						tirion->CastSpell(tirion, SPELL_TIRION_CHARGE, true);
						tirion->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
						tirion->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
					}
					break;
				case EVENT_OUTRO_SCENE_44:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
						lk->AI()->Talk(SAY_LIGHT_OF_DAWN57);
					break;
				case EVENT_OUTRO_SCENE_45:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
						lk->AI()->Talk(SAY_LIGHT_OF_DAWN58);
					break;
				case EVENT_OUTRO_SCENE_46:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
						lk->AI()->Talk(SAY_LIGHT_OF_DAWN59);
					break;
				case EVENT_OUTRO_SCENE_47:
					if (Creature* lk = GetEntryFromSummons(NPC_THE_LICH_KING))
					{
						lk->CastSpell(lk, SPELL_EXIT_TELEPORT_VISUAL, true);
						lk->DespawnOrUnsummon(1500);
					}

					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
					{
						float o = me->GetAngle(tirion);
						tirion->GetMotionMaster()->MovePoint(4, me->GetPositionX() + 2.0f*cos(o), me->GetPositionY() + 2.0f*sin(o), me->GetPositionZ(), false);
						tirion->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
						tirion->setFaction(35);
					}
					break;
				case EVENT_OUTRO_SCENE_48:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->CastSpell(me, SPELL_LAY_ON_HANDS, false);
					me->SetStandState(UNIT_STAND_STATE_KNEEL);
					break;
				case EVENT_OUTRO_SCENE_49:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
					{
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN60);
						tirion->SetWalk(true);
					}
					break;
				case EVENT_OUTRO_SCENE_50:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->GetMotionMaster()->MovePoint(4, LightOfDawnPos[14].GetPositionX(), LightOfDawnPos[14].GetPositionY(), LightOfDawnPos[14].GetPositionZ());
					break;
				case EVENT_OUTRO_SCENE_51:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->GetMotionMaster()->MovePoint(4, LightOfDawnPos[15].GetPositionX(), LightOfDawnPos[15].GetPositionY(), LightOfDawnPos[15].GetPositionZ());
					break;
				case EVENT_OUTRO_SCENE_52:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
					{
						tirion->SetFacingToObject(me);
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN61);
					}
					break;
				case EVENT_OUTRO_SCENE_53:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN62);

					events.Reset();
					events.ScheduleEvent(EVENT_OUTRO_SCENE_54, 6000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_55, 14000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_56, 27000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_57, 37000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_58, 44000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_59, 50000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_60, 63000);
					events.ScheduleEvent(EVENT_OUTRO_SCENE_61, 150000);
					break;
				case EVENT_OUTRO_SCENE_54:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN63);
					break;
				case EVENT_OUTRO_SCENE_55:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN64);
					break;
				case EVENT_OUTRO_SCENE_56:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN65);
					break;
				case EVENT_OUTRO_SCENE_57:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN66);
					break;
				case EVENT_OUTRO_SCENE_58:
					if (Creature* tirion = GetEntryFromSummons(NPC_HIGHLORD_TIRION_FORDRING))
						tirion->AI()->Talk(SAY_LIGHT_OF_DAWN67);
					break;
				case EVENT_OUTRO_SCENE_59:
					Talk(SAY_LIGHT_OF_DAWN68);
					me->SetStandState(UNIT_STAND_STATE_STAND);
					break;
				case EVENT_OUTRO_SCENE_60:
				{
                    Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
                    if (!PlayerList.isEmpty())
                    {
                        for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                            if (i->GetSource()->IsAlive() && me->IsWithinDistInMap(i->GetSource(), 100))
                                i->GetSource()->CastSpell(i->GetSource(), SPELL_THE_LIGHT_OF_DAWN_Q, false);
                    }
					me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
					break;
				}
				case EVENT_OUTRO_SCENE_61:
					summons.DespawnAll();
					me->DespawnOrUnsummon(1);
					events.Reset();
					return;
			}

			if (battleStarted != ENCOUNTER_STATE_FIGHT)
				return;

			if (!UpdateVictim())
				return;

			switch (eventId)
			{
				case EVENT_SPELL_ANTI_MAGIC_ZONE:
					DoCast(me, SPELL_ANTI_MAGIC_ZONE1);
					events.RescheduleEvent(eventId, urand(25000, 30000));
					break;
				case EVENT_SPELL_DEATH_STRIKE:
					DoCastVictim(SPELL_DEATH_STRIKE);
					events.RescheduleEvent(eventId, urand(5000, 10000));
					break;
				case EVENT_SPELL_DEATH_EMBRACE:
					DoCastVictim(SPELL_DEATH_EMBRACE);
					events.RescheduleEvent(eventId, urand(15000, 20000));
					break;
				case EVENT_SPELL_UNHOLY_BLIGHT:
					DoCast(me, SPELL_UNHOLY_BLIGHT);
					events.RescheduleEvent(eventId, 60000);
					break;
				case EVENT_SPELL_TALK:
					Talk(SAY_LIGHT_OF_DAWN09);
					events.RescheduleEvent(eventId, urand(15000, 20000));
					break;
			}

			DoMeleeAttackIfReady();
		}
    };
};

class spell_chapter5_light_of_dawn_aura : public SpellScriptLoader
{
    public:
        spell_chapter5_light_of_dawn_aura() : SpellScriptLoader("spell_chapter5_light_of_dawn_aura") { }

        class spell_chapter5_light_of_dawn_aura_AuraScript : public AuraScript
        {
            PrepareAuraScript(spell_chapter5_light_of_dawn_aura_AuraScript);

            void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
            {
				GetUnitOwner()->Dismount();
				GetUnitOwner()->SetCanFly(true);
				GetUnitOwner()->SetDisableGravity(true);
				GetUnitOwner()->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
            }

            void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
            {
				GetUnitOwner()->SetCanFly(false);
				GetUnitOwner()->SetDisableGravity(false);
				GetUnitOwner()->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING);
				GetUnitOwner()->GetMotionMaster()->MoveFall();
            }

            void Register()
            {
                OnEffectApply += AuraEffectApplyFn(spell_chapter5_light_of_dawn_aura_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
                OnEffectRemove += AuraEffectRemoveFn(spell_chapter5_light_of_dawn_aura_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
            }
        };

        AuraScript* GetAuraScript() const
        {
            return new spell_chapter5_light_of_dawn_aura_AuraScript();
        }
};

class spell_chapter5_rebuke : public SpellScriptLoader
{
    public:
        spell_chapter5_rebuke() : SpellScriptLoader("spell_chapter5_rebuke") { }

        class spell_chapter5_rebuke_SpellScript : public SpellScript
        {
            PrepareSpellScript(spell_chapter5_rebuke_SpellScript);

            void HandleLeapBack(SpellEffIndex effIndex)
            {
				PreventHitEffect(effIndex);
                if (Unit* unitTarget = GetHitUnit())
					unitTarget->KnockbackFrom(2282.86f, -5263.45f, 40.0f, 8.0f);
            }

            void Register()
            {
                OnEffectLaunchTarget += SpellEffectFn(spell_chapter5_rebuke_SpellScript::HandleLeapBack, EFFECT_0, SPELL_EFFECT_LEAP_BACK);
            }
        };

        SpellScript* GetSpellScript() const
        {
            return new spell_chapter5_rebuke_SpellScript();
        }
};

void AddSC_the_scarlet_enclave_c5()
{
    new npc_highlord_darion_mograine();
	new spell_chapter5_light_of_dawn_aura();
	new spell_chapter5_rebuke();
}
