/*
 * Copyright (C) 2005-2008 L2J_JP / 2008-2013 L2J-SFJP
 * 
 * This file is part of L2J Server.
 * 
 * L2J Server 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 Server 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.npc.NpcBuffers.impl;

import static com.l2jserver.gameserver.datatables.SkillTable.*;

import java.util.concurrent.ScheduledFuture;

import ai.npc.AbstractNpcAI;

import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.instancemanager.ZoneManager;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.effects.L2Effect;
import com.l2jserver.gameserver.model.skills.AbnormalType;
import com.l2jserver.gameserver.model.skills.L2Skill;
import com.l2jserver.gameserver.model.skills.L2SkillType;
import com.l2jserver.gameserver.model.zone.type.L2TownZone;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;

//@formatter:off
/**
 * @author JOJO
 * 
 * NPC          148     焚き火
 * |アイテム    21875   焚き火用の火打石 - 幹30個を持った状態で使うと焚き火をおこせます。村から一定距離以上離れた場所で焚き火をおこすと回復ボーナス効果が発揮されます。戦闘地域では回復力が上がります。トレード、ドロップ、破壊はできません。個人倉庫への保管はできます。
 * |            1864    幹(30)
 * |召喚スキル  22305-1 焚き火召喚
 * |BUFスキル   22304-1 焚き火の温もり - 焚き火の温もりが感じられます。HP回復力が80%、CP回復力が60%、MP回復力が40％増加します。
 */
public class CampfireBuffer extends AbstractNpcAI
{
	private static final int CAMPFIRE = 148;
	
	static final int CAMPFIRE_WARMTH = getSkillHashCode(22304, 1);
	
	private CampfireBuffer()
	{
		super(CampfireBuffer.class.getSimpleName(), "ai/npc/NpcBuffers/impl");
		addFirstTalkId(CAMPFIRE);
		addSpawnId(CAMPFIRE);
		if (getSkill(CAMPFIRE_WARMTH).getSkillType() == L2SkillType.NOTDONE) throw new RuntimeException();
	}
	
	@Override
	public String onFirstTalk(L2Npc npc, L2PcInstance player)
	{
		return null;
	}
	
	@Override
	public String onSpawn(L2Npc npc)
	{
		npc.setShowSummonAnimation(false);
		
		if (ZoneManager.getInstance().getZone(npc, L2TownZone.class) == null
	  /* && ZoneManager.getInstance().getZone(npc, L2****Zone.class) != null*/) //TODO: "戦闘地域では回復力が上がります。"
		{
			new CampfireAI(npc);
		}
		return null;
	}
	
	private static class CampfireAI implements Runnable
	{
		private final L2Npc _npc;
		private final ScheduledFuture<?> _aiTask;
		
		protected CampfireAI(L2Npc npc)
		{
			_npc = npc;
			_aiTask = ThreadPoolManager.getInstance().scheduleGeneralWithFixedDelay(this, 3000, 3000);
		}
		
		@Override
		public void run()
		{
			if (!_npc.isVisible())
			{
				_aiTask.cancel(false);
				return;
			}
			
			if (_npc.getKnownList().getKnownPlayers().size() == 0)
				return;
			
			final L2Skill campfireWarmth = getSkill(CAMPFIRE_WARMTH);
			final int skillRadius = campfireWarmth.getAffectRange();
			for (L2PcInstance player : _npc.getKnownList().getKnownPlayers().values())
			{
				if (player == null || !player.isVisible() || player.isInvul() || player.isMovementDisabled())
					continue;
				if (player.getPkKills() > 5)
					continue;
				if (!player.isInsideRadius(_npc, skillRadius, true, true))
					continue;
				if (player.getCurrentHp() < player.getMaxHp()
				 || player.getCurrentCp() < player.getMaxCp()
				 || player.getCurrentMp() < player.getMaxMp())
				{
					handleEffect(player, campfireWarmth);
				}
			}
		}
		
		private void handleEffect(L2PcInstance player, L2Skill skill)
		{
			if (! doesStack(player, skill))
			{
				skill.getEffects(player, player);
				player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT)
					.addSkillName(skill));
			}
		}
		
		private boolean doesStack(L2PcInstance player, L2Skill checkSkill)
		{
			AbnormalType type = checkSkill.getAbnormalType();
			for (L2Effect e : player.getAllEffects())
				if (e.getSkill().getAbnormalType() == type)
					return true;
			return false;
		}
	}
	
	public static void main(String[] args)
	{
		new CampfireBuffer();
	}
}
