/*
 * 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 3 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/>.
 */
package ai.individual;

import java.text.SimpleDateFormat;
import java.util.Date;

import net.sf.l2j.Config;
import net.sf.l2j.gameserver.ai.CtrlIntention;
import net.sf.l2j.gameserver.instancemanager.GrandBossManager;
import net.sf.l2j.gameserver.model.L2CharPosition;
import net.sf.l2j.gameserver.model.actor.instance.L2GrandBossInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.zone.type.L2BossZone;
import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
import net.sf.l2j.gameserver.network.serverpackets.Earthquake;
import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
import net.sf.l2j.gameserver.network.serverpackets.PlaySound;
import net.sf.l2j.gameserver.network.serverpackets.SocialAction;
import net.sf.l2j.gameserver.network.serverpackets.SpecialCamera;
import net.sf.l2j.gameserver.templates.StatsSet;
import net.sf.l2j.gameserver.util.Broadcast;
import net.sf.l2j.util.Rnd;
import ai.group_template.L2AttackableAIScript;

/**
 * Antharas AI
 * @author Emperorc
 * modify JOJO 【アンタラス強中弱-試作品】
 
データベースのアップデートが必要：
INSERT IGNORE INTO grandboss_data SET boss_id=29066;
INSERT IGNORE INTO grandboss_data SET boss_id=29067;
INSERT IGNORE INTO grandboss_data SET boss_id=29068;
 */
public class Antharas2 extends L2AttackableAIScript
{
	
	private static final int ANTHARAS = 29019;			//寝タラス（奥で寝ているだけのダミー）
	private static final int ANTHARAS_WEAK   = 29066;	//弱タラス（実際に表に出て戦う）
	private static final int ANTHARAS_NORMAL = 29067;	//中タラス（実際に表に出て戦う）
	private static final int ANTHARAS_STRONG = 29068;	//強タラス（実際に表に出て戦う）
	private static final int BEHEMOTH_DRAGON = 29069;
	private static final int DRAGON_BOMBER = 29076;

	//Antharas Status Tracking :
	private static final byte DORMANT = 0;     	//Antharas is spawned and no one has entered yet. Entry is unlocked
	private static final byte WAITING = 1;     	//Antharas is spawend and someone has entered, triggering a 30 minute window for additional people to enter
	                							//before he unleashes his attack. Entry is unlocked
	private static final byte FIGHTING = 2;    	//Antharas is engaged in battle, annihilating his foes. Entry is locked
	private static final byte DEAD = 3;        	//Antharas has been killed. Entry is locked
    
	private static long _LastAction = 0;
	
	private static L2BossZone _Zone;
	private static L2NpcInstance[] _minions;
	
