/*
 * Copyright (C) 2004-2014 L2J DataPack
 * 
 * This file is part of L2J DataPack.
 * 
 * L2J DataPack 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 3 of the License, or
 * (at your option) any later version.
 * 
 * L2J DataPack 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/>.
 */
package ai.individual;

import javolution.util.FastMap;

import com.l2jserver.gameserver.ai.CtrlEvent;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.ai.NextAction;
import com.l2jserver.gameserver.datatables.SkillTable;
import com.l2jserver.gameserver.datatables.SpawnTable;
import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.clientpackets.Say2;
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
import com.l2jserver.gameserver.util.Util;
import com.l2jserver.util.Rnd;

public final class FrightenedRagnaOrc extends Quest
{
	// NPC
	private static final int FRIGHTENED_RAGNA_ORC = 18807;
	
	// TEXT
	private static final NpcStringId[] ON_KILL_SAY = {
		NpcStringId.UGH_A_CURSE_UPON_YOU, //うっう．．．お前にのろいをかけてやる！
		NpcStringId.I_REALLY_DIDNT_WANT_TO_FIGHT, //俺．．．ほんとに戦うのいやだったのに．．．
	};
	
	// COORD
	private static final Location[] ESCAPE_COORDS = {
		// zone_vertices.sql#Den of Evil Zones
		new Location(74313, -116888, -2218, 0), // 70000
		new Location(63170, -106621, -2384, 0), // 70001
		new Location(68030, -107150, -1152, 0), // 70002
		new Location(62351, -117376, -3064, 0), // 70003
		new Location(68100, -116006, -2171, 0), // 70004
		new Location(69911, -118790, -2256, 0), // 70005
		new Location(67520, -122211, -2910, 0), // 70006
		new Location(74325, -121296, -3024, 0), // 70007
		new Location(70788, -125554, -3016, 0), // 70008
		new Location(76155, -127355, -3149, 0), // 70009
		new Location(71543, -128820, -3360, 0), // 70010
	};
	
	private FrightenedRagnaOrc()
	{
		super(-1, FrightenedRagnaOrc.class.getSimpleName(), "ai/individual");
		
		addSpawnId(FRIGHTENED_RAGNA_ORC);
		addAttackId(FRIGHTENED_RAGNA_ORC);
		addKillId(FRIGHTENED_RAGNA_ORC);
		
if (!com.l2jserver.Config.FIX_onSpawn_for_SpawnTable) {{
		for (L2Spawn spawn : SpawnTable.getInstance().getSpawns(FRIGHTENED_RAGNA_ORC))
		{
			L2Npc npc;
			if (spawn != null && (npc = spawn.getLastSpawn()) != null)
				this.onSpawn(npc);
		}
}}
	}
	
	/*******************************************************/
	// Frightened Ragna Orc Instance
	/*******************************************************/
	protected static class TheFrightenedRagnaOrcInstance
	{
		L2PcInstance lastAttacker;
		long lastAttackTime;
		double hp;
		boolean enabled;
	}
	private static FastMap<L2Npc,TheFrightenedRagnaOrcInstance> _frightenedRagnaOrcs = new FastMap<>();
	
	private void put(L2Npc npc, L2PcInstance attacker)
	{
		synchronized (_frightenedRagnaOrcs)
		{
			TheFrightenedRagnaOrcInstance he;
			if ((he = _frightenedRagnaOrcs.get(npc)) == null)
			{
				he = new TheFrightenedRagnaOrcInstance();
				he.lastAttacker = attacker;
				he.lastAttackTime = System.currentTimeMillis();
				he.hp = npc.getCurrentHp();
				_frightenedRagnaOrcs.put(npc, he);
				startQuestTimer("1", 1000, npc, null, true);
			}
			else
			{
				he.lastAttacker = attacker;
				he.lastAttackTime = System.currentTimeMillis();
				he.hp = npc.getCurrentHp();
			}
		}
	}
	private TheFrightenedRagnaOrcInstance get(L2Npc npc)
	{
		return _frightenedRagnaOrcs.get(npc);
	}
	private void remove(L2Npc npc)
	{
		cancelQuestTimer("1", npc, null);
		_frightenedRagnaOrcs.remove(npc);
	}
	/*******************************************************/
	
