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

import com.l2jserver.Config;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.handler.IActionHandler;
import com.l2jserver.gameserver.instancemanager.WalkingManager;
import com.l2jserver.gameserver.model.Elementals;
import com.l2jserver.gameserver.model.L2Object;
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.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;

import handlers.bypasshandlers.NpcViewMod;

public class L2NpcActionShift implements IActionHandler
{
	/**
	 * Manage and Display the GM console to modify the L2NpcInstance (GM only).<BR>
	 * <BR>
	 * <B><U> Actions (If the L2PcInstance is a GM only)</U> :</B><BR>
	 * <BR>
	 * <li>Set the L2NpcInstance as target of the L2PcInstance player (if necessary)</li> <li>Send a Server->Client packet MyTargetSelected to the L2PcInstance player (display the select window)</li> <li>If L2NpcInstance is autoAttackable, send a Server->Client packet StatusUpdate to the
	 * L2PcInstance in order to update L2NpcInstance HP bar</li> <li>Send a Server->Client NpcHtmlMessage() containing the GM console about this L2NpcInstance</li><BR>
	 * <BR>
	 * <FONT COLOR=#FF0000><B> <U>Caution</U> : Each group of Server->Client packet must be terminated by a ActionFailed packet in order to avoid that client wait an other packet</B></FONT><BR>
	 * <BR>
	 * <B><U> Example of use </U> :</B><BR>
	 * <BR>
	 * <li>Client packet : Action</li><BR>
	 * <BR>
	 */
	@Override
	public boolean action(L2PcInstance activeChar, L2Object targetObject, boolean interact)
	{
		if (targetObject == null) return false;	// "admin_L2NpcActionShift"
		
		L2Npc target = (L2Npc)targetObject;

		// Check if the L2PcInstance is a GM
		if (activeChar.getAccessLevel().isGm())
		{
			// Set the target of the L2PcInstance activeChar
			activeChar.setTarget(target);
			
			final NpcHtmlMessage html = new NpcHtmlMessage();
			html.setFile(activeChar.getHtmlPrefix(), "data/html/admin/npcinfo.htm");
			
			html.replace("%objid%", target.getObjectId());
			html.replace("%class%", target.getClass().getSimpleName());
			html.replace("%id%",    target.getTemplate().getId());
			html.replace("%lvl%",   target.getTemplate().getLevel());
			html.replace("%name%",  target.getTemplate().getName());
			html.replace("%tmplid%",target.getTemplate().getId());
			html.replace("%aggro%", (target.isAggressive() ? "<font color=FF0000>" : "<font color=999999>") + target.getAggroRange() + "</font>");
			html.replace("%known%", target.getTemplate().getKnownRange());
			html.replace("%hp%",    (int)target.getCurrentHp());
			html.replace("%hpmax%", target.getMaxHp());
			html.replace("%mp%",    (int)target.getCurrentMp());
			html.replace("%mpmax%", target.getMaxMp());
			double php = target.getCurrentHp() / target.getMaxHp();	//[JOJO]
			double pmp = target.getCurrentMp() / target.getMaxMp();	//[JOJO]
			html.replace("%php%", new java.text.DecimalFormat(php < 0.10 ? "0.0% " : "##0%").format(php));	//[JOJO]
			html.replace("%pmp%", new java.text.DecimalFormat(pmp < 0.10 ? "0.0% " : "##0%").format(pmp));	//[JOJO]
			
			html.replace("%patk%", target.getPAtk(null));
			html.replace("%matk%", target.getMAtk(null, null));
			html.replace("%pdef%", target.getPDef(null));
			html.replace("%mdef%", target.getMDef(null, null));
			html.replace("%accu%", target.getAccuracy());
			html.replace("%evas%", target.getEvasionRate(null));
			html.replace("%crit%", target.getCriticalHit(null, null));
			html.replace("%rspd%", target.getRunSpeed());
			html.replace("%aspd%", target.getPAtkSpd());
			html.replace("%cspd%", target.getMAtkSpd());
			html.replace("%atkType%", ((L2Character) target).getTemplate().getBaseAttackType().name());
			html.replace("%atkRng%", ((L2Character) target).getTemplate().getBaseAttackRange());
			html.replace("%str%",  target.getSTR());
			html.replace("%dex%",  target.getDEX());
			html.replace("%con%",  target.getCON());
			html.replace("%int%",  target.getINT());
			html.replace("%wit%",  target.getWIT());
			html.replace("%men%",  target.getMEN());
			html.replace("%loc%",  target.getX()+" "+target.getY()+" "+target.getZ());
			html.replace("%heading%",  target.getHeading());
			html.replace("%collision_radius%", target.getTemplate().getfCollisionRadius());
			html.replace("%collision_height%", target.getTemplate().getfCollisionHeight());
			//html.replace("%dist%", (int) activeChar.calculateDistance(target, true, false));	//-[JOJO]
			
			byte attackAttribute = target.getAttackElement();
			html.replace("%ele_atk%", Elementals.getElementName(attackAttribute));
			html.replace("%ele_atk_value%", target.getAttackElementValue(attackAttribute));
			html.replace("%ele_dfire%", target.getDefenseElementValue(Elementals.FIRE));
			html.replace("%ele_dwater%", target.getDefenseElementValue(Elementals.WATER));
			html.replace("%ele_dwind%", target.getDefenseElementValue(Elementals.WIND));
			html.replace("%ele_dearth%", target.getDefenseElementValue(Elementals.EARTH));
			html.replace("%ele_dholy%", target.getDefenseElementValue(Elementals.HOLY));
			html.replace("%ele_ddark%", target.getDefenseElementValue(Elementals.DARK));
			
			if (target.getSpawn() != null)
			{
				final L2Spawn spawn = target.getSpawn();
				html.replace("%territory%", spawn.getSpawnTerritory() == null ? "None" : spawn.getSpawnTerritory().getName());
				if (spawn.isTerritoryBased())
				{
					html.replace("%spawntype%", "Random");
					final Location spawnLoc = spawn.getLocation(target);
					html.replace("%spawn%", spawnLoc.getX() + " " + spawnLoc.getY() + " " + spawnLoc.getZ());
				}
				else
				{
					html.replace("%spawntype%", "Fixed");
					html.replace("%spawn%", spawn.getX() + " " + spawn.getY() + " " + spawn.getZ() + " " + spawn.getHeading());
				}
				html.replace("%loc2d%", (int) target.calculateDistance(spawn.getLocation(target), false, false));
				html.replace("%loc3d%", (int) target.calculateDistance(spawn.getLocation(target), true, false));
				html.replace("%locV%", target.getZ() - spawn.getZ());	//[JOJO]
				if (spawn.getRespawnMinDelay() == 0)
				{
					html.replace("%resp%", "None");
				}
				else if (spawn.hasRespawnRandom())
				{
					html.replace("%resp%", (spawn.getRespawnMinDelay() / 1000) + "-" + (spawn.getRespawnMaxDelay() / 1000) + " sec");
				}
				else
				{
					html.replace("%resp%", (spawn.getRespawnMinDelay() / 1000) + " sec");
				}
			}
			else
			{
				html.replace("%territory%", "<font color=FF0000>--</font>");
				html.replace("%spawntype%", "<font color=FF0000>--</font>");
				html.replace("%spawn%", "<font color=FF0000>null</font>");
				html.replace("%loc2d%", "<font color=FF0000>--</font>");
				html.replace("%loc3d%", "<font color=FF0000>--</font>");
				html.replace("%locV%", "<font color=FF0000>--</font>");	//[JOJO]
				html.replace("%resp%", "<font color=FF0000>--</font>");
			}
			html.replace("%dist2d%", (int) target.calculateDistance(activeChar, false, false));	//[JOJO]
			html.replace("%dist3d%", (int) target.calculateDistance(activeChar, true, false));	//[JOJO]
			html.replace("%distV%", target.getZ() - activeChar.getZ());	//[JOJO]

if (com.l2jserver.Config.ADMIN_VIEW_NPC_STATUS) {{
			StringBuilder sb = new StringBuilder(256);
			sb.append("<TR><TD><table width=270 border=0><tr><td>");
			L2Object o = target.getTarget();
			if (o != null) {
				sb.append("Target: ");
				if (o == target) sb.append("(self)");
				else sb.append(o.getName()).append(", Range: ").append((int)com.l2jserver.gameserver.util.Util.calculateDistance(target, o, false));
				if (target instanceof L2Attackable && o instanceof L2Character) sb.append(", Hate: ").append(((L2Attackable)target).getHating((L2Character) o));
				sb.append("<BR1>");
			}
			if (target.getInstanceId() != 0) sb.append("Instance ID:").append(target.getInstanceId()).append("<BR1>");
			if (target.getScriptValue() != 0) sb.append(" v=").append(target.getScriptValue());
			if (target.isAfraid()) sb.append(" Afraid");
			if (target.isAlikeDead()) sb.append(" AlikeDead");
			if (target.isAllSkillsDisabled()) sb.append(" AllSkillsDisabled");
			if (target.isAttackingDisabled()) sb.append(" AttackingDisabled");
			if (target.isAttackingNow()) sb.append(" AttackingNow");
			if (target.isBetrayed()) sb.append(" Betrayed");
			if (target.isBusy()) sb.append(" Busy");
			if (target.getBusyMessage() != null && target.getBusyMessage().length() > 0) sb.append(" \"").append(target.getBusyMessage()).append('\"');
			if (target.isCastingNow()) sb.append(" CastingNow");
 //			if (target.isCastingNow()) sb.append(" CastingNow(").append(target.getCastEndTimeLeftMilli()).append("ms)");
			if (target.isCastingSimultaneouslyNow()) sb.append(" CastingSimultaneouslyNow");
			if (target.isChampion()) sb.append(" Champion");
			if (target.isConfused()) sb.append(" Confused");
			if (target.isCoreAIDisabled()) sb.append(" CoreAIDisabled");
			if (target.isDead()) sb.append(" Dead");
			if (target.isDebug()) sb.append(" Debug");
			if (target.isDecayed()) sb.append(" Decayed");
			if (target.isDisarmed()) sb.append(" Disarmed");
			if (target.isFallsdown()) sb.append(" Fallsdown");
			if (target.isImmobilized()) sb.append(" Immobilized");
			if (target.isInActiveRegion()) sb.append(" InActiveRegion");
			if (target.isInCombat()) sb.append(" InCombat");
			if (target.isInvul()) sb.append(" Invul");
			if (target.isMinion()) sb.append(" Minion");
			if (target.isMortal()) sb.append(" Mortal");
			if (target.isMovementDisabled()) sb.append(" MovementDisabled");
			if (target.isMoving()) sb.append(" Moving");
			if (target.isMuted()) sb.append(" Muted");
			if (target.isNoRndWalk()) sb.append(" NoRndWalk");
			if (target.isOnGeodataPath()) sb.append(" OnGeodataPath");
			if (target.isOutOfControl()) sb.append(" OutOfControl");
			if (target.isOverloaded()) sb.append(" Overloaded");
			if (target.isParalyzed()) sb.append(" Paralyzed");
			if (target.isPendingRevive()) sb.append(" PendingRevive");
			if (target.isPhysicalAttackMuted()) sb.append(" PhysicalAttackMuted");
			if (target.isPhysicalMuted()) sb.append(" PhysicalMuted");
			if (target.isRaid()) sb.append(" Raid");
			if (target.isRaidMinion()) sb.append(" RaidMinion");
			if (target.isRandomAnimationEnabled()) sb.append(" RandomAnimationEnabled");
			if (target.hasRandomAnimation()) sb.append(" hasRandomAnimation");
			if (target.isResurrectionBlocked()) sb.append(" ResurrectionBlocked");
			if (target.isRooted()) sb.append(" Rooted");
			if (target.isRunning()) sb.append(" Running");
			if (target.isShowSummonAnimation()) sb.append(" ShowSummonAnimation");
			if (target.isSleeping()) sb.append(" Sleeping");
			if (target.isStunned()) sb.append(" Stunned");
			if (target.isTeleporting()) sb.append(" Teleporting");
			if (target.isTransformed()) sb.append(" Transformed");
			if (target.isUndead()) sb.append(" Undead");
			if (target instanceof L2Attackable) {
				L2Attackable a = (L2Attackable) target;
				if (a.canReturnToSpawnPoint()) sb.append(" canReturnToSpawnPoint");
				if (a.isReturningToSpawnPoint()) sb.append(" ReturningToSpawnPoint");
				if (a.canSeeThroughSilentMove()) sb.append(" canSeeThroughSilentMove");
				if (a.isSweepActive()) sb.append(" SweepActive");
			}
			sb.append("</td></tr></table></TD></TR>");
			html.replace("%STATUS%", sb.toString());
}} else {{
			html.replace("%STATUS%", "");
}}
			
			String clansString = target.getTemplate().getClanNames(); if (clansString == null) clansString = "<font color=FF0000>--</font>";	//[JOJO]
			String enemyClansString = target.getTemplate().getEnemyClanNames(); if (enemyClansString == null) enemyClansString = "<font color=FF0000>--</font>";	//[JOJO]
			
			html.replace("%ai_intention%",  "<tr><td><table width=270 border=0 bgcolor=131210><tr><td width=100><font color=FFAA00>Intention:</font></td><td align=right width=170>" + (target.hasAI() ? target.getAI().getIntention().name() : "null") + "</td></tr></table></td></tr>");
			html.replace("%ai%",            "<tr><td><table width=270 border=0><tr><td width=100><font color=FFAA00>AI</font></td><td align=right width=170>"+(target.hasAI() ? target.getAI().getClass().getSimpleName() : "null") + "</td></tr></table></td></tr>");
			html.replace("%ai_type%",       "<tr><td><table width=270 border=0 bgcolor=131210><tr><td width=100><font color=FFAA00>AIType</font></td><td align=right width=170>"+target.getAiType().name() + "</td></tr></table></td></tr>");
			html.replace("%ai_clan%", "<tr><td><table width=270 border=0><tr><td width=100><font color=FFAA00>Clan & Range:</font></td><td align=right width=170>" + clansString + " " + target.getTemplate().getClanHelpRange() + "</td></tr></table></td></tr>");
			html.replace("%ai_enemy_clan%", "<tr><td><table width=270 border=0 bgcolor=131210><tr><td width=100><font color=FFAA00>Enemy & Range:</font></td><td align=right width=170>" + enemyClansString + " " + target.getTemplate().getAggroRange() + "</td></tr></table></td></tr>");
			
			final String routeName = WalkingManager.getInstance().getRouteName(target);
			if (!routeName.isEmpty())
			{
				html.replace("%route%", "<tr><td><table width=270 border=0><tr><td width=100><font color=LEVEL>Route:</font></td><td align=right width=170>" + routeName + "</td></tr></table></td></tr>");
			}
			else
			{
				html.replace("%route%", "");
			}
			activeChar.sendPacket(html);
		}
		else if (Config.ALT_GAME_VIEWNPC)
		{
			if (!target.isNpc())
			{
				return false;
			}
			activeChar.setTarget(target);
			NpcViewMod.sendNpcView(activeChar, target);
		}
		return true;
	}
	
	@Override
	public InstanceType getInstanceType()
	{
		return InstanceType.L2Npc;
	}
}