	// Boss: Antharas
	public Antharas2(int id,String name,String descr)
	{
        super(id,name,descr);
        int[] mob = {ANTHARAS, ANTHARAS_WEAK, ANTHARAS_NORMAL, ANTHARAS_STRONG};
        this.registerMobs(mob);
        _Zone = GrandBossManager.getInstance().getZone(179700,113800,-7709);

        int bossId, status;
        if      ((status = GrandBossManager.getInstance().getBossStatus(ANTHARAS_STRONG)) == FIGHTING) bossId = ANTHARAS_STRONG;
        else if ((status = GrandBossManager.getInstance().getBossStatus(ANTHARAS_NORMAL)) == FIGHTING) bossId = ANTHARAS_NORMAL;
        else if ((status = GrandBossManager.getInstance().getBossStatus(ANTHARAS_WEAK  )) == FIGHTING) bossId = ANTHARAS_WEAK;
        else
        {
        	//'ANTHARAS' must be DORMANT,WAITING or DEAD.
        	status = GrandBossManager.getInstance().getBossStatus(ANTHARAS); bossId = ANTHARAS;
        	if (status == FIGHTING) status = DEAD;
        }
        StatsSet info = GrandBossManager.getInstance().getStatsSet(bossId);
        
        if (info.getInteger("loc_x") == 0 && info.getInteger("loc_y") == 0) status = DEAD;	//[JOJO]
///////////////////////
System.out.println("〓Antharas2: bossId="+bossId+", status="+status);
///////////////////////
        if (status == DEAD)
        {
            // load the unlock date and time for antharas from DB
            long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
///////////////////////
//temp = 0; //〓DEBUG〓//
///////////////////////
            // if antharas is locked until a certain time, mark it so and start the unlock timer
            // the unlock time has not yet expired.  Mark Antharas as currently locked.  Setup a timer
            // to fire at the correct time (calculate the time between now and the unlock time,
            // setup a timer to fire after that many msec)
            if (temp > 0)
            {
                this.startQuestTimer("antharas_unlock", temp, null, null);
                _log.info("AI script : Next spawn date of Anthras is " + new SimpleDateFormat("yyyy/MM/dd HH:mm").format(new Date(info.getLong("respawn_time"))) + ".");
            }
            else
            {
                // the time has already expired while the server was offline. Immediately spawn antharas in his cave.
                // also, the status needs to be changed to DORMANT
                L2GrandBossInstance antharas = (L2GrandBossInstance) addSpawn(ANTHARAS,185708,114298,-8221,32768,false,0);
                GrandBossManager.getInstance().setBossStatus(ANTHARAS,DORMANT);
                _Zone.broadcastPacket(new Earthquake(185708,114298,-8221,20,10));
                GrandBossManager.getInstance().addBoss(antharas);
            }
        }
        else if (status == DORMANT)
        {
            L2GrandBossInstance antharas = (L2GrandBossInstance) addSpawn(ANTHARAS,185708,114298,-8221,32768,false,0);
            GrandBossManager.getInstance().addBoss(antharas);
        }
        else if (status == WAITING)
        {
            L2GrandBossInstance antharas = (L2GrandBossInstance) addSpawn(ANTHARAS,185708,114298,-8221,32768,false,0);
            GrandBossManager.getInstance().addBoss(antharas);
            // Start timer to lock entry after 30 minutes
            this.startQuestTimer("waiting_3",Config.FWA_APPTIMEOFANTHARAS, antharas, null);	//[JOJO]
        }
        else if (status == FIGHTING)
        {
            int loc_x = info.getInteger("loc_x");
            int loc_y = info.getInteger("loc_y");
            int loc_z = info.getInteger("loc_z") - 20;
            int heading = info.getInteger("heading");
            int hp = info.getInteger("currentHP");
            int mp = info.getInteger("currentMP");
            L2GrandBossInstance boss = (L2GrandBossInstance) addSpawn(bossId,loc_x,loc_y,loc_z,heading,false,0);
            L2GrandBossInstance anthras = (L2GrandBossInstance) addSpawn(ANTHARAS,185708,114298,-8221,32768,false,0);
            boss.setCurrentHpMp(hp,mp);
            GrandBossManager.getInstance().addBoss(boss);
            GrandBossManager.getInstance().addBoss(anthras);
            GrandBossManager.getInstance().setBossStatus(bossId,FIGHTING);
            GrandBossManager.getInstance().setBossStatus(ANTHARAS,FIGHTING);
            _LastAction = System.currentTimeMillis();
            // Start repeating timer to check for inactivity
            this.startQuestTimer("antharas_despawn",60000, boss, null, true);
        }
	}

