/*
 * 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.group_template;

import static com.l2jserver.gameserver.datatables.SkillData.*;
import ai.npc.AbstractNpcAI;

import com.l2jserver.gameserver.datatables.SpawnTable;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.L2Playable;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.clientpackets.Say2;

/**
 * Prison Guards AI.
 * @author St3eT
 */
public final class PrisonGuards extends AbstractNpcAI
{
	private static final boolean MOD_SOUND = true;	//+[JOJO]
	// NPCs
	private static final int GUARD_HEAD = 18367; // Prison Guard
	private static final int GUARD = 18368; // Prison Guard
	// Item
	private static final int STAMP = 10013; // Race Stamp
	// Skills
	private static final int TIMER = 5239; // Event Timer
	private static final int STONE = getSkillHashCode(4578, 1); // Petrification
	private static final int SILENCE = getSkillHashCode(4098, 9); // Silence
	// Misc
	private static final int NUM_OF_STAMPS = 4;
	
	private PrisonGuards()
	{
		super(PrisonGuards.class.getSimpleName(), "ai/group_template");
		addAttackId(GUARD_HEAD, GUARD);
		addSpawnId(GUARD_HEAD, GUARD);
		addMoveFinishedId(GUARD);
		addNpcHateId(GUARD);
		addSkillSeeId(GUARD);
		addSpellFinishedId(GUARD_HEAD, GUARD);
		
if (!com.l2jserver.Config.FIX_onSpawn_for_SpawnTable) {{
		for (L2Spawn spawn : SpawnTable.getInstance().getSpawns(GUARD_HEAD))
		{
			onSpawn(spawn.getLastSpawn());
		}
		
		for (L2Spawn spawn : SpawnTable.getInstance().getSpawns(GUARD))
		{
			onSpawn(spawn.getLastSpawn());
		}
}}
	}
	
	@Override
	public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
	{
		if (event == "CLEAR_STATUS")	// Rignos.java
		{
			for (L2Spawn spawn : SpawnTable.getInstance().getSpawns(GUARD_HEAD))
			{
				final L2Npc guard = spawn.getLastSpawn();
				guard.setScriptValue(0);
			}
		}
		else if (event == "CHECK_HOME") // GUARD
		{
			if (!npc.isInCombat())
			{
				cancelQuestTimer(event, npc, player);
				if (npc.calculateDistance(npc.getSpawn().getLocation(), false, false) > 10 && !npc.isDead() && npc.isVisible())
					npc.teleToLocation(npc.getSpawn().getLocation());
			}
		}
		return super.onAdvEvent(event, npc, player);
	}
	
	@Override
	public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
	{
		if (npc.getId() == GUARD_HEAD)
		{
			if (player.isAffectedBySkill(TIMER))
			{
				if (getRandom(100) < 10 && npc.calculateDistance(player, true, false) < 100)
				{
					if (getQuestItemsCount(player, STAMP) < NUM_OF_STAMPS && npc.compareAndSetScriptValue(0, 1))
					{
						giveItems(player, STAMP, 1);
						if (MOD_SOUND) playSound(player, "ItemSound.quest_itemget");
					}
				}
			}
			else
			{
				npc.setTarget(player);
				npc.doCast(getSkill(STONE));
				broadcastNpcSay(npc, Say2.ALL, NpcStringId.ITS_NOT_EASY_TO_OBTAIN);
			}
		}
		else // GUARD
		{
			if (!player.isAffectedBySkill(TIMER) && npc.calculateDistance(npc.getSpawn().getLocation(), false, false) < 2000)
			{
				npc.setTarget(player);
				npc.doCast(getSkill(STONE));
				broadcastNpcSay(npc, Say2.ALL, NpcStringId.YOURE_OUT_OF_YOUR_MIND_COMING_HERE);
			}
		}
		return super.onAttack(npc, player, damage, isSummon);
	}
	
	@Override
	public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
	{
		// GUARD
		if (!caster.isAffectedBySkill(TIMER))
		{
			npc.setTarget(caster);
			npc.doCast(getSkill(SILENCE));
		}
		return super.onSkillSee(npc, caster, skill, targets, isSummon);
	}
	
	@Override
	public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
	{
		// GUARD_HEAD, GUARD
		if (skill.getReuseHashCode() == SILENCE || skill.getReuseHashCode() == STONE)
		{
			((L2Attackable) npc).clearAggroList();
			npc.setTarget(npc);
		}
		return super.onSpellFinished(npc, player, skill);
	}
	
	@Override
	public boolean onMoveFinished(L2Npc npc)
	{
		// GUARD
		startQuestTimer("CHECK_HOME", 30000, npc, null, Repeating.WithFixedDelay);
		return super.onMoveFinished(npc);
	}
	
	@Override
	public boolean onNpcHate(L2Attackable mob, L2Playable playable)
	{
		// GUARD
		return playable.isAffectedBySkill(TIMER);
	}
	
	@Override
	public String onSpawn(L2Npc npc)
	{
		if (!npc.isTeleporting())
		{
			if (npc.getId() == GUARD_HEAD)
			{
				npc.setIsImmobilized(true);
				npc.setIsInvul(true);
			}
			else // GUARD
			{
				npc.setIsNoRndWalk(true);
			}
		}
		return super.onSpawn(npc);
	}
	
	//[JOJO]-------------------------------------------------
	@Override
	public boolean unload()
	{
		for (L2Object o : L2World.getInstance().getVisibleObjects()) {
			if (o instanceof L2Npc) {
				L2Npc npc = (L2Npc) o;
				switch (npc.getNpcId()) {
					case GUARD_HEAD:
					case GUARD:
						npc.deleteMe();
						break;
				}
			}
		}
		return super.unload();
	}
	//-------------------------------------------------------
	
	public static void main(String[] args)
	{
		new PrisonGuards();
	}
}