	private void autoChat(L2Npc npc, NpcStringId npcString)
	{
		npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.ALL, npc.getId(), npcString));
	}
	
	private void escape(final L2Npc npc)
	{
		((L2Attackable)npc).clearAggroList();
		
		L2Spawn spawn = npc.getSpawn();
		Location pos = null;
		double m = Double.MAX_VALUE;
		for (Location a : ESCAPE_COORDS)
		{
			double d = com.l2jserver.gameserver.util.Util.calculateDistance(a.getX(), a.getY(), spawn.getX(), spawn.getY());
			if (m > d)
			{
				m = d;
				pos = a;
			}
		}
		if (pos == null) pos = new Location(spawn.getX(), spawn.getY(), spawn.getZ(), 0);
		npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, pos);
		
		npc.getAI().setNextAction(new NextAction(CtrlEvent.EVT_ARRIVED, null, null){
			@Override public void doWork() // onEvtArrived
			{
				if (!npc.isDead() && npc.isVisible())
				{
					npc.getSpawn().setRespawnDelay(60);
					npc.deleteMe();
				}
			}
		});
	}
	
	@Override
	public String onSpawn(L2Npc npc)
	{
		npc.disableCoreAI(true);
		((L2Attackable)npc).setOnKillDelay(1000);	//Default 5000ms.
		npc.getSpawn().setRespawnDelay(60);
		return super.onSpawn(npc);
	}
	
	@Override
	public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
	{
		final TheFrightenedRagnaOrcInstance he = get(npc);
		if (he == null)
		{
			put(npc, attacker);
			autoChat(npc, NpcStringId.I_DONT_WANT_TO_FIGHT);	//俺．．．戦うのいやなんだけどなぁ．．．
		}
		else
		{
			double previousHpPercent = he.hp / npc.getMaxHp() * 100;
			double currentHpPercent = npc.getCurrentHp() / npc.getMaxHp() * 100;
			long time = System.currentTimeMillis() - he.lastAttackTime;
			
			put(npc, attacker);
			
			if (currentHpPercent <= 50 && 50 < previousHpPercent)
			{
				he.enabled = true;
				autoChat(npc, NpcStringId.WAIT_WAIT_STOP_SAVE_ME_AND_ILL_GIVE_YOU_10000000_ADENA);	//ま、待ってくれ。もうやめにしよう。助けてくれたら1000万アデナやる。
			}
			else if (currentHpPercent <= 80 && time >= 5000)
			{
				int rnd = Rnd.get(100);
				if ((rnd -= 15) <= 0)
					autoChat(npc, NpcStringId.IS_THIS_REALLY_NECESSARY);	//どうしてやんなきゃなんないの？
				else if ((rnd -= 15) <= 0)
					autoChat(npc, NpcStringId.I_DONT_WANT_TO_FIGHT);	//俺．．．戦うのいやなんだけどなぁ．．．
			}
		}
		return null;
	}
	
	@Override
	public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
	{
		remove(npc);
		autoChat(npc, ON_KILL_SAY[Rnd.get(ON_KILL_SAY.length)]);
		return null;
	}
	
	@Override
	public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
	{
		if (event == "1")
		{
			final TheFrightenedRagnaOrcInstance he = get(npc);
			long time = System.currentTimeMillis() - he.lastAttackTime;
			if (he.enabled && 
			   (time > 60000
			 || time > 10000 && npc.getCurrentHp() >= he.hp) )
			{
				remove(npc);
				if (Rnd.get(100) <= 33 && Util.checkIfInRange(100, he.lastAttacker, npc, true))
				{
					final int adena;
					NpcStringId say = NpcStringId.TH_THANKS_I_COULD_HAVE_BECOME_GOOD_FRIENDS_WITH_YOU; //ありがとよ．．．おまえみたいなやつなら、いい友達になれたかもな．．．
					int chance = Rnd.get(100);
					if ((chance -= 1) <= 0)
					{
						adena = 10000000;
						say = NpcStringId.ILL_GIVE_YOU_10000000_ADENA_LIKE_I_PROMISED_I_MIGHT_BE_AN_ORC_WHO_KEEPS_MY_PROMISES;	//約束どおり1000万アデナやろう。俺は意外と約束をよく守るオークかもしれねえだろ？
					}
					else if ((chance -= 5) <= 0)
						adena = 5000000;/*500万*/
					else if ((chance -= 10) <= 0)
						adena = 1000000;/*100万*/
					else if ((chance -= 15) <= 0)
						adena = 500000;/*50万*/
					else if ((chance -= 20) <= 0)
						adena = 100000;/*10万*/
					else /*49%*/
						adena = 50000;/*5万*/
					autoChat(npc, say);
					npc.doCast(SkillTable.getInstance().getInfo(6234, 1)); // 演出：アデナ花火
					for (int n = 10; --n >= 0;)
						npc.dropItem(he.lastAttacker, 57, adena / 10);
					
					startQuestTimer("despawn", 5000, npc, null);
				}
				else
				{
					autoChat(npc, NpcStringId.THANKS_BUT_THAT_THING_ABOUT_10000000_ADENA_WAS_A_LIE_SEE_YA); //ありがとよ！でも、1000万アデナの話はうそだよ〜ん。あばよ！
					autoChat(npc, NpcStringId.YOURE_PRETTY_DUMB_TO_BELIEVE_ME); //俺の話を信じるとは、おまえも愚かしいな。
					escape(npc);
				}
			}
			else if (time > 60000 && npc.getCurrentHp() >= npc.getMaxHp())
			{
				// timeout.
				remove(npc);
			}
			return null;
		}
		else if (event == "despawn")
		{
			npc.getSpawn().setRespawnDelay(1800);
			npc.deleteMe();
		}
		return super.onAdvEvent(event, npc, player);
	}
	
	// Register the new Script at the Script System
	public static void main(String[] args)
	{
		new FrightenedRagnaOrc();
	}
}