	public String onAdvEvent (String event, L2NpcInstance npc, L2PcInstance player)
	{
        if (npc != null)
        {
            if (event.equals("waiting_3")) // <- scripts/teleports/6000_GrandBossTeleporters/__init__.py
            {
                this.startQuestTimer("waiting_2",60000, npc, null);
                this.screenMessage("3分前");
              //this.announce("アンタラス登場ムービーを見たい方はステージに近づいてください。");
/////////////////////////////////////////////////////////////////
//DEBUG:アンタラス散歩範囲マーカー
//addSpawn(31111, 181911, 114835, -7678,0,false,300000);
//for (int i=0; i < 19; i++)
//{
//    int x = 177915 + (int)(2300*Math.cos(i*0.330693963)); //.331~2pi/19
//    int y = 114941 + (int)(2300*Math.sin(i*0.330693963));
//    addSpawn(31111, x, y, -7707,0,false,300000);
//}
/////////////////////////////////////////////////////////////////
            }
            else if (event == "waiting_2")
            {
                this.startQuestTimer("waiting_1",60000, npc, null);
                this.screenMessage("2分前");
            }
            else if (event == "waiting_1")
            {
                this.startQuestTimer("waiting",60000, npc, null);
                this.screenMessage("1分前");
                _Zone.broadcastPacket(new Earthquake(179700,113800,-7709,40,15));
            }
            else if (event == "waiting")
            {
				int bossId =
					  _Zone.getAllowedPlayers().size() <= Config.FWA_LIMITOFWEAK ? ANTHARAS_WEAK
					: _Zone.getAllowedPlayers().size() <= Config.FWA_LIMITOFNORMAL ? ANTHARAS_NORMAL
					: ANTHARAS_STRONG;
				L2GrandBossInstance boss = (L2GrandBossInstance)addSpawn(bossId,185452,114835,-8221,32768,false,0);
				GrandBossManager.getInstance().addBoss(boss);
				TRACE("人数="+_Zone.getAllowedPlayers().size()+", bossId="+bossId);
                _Zone.updateKnownList(boss);
                boss.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(181911,114835,-7678,0));
                this.startQuestTimer("antharas_has_arrived",2000, boss, null, true);
                _Zone.broadcastPacket(new PlaySound(1, "BS02_A", 1, boss.getObjectId(), 185452, 114835, -8221));
                GrandBossManager.getInstance().setBossStatus(bossId,FIGHTING);
                GrandBossManager.getInstance().setBossStatus(ANTHARAS,FIGHTING);
                this.screenMessage("覚醒");
            }
            else if (event == "camera_1")
            {
                this.startQuestTimer("camera_2",3000, npc, null);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),700,13,-19,0,20000));
            }
            else if (event == "camera_2")
            {
                this.startQuestTimer("camera_3",10000, npc, null);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),700,13,0,6000,20000));
            }
            else if (event == "camera_3")
            {
                this.startQuestTimer("camera_4",200, npc, null);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),3700,0,-3,0,10000));
            }
            else if (event == "camera_4")
            {
                this.startQuestTimer("camera_5",10800, npc, null);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),1100,0,-3,22000,30000));
            }
            else if (event == "camera_5")
            {
                this.startQuestTimer("minion_spawn", 30000, npc, null, false);
                this.startQuestTimer("antharas_despawn",60000, npc, null, true);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),1100,0,-3,300,7000));
                _LastAction = System.currentTimeMillis();
                Broadcast.announceToOnlinePlayers("地竜アンタラスが登場しました。");
                this.announce("アンタラスを15分間攻撃しないでいると、巣穴に戻ってしまいます。");
            }
            else if (event == "antharas_despawn")
            {
                long temp = (System.currentTimeMillis() - _LastAction);
                if (temp > 900000)
                {
                    this.cancelQuestTimer("antharas_despawn", npc, null);

    				despawnMinions();	//+[JOJO]
					npc.deleteMe();
                    GrandBossManager.getInstance().setBossStatus(npc.getNpcId(),DORMANT);
                    GrandBossManager.getInstance().setBossStatus(ANTHARAS,DORMANT);
                    _Zone.oustAllPlayers();
                }
                else if (Config.FWV_MOVEATRANDOM && temp >= 60000 && ! npc.isAttackingNow()) //move at random.
                {
                    if (npc.getX() == 181911 && npc.getX() > 180660)	//stage --> arena.
                  //if (npc.getX() == 181911 && npc.getY() == 114835)	//stage --> arena.
                        npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(177915, 114941, -7707, 0));
                    else if (Rnd.get(5) == 0)
                        _Zone.broadcastPacket(new SocialAction(npc.getObjectId(), Rnd.get(1,4)));
                    else {
                        _Zone.updateKnownList(npc);
                        double radius = Rnd.get(2300);
                        double angle = Rnd.get() * 6.283185307179586476925286766559D;
                        int x = 177915 + (int)(radius*Math.cos(angle));
                        int y = 114941 + (int)(radius*Math.sin(angle));
                        npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(x, y, -7707, 0));
                    }
                }
            }
            else if (event == "antharas_has_arrived")
            {
               int dx = Math.abs(npc.getX() - 181911);
               int dy = Math.abs(npc.getY() - 114835);
               if (dx <= 50 && dy <= 50)
               {
                   this.cancelQuestTimer("antharas_has_arrived", npc, null);
                   this.startQuestTimer("camera_1",2000, npc, null);
                   npc.getSpawn().setLocx(181911);
                   npc.getSpawn().setLocy(114835);
                   npc.getSpawn().setLocz(-7678);
                   npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
               }
               else
               {
                   npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO,new L2CharPosition(181911,114835,-7678,0));
               }
            }
			else if (event == "minion_spawn")
				spawnMinions(npc);
            else if (event == "spawn_cubes")
            {
                addSpawn(31859,177615,114941,-7709,0,false,900000);
                int radius = 1500;
                for (int i=0; i < /*JOJO*/19; i++)
                {
                    int x = (int) (radius*Math.cos(i*0.330693963)); //.331~2pi/19
                    int y = (int) (radius*Math.sin(i*0.330693963));
                    addSpawn(31859,177615+x,114941+y,-7709,0,false,900000);
                }
//              this.cancelQuestTimer("antharas_despawn", npc, null);	//-[JOJO]
                this.startQuestTimer("remove_players",900000, null, null);
                this.screenMessage("討伐成功");
                this.announce("15分以内にアンタラスの棲処から退去してください。");
            }
        }
        else
        {
            if (event == "antharas_unlock")
            {
                L2GrandBossInstance antharas = (L2GrandBossInstance) addSpawn(ANTHARAS,185708,114298,-8221,32768,false,0);
                GrandBossManager.getInstance().addBoss(antharas);
                GrandBossManager.getInstance().setBossStatus(ANTHARAS,DORMANT);
                _Zone.broadcastPacket(new Earthquake(185708,114298,-8221,20,10));
            }
            else if (event == "remove_players")
            {
                _Zone.oustAllPlayers();
            }
        }
        return super.onAdvEvent(event, npc, player);
	}

	public String onAttack (L2NpcInstance npc, L2PcInstance attacker, int damage, boolean isPet)
	{	
        _LastAction = System.currentTimeMillis();
        if (GrandBossManager.getInstance().getBossStatus(ANTHARAS) != FIGHTING)
        {
            _Zone.oustAllPlayers();
        }
        return super.onAttack(npc, attacker, damage, isPet);
	}

    public String onKill (L2NpcInstance npc, L2PcInstance killer, boolean isPet) 
    { 
        this.cancelQuestTimer("antharas_despawn", npc, null);
        _Zone.broadcastPacket(new PlaySound(1, "BS01_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
		despawnMinions();	//+[JOJO]
        this.startQuestTimer("spawn_cubes", 10000, npc, null);
        GrandBossManager.getInstance().setBossStatus(npc.getNpcId(),DORMANT);
        GrandBossManager.getInstance().setBossStatus(ANTHARAS,DEAD);
		npc.deleteMe();
        long respawnTime = Config.FWA_FIXINTERVALOFANTHARAS + Rnd.get(Config.FWA_RANDOMINTERVALOFANTHARAS);	//[JOJO]
///////////////////////////////////
//respawnTime = 300000; //〓DEBUG〓//
///////////////////////////////////
		long respawnDateTime = System.currentTimeMillis() + respawnTime;	//[JOJO]
        this.startQuestTimer("antharas_unlock", respawnTime, null, null);
        // also save the respawn time so that the info is maintained past reboots
        StatsSet info = GrandBossManager.getInstance().getStatsSet(ANTHARAS);
        info.set("respawn_time", respawnDateTime);	//[JOJO]
        GrandBossManager.getInstance().setStatsSet(ANTHARAS,info);
		Broadcast.announceToOnlinePlayers("地竜アンタラスが死亡しました。次の復活は "+new SimpleDateFormat("yyyy/MM/dd HH:mm").format(new Date(respawnDateTime))+" ごろです。");	//[JOJO]
        return super.onKill(npc,killer,isPet);
    }

	private synchronized void spawnMinions(L2NpcInstance boss)
	{
		if (_minions != null) return;
		_minions = new L2NpcInstance[6];
		
		for (int i = 0; i < 6; i++)
		{
			double angle = i * 1.0471975511965977461542144610932D + 0.5; // 2*Math.PI/6
			int x = 177915 + (int)(2000.0 * Math.cos(angle));
			int y = 114941 + (int)(2000.0 * Math.sin(angle));
			int npcId = i % 2 == 0 ? BEHEMOTH_DRAGON : DRAGON_BOMBER;
			_minions[i] = addSpawn(npcId, x, y, -7710, 0, false, 0);
		}
	}
	private void despawnMinions()
	{
		if (_minions == null) return;
		for (L2NpcInstance mob : _minions)
			mob.deleteMe();
		_minions = null;
	}

    private void screenMessage(String text) //+[JOJO]
    {
        _Zone.broadcastPacket(new ExShowScreenMessage(text,/*time=>*/10000));
//      _Zone.broadcastPacket(new CreatureSay(0, 15, "アンタラス", text));
    }
    private void announce(String text) //+[JOJO]
    {
        _Zone.broadcastPacket(new CreatureSay(0, 10, "", text));
    }
    @Deprecated
    private void TRACE(String text) //+[JOJO]
    {
        _Zone.broadcastPacket(new CreatureSay(0, 2, "", text));
    }

    public static void main(String[] args)
    {
    	// now call the constructor (starts up the ai)
    	new Antharas2(-1,"antharas","ai");
    }
}
