/*
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
*
* 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/>.
*/

/* ScriptData
SDName: Sunwell_Plateau
SD%Complete: 0
SDComment: Placeholder, Epilogue after Kil'jaeden, Captain Selana Gossips
EndScriptData */

/* ContentData
npc_prophet_velen
npc_captain_selana
npc_queldelar_sunwell_plateau
item_tainted_queldelar
go_dalaran_portal_sunwell
EndContentData */

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

/*######
## npc_prophet_velen
######*/

enum ProphetSpeeches
{
	PROPHET_SAY1 = -1580099,
	PROPHET_SAY2 = -1580100,
	PROPHET_SAY3 = -1580101,
	PROPHET_SAY4 = -1580102,
	PROPHET_SAY5 = -1580103,
	PROPHET_SAY6 = -1580104,
	PROPHET_SAY7 = -1580105,
	PROPHET_SAY8 = -1580106
};

enum LiadrinnSpeeches
{
	LIADRIN_SAY1 = -1580107,
	LIADRIN_SAY2 = -1580108,
	LIADRIN_SAY3 = -1580109
};

/*######
## npc_captain_selana
######*/

#define CS_GOSSIP1 "Give me a situation report, Captain."
#define CS_GOSSIP2 "What went wrong?"
#define CS_GOSSIP3 "Why did they stop?"
#define CS_GOSSIP4 "Your insight is appreciated."


enum Says
{
	SAY_QUELDELAR_1 = 1,  // Damas y Caballeros, les presento a $N, portador de Quel'Delar.
	SAY_QUELDELAR_2 = 0,  // Is it true that this is Quel\'Delar?
	SAY_QUELDELAR_3 = 1,  // We will see.
	SAY_QUELDELAR_4 = 2,  // Look Lor\'themar! It is Quel\'Delar without a doubt.
	SAY_QUELDELAR_5 = 3,  // So be it. You have my thanks, $N, for returning Quel\'Delar to its rightful owners
	SAY_QUELDELAR_6 = 4,  // What means this treason?
	SAY_QUELDELAR_7 = 5,  // Drop the weapon and surrender, traitor.
	SAY_QUELDELAR_8 = 6,  // This is not my fault, Rommath. It is not a treason.
	SAY_QUELDELAR_9 = 7,  // Remove your men. The stupidity of Lor\'themar himself caused his wounds. Quel\'Delar is not chosen, it chooses it\'s master.
	SAY_QUELDELAR_10 = 8,  // Guards, return to your posts
	SAY_QUELDELAR_11 = 9,  // You will have what you seek, $N. Take the sword and leave. And your Auric, be careful what you say in this sacred place.
	SAY_QUELDELAR_12 = 10,  // Take the sword through this portal into Dalaran, $N. You have done what many quel\'dorei have dreamed for years. At last Quel\'Delar is restored.
};

enum QuelDelarEvents
{
	EVENT_QUEST_STEP_1 = 1,
	EVENT_QUEST_STEP_2 = 2,
	EVENT_QUEST_STEP_3 = 3,
	EVENT_QUEST_STEP_4 = 4,
	EVENT_QUEST_STEP_5 = 5,
	EVENT_QUEST_STEP_6 = 6,
	EVENT_QUEST_STEP_7 = 7,
	EVENT_QUEST_STEP_8 = 8,
	EVENT_QUEST_STEP_9 = 9,
	EVENT_QUEST_STEP_10 = 10,
	EVENT_QUEST_STEP_11 = 11,
	EVENT_QUEST_STEP_12 = 12,
	EVENT_QUEST_STEP_13 = 13,
	EVENT_QUEST_STEP_14 = 14,
	EVENT_QUEST_STEP_15 = 15,
	EVENT_QUEST_STEP_16 = 16
};

enum QuelDelarActions
{
	ACTION_START_EVENT = 1
};

enum QuelDelarCreatures
{
	NPC_ROMMATH = 37763,
	NPC_THERON = 37764,
	NPC_AURIC = 37765,
	NPC_QUEL_GUARD = 37781,
	NPC_CASTER_BUNNY = 37746,
	NPC_CHAMBERLAIN_GALIROS = 38056,
};

enum QuelDelarGameobjects
{
	GO_QUEL_DANAR = 201794,
	GO_PORTAL_DALARAN = 195682,
};
enum QuelDelarMisc
{
	ITEM_TAINTED_QUELDANAR_1 = 49879,
	ITEM_TAINTED_QUELDANAR_2 = 49889,
	SPELL_WRATH_QUEL_DANAR = 70493,
	SPELL_ICY_PRISON = 70540
};

/*######
## npc_queldelar_sunwell_plateau
######*/

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

	bool OnGossipHello(Player* player, Creature* creature)
	{
		player->PrepareGossipMenu(creature, 0);

		if (player->HasItemCount(ITEM_TAINTED_QUELDANAR_1, 1) || player->HasItemCount(ITEM_TAINTED_QUELDANAR_2, 1))
			player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "[PH] Start Event.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
		player->SendPreparedGossip(creature);

		return true;
	}

	bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 Action)
	{
		player->PlayerTalkClass->ClearMenus();

		switch (Action)
		{
		case GOSSIP_ACTION_INFO_DEF + 1:
			player->CLOSE_GOSSIP_MENU();
			creature->AI()->SetGUID(player->GetGUID());
			creature->AI()->DoAction(ACTION_START_EVENT);
			break;
		default:
			return false;
		}
		return true;
	}

	struct npc_queldelar_sunwell_plateauAI : public ScriptedAI
	{
		npc_queldelar_sunwell_plateauAI(Creature* creature) : ScriptedAI(creature) { }

		void Reset()
		{
			me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
			events.Reset();
		}

		void DoAction(int32 action)
		{
			switch (action)
			{
			case ACTION_START_EVENT:
				me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
				events.ScheduleEvent(EVENT_QUEST_STEP_1, 0);
				break;
			}
		}

		void UpdateAI(uint32 diff)
		{
			events.Update(diff);

			switch (events.ExecuteEvent())
			{
			case EVENT_QUEST_STEP_1:
				if (Creature* rommath = me->FindNearestCreature(NPC_ROMMATH, 100.0f, true))  // Rommath
					uiRommath = rommath->GetGUID();

				if (Creature* theron = me->FindNearestCreature(NPC_THERON, 100.0f, true))    // Lor'Themar Theron
					uiTheron = theron->GetGUID();

				if (Creature* auric = me->FindNearestCreature(NPC_AURIC, 100.0f, true))      // Auric
					uiAuric = auric->GetGUID();

				if (GameObject* quelDelar = me->SummonGameObject(GO_QUEL_DANAR, 1683.99f, 620.231f, 29.3599f, 0.410932f, 0, 0, 0, 0, 0))
				{
					uiQuelDelar = quelDelar->GetGUID();
					quelDelar->SetFlag(GAMEOBJECT_FLAGS, 5);
				}

				if (Player* player = me->SelectNearestPlayer(200.0f))
				{
					player->DestroyItemCount(ITEM_TAINTED_QUELDANAR_1, 1, true);
					player->DestroyItemCount(ITEM_TAINTED_QUELDANAR_2, 1, true);
				}
				events.ScheduleEvent(EVENT_QUEST_STEP_2, 2 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_2:
				if (Creature* guard = me->FindNearestCreature(NPC_QUEL_GUARD, 100.0f, true))
					guard->AI()->Talk(SAY_QUELDELAR_2);
				events.ScheduleEvent(EVENT_QUEST_STEP_3, 1 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_3:
				if (Creature* theron = ObjectAccessor::GetCreature(*me, uiTheron))
					theron->AI()->Talk(SAY_QUELDELAR_3);
				events.ScheduleEvent(EVENT_QUEST_STEP_4, 4 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_4:
				if (Creature* rommath = ObjectAccessor::GetCreature(*me, uiRommath))
					rommath->GetMotionMaster()->MovePoint(1, 1675.8f, 617.19f, 28.0504f);
				if (Creature*auric = ObjectAccessor::GetCreature(*me, uiAuric))
					auric->GetMotionMaster()->MovePoint(1, 1681.77f, 612.084f, 28.4409f);
				events.ScheduleEvent(EVENT_QUEST_STEP_5, 6 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_5:
				if (Creature* rommath = ObjectAccessor::GetCreature(*me, uiRommath))
				{
					rommath->SetOrientation(0.3308f);
					rommath->AI()->Talk(SAY_QUELDELAR_4);
				}
				if (Creature* auric = ObjectAccessor::GetCreature(*me, uiAuric))
					auric->SetOrientation(1.29057f);
				if (Creature* theron = ObjectAccessor::GetCreature(*me, uiTheron))
					theron->GetMotionMaster()->MovePoint(1, 1677.07f, 613.122f, 28.0504f);
				events.ScheduleEvent(EVENT_QUEST_STEP_6, 10 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_6:
				if (Creature* theron = ObjectAccessor::GetCreature(*me, uiTheron))
				{
					theron->AI()->Talk(SAY_QUELDELAR_5);
					theron->GetMotionMaster()->MovePoint(1, 1682.3f, 618.459f, 27.9581f);
				}
				events.ScheduleEvent(EVENT_QUEST_STEP_7, 4 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_7:
				if (Creature* theron = ObjectAccessor::GetCreature(*me, uiTheron))
					theron->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
				events.ScheduleEvent(EVENT_QUEST_STEP_8, 0.8 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_8:
				if (Creature* theron = ObjectAccessor::GetCreature(*me, uiTheron))
					theron->CastSpell(theron, SPELL_WRATH_QUEL_DANAR, true);
				events.ScheduleEvent(EVENT_QUEST_STEP_9, 1 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_9:
				if (Creature* rommath = ObjectAccessor::GetCreature(*me, uiRommath))
				{
					if (Player* player = me->SelectNearestPlayer(200.0f))
						rommath->AddAura(SPELL_ICY_PRISON, player);
					rommath->AI()->Talk(SAY_QUELDELAR_6);
				}
				if (Creature* guard = me->FindNearestCreature(NPC_QUEL_GUARD, 200.0f))
				{
					guard->GetMotionMaster()->MovePoint(0, 1681.1f, 614.955f, 28.4983f);
					guard->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H);
				}
				events.ScheduleEvent(EVENT_QUEST_STEP_10, 3 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_10:
				if (Creature* guard = me->FindNearestCreature(NPC_QUEL_GUARD, 200.0f))
					guard->AI()->Talk(SAY_QUELDELAR_7);
				events.ScheduleEvent(EVENT_QUEST_STEP_11, 2 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_11:
				if (Creature* auric = ObjectAccessor::GetCreature(*me, uiAuric))
					auric->AI()->Talk(SAY_QUELDELAR_8);
				events.ScheduleEvent(EVENT_QUEST_STEP_12, 6 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_12:
				if (Creature* auric = ObjectAccessor::GetCreature(*me, uiAuric))
					auric->AI()->Talk(SAY_QUELDELAR_9);
				events.ScheduleEvent(EVENT_QUEST_STEP_13, 5 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_13:
				if (Creature* rommath = ObjectAccessor::GetCreature(*me, uiRommath))
					rommath->AI()->Talk(SAY_QUELDELAR_10);
				events.ScheduleEvent(EVENT_QUEST_STEP_14, 2 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_14:
				if (Creature* guard = me->FindNearestCreature(NPC_QUEL_GUARD, 200.0f))
				{
					guard->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND);
					guard->GetMotionMaster()->MovePoint(0, guard->GetHomePosition());
				}
				if (Creature* rommath = ObjectAccessor::GetCreature(*me, uiRommath))
				{
					rommath->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
					rommath->AI()->Talk(SAY_QUELDELAR_11);
				}
				events.ScheduleEvent(EVENT_QUEST_STEP_15, 7 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_15:
				if (Creature* auric = ObjectAccessor::GetCreature(*me, uiAuric))
				{
					auric->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
					auric->AI()->Talk(SAY_QUELDELAR_12);
					if (GameObject* quelDelar = me->FindNearestGameObject(GO_QUEL_DANAR, 100.0f))
						quelDelar->RemoveFlag(GAMEOBJECT_FLAGS, 5);
				}
				events.ScheduleEvent(EVENT_QUEST_STEP_16, 2 * IN_MILLISECONDS);
				break;
			case EVENT_QUEST_STEP_16:
				if (Creature* auric = ObjectAccessor::GetCreature(*me, uiAuric))
					auric->GetMotionMaster()->MovePoint(0, auric->GetHomePosition());
				if (Creature* rommath = ObjectAccessor::GetCreature(*me, uiRommath))
					rommath->GetMotionMaster()->MovePoint(0, rommath->GetHomePosition());
				if (Creature* theron = ObjectAccessor::GetCreature(*me, uiTheron))
					theron->DespawnOrUnsummon(5 * IN_MILLISECONDS);

				//Portail Dalaran
				me->SummonGameObject(GO_PORTAL_DALARAN, 1655.66f, 627.25f, 28.15f, 0.03f, 0, 0, 0, 0, 0);
				break;
			default:
				break;
			}
		}
	private:
		EventMap events;
		ObjectGuid uiRommath;
		ObjectGuid uiTheron;
		ObjectGuid uiAuric;
		ObjectGuid uiQuelDelar;
	};

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

class item_tainted_queldelar : public ItemScript
{
public:

	item_tainted_queldelar() : ItemScript("item_tainted_queldelar") { }

	bool OnUse(Player* player, Item* item, SpellCastTargets const& /*targets*/)
	{
		InstanceScript *instance = player->GetInstanceScript();

		if (instance && player->FindNearestCreature(NPC_CASTER_BUNNY, 200.0f, true))
		{
			if (Creature *introducer = player->FindNearestCreature(NPC_CHAMBERLAIN_GALIROS, 200.0f, true))
			{
				introducer->AI()->SetGUID(player->GetGUID());
				introducer->AI()->DoAction(ACTION_START_EVENT);
			}
			return true;
		}
		else
			return false;
	}
};

class go_dalaran_portal_sunwell : public GameObjectScript
{
public:

	go_dalaran_portal_sunwell() : GameObjectScript("go_dalaran_portal_sunwell") {}

	bool OnGossipHello(Player* player, GameObject* /*go*/)
	{
		player->SetPhaseMask(1, true);
		player->TeleportTo(571, 5804.15f, 624.771f, 647.767f, 1.64f);
		return false;
	}
};

void AddSC_sunwell_plateau() {
	new npc_queldelar_sunwell_plateau();
	new item_tainted_queldelar();
	new go_dalaran_portal_sunwell();
}
