package l2.universe.scripts.instances;

import l2.universe.gameserver.ThreadPoolManager;
import l2.universe.gameserver.ai.CtrlIntention;
import l2.universe.gameserver.datatables.NpcTable;
import l2.universe.gameserver.datatables.SkillTable;
import l2.universe.gameserver.instancemanager.GrandBossManager;
import l2.universe.gameserver.instancemanager.InstanceManager;
import l2.universe.gameserver.model.L2CharPosition;
import l2.universe.gameserver.model.L2Effect;
import l2.universe.gameserver.model.L2Party;
import l2.universe.gameserver.model.L2Skill;
import l2.universe.gameserver.model.L2Spawn;
import l2.universe.gameserver.model.L2World;
import l2.universe.gameserver.model.Location;
import l2.universe.gameserver.model.actor.L2Character;
import l2.universe.gameserver.model.actor.L2Npc;
import l2.universe.gameserver.model.actor.instance.L2PcInstance;
import l2.universe.gameserver.model.entity.Instance;
import l2.universe.gameserver.instancemanager.InstanceManager.InstanceWorld;
import l2.universe.gameserver.model.quest.Quest;
import l2.universe.gameserver.model.zone.L2ZoneType;
import l2.universe.gameserver.model.zone.type.L2BossZone;
import l2.universe.gameserver.network.SystemMessageId;
import l2.universe.gameserver.network.serverpackets.ExShowScreenMessage2;
import l2.universe.gameserver.network.serverpackets.SystemMessage;
import l2.universe.gameserver.taskmanager.DecayTaskManager;
import l2.universe.gameserver.templates.chars.L2NpcTemplate;
import l2.universe.util.Rnd;
import l2.universe.gameserver.util.Util;

import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

/**
 * @author Threata
 */
public class Freya extends Quest
{
    private class FreyaWorld extends InstanceWorld
    {
        private L2Npc Freya, Kegor, Jinia;
        private L2BossZone BossZone = GrandBossManager.getInstance().getZone(114722, -114797, -11203);
        private ArrayList<L2Npc> activeMobs = new ArrayList<L2Npc>();
        private ArrayList<L2Npc> activeKnights = new ArrayList<L2Npc>();
        private ArrayList<L2Npc> Glaciers = new ArrayList<L2Npc>();
        private ScheduledFuture<?> GlacierTimer = null;
        private ScheduledFuture<?> ArchersTimer = null;
    }

    private static final boolean debug = true;

    private static final int FreyaOnThrone = 29177; // 29178 - hard mode
    private static final int FreyaStand = 29179; // 29180 - hard mode
    private static final int Glacier = 18853; // cannot see oO why???
    private static final int Glakias = 25699; // 25700 - hard mode
    private static final int ArcheryKnight = 18855; // 18856 - hard mode
    private static final int ArchersBreath = 18854;
    // private static final int Sirra = 18852;
    // This npc must attack Freya
    private static final int Kegor = 18846; // and 18851
    private static final int Jinia = 18850;

    private static final int JiniaStart = 32781;

    private static final int[][] KnightSpawns = {
            {113828, -113498, -11172},
            {113366, -113968, -11172},
            {115606, -116099, -11172},
            {116073, -115631, -11172},
    };

    private static final int[][] GlacierSpawns = {
            {115176, -114614},
            {114918, -114361},
            {114539, -114349},
            {114270, -114613},
            {114271, -114981},
            {114526, -115249},
            {114905, -115252},
            {115167, -114996}
    };



    private static int checkworld(L2PcInstance player)
    {
        InstanceWorld checkworld = InstanceManager.getInstance().getPlayerWorld(player);
        if (checkworld != null)
        {
            if (!(checkworld instanceof FreyaWorld))
                return 0;
            return 1;
        }
        return 2;
    }

    @SuppressWarnings({ "deprecation", "unused" })
	private static boolean checkConditions(L2PcInstance player)
    {
        if (debug)
            return true;
        L2Party party = player.getParty();
        if (party == null || !party.isInCommandChannel())
        {
            if (party != null)
                party.broadcastToPartyMembers(new SystemMessage(SystemMessageId.NOT_IN_COMMAND_CHANNEL_CANT_ENTER));
            else
                player.sendPacket(SystemMessageId.NOT_IN_COMMAND_CHANNEL_CANT_ENTER);
            return false;
        }
        if (party.getCommandChannel().getChannelLeader() != player)
        {
            party.getCommandChannel().broadcastToChannelMembers(new SystemMessage(2765));
            return false;
        }
        int count = 0;
        for (int id : InstanceManager.getInstance().getInstances().keySet())
        {
            InstanceWorld inst = InstanceManager.getInstance().getWorld(id);
            if (inst != null && inst instanceof FreyaWorld)
                count++;
            if (count >= 3)
            {
                party.getCommandChannel().broadcastToChannelMembers(new SystemMessage(2104));
                return false;
            }

        }
        if (party.getCommandChannel().getMembers().size() < 10)
        {
            party.getCommandChannel().broadcastToChannelMembers(new SystemMessage(2793).addNumber(10));
            return false;
        }
        if (party.getCommandChannel().getMembers().size() > 27)
        {
            party.getCommandChannel().broadcastToChannelMembers(new SystemMessage(2764));
            return false;
        }
        Map<Integer, Long> instanceTimes;
        for (L2PcInstance plr : party.getCommandChannel().getMembers())
        {
            if (checkworld(plr) == 0)
            {
                party.getCommandChannel().broadcastToChannelMembers(new SystemMessage(SystemMessageId.ALREADY_ENTERED_ANOTHER_INSTANCE_CANT_ENTER));
                return false;
            }
            if (plr.getLevel() < 75)
            {
                party.getCommandChannel().broadcastToChannelMembers(new SystemMessage(SystemMessageId.C1_LEVEL_REQUIREMENT_NOT_SUFFICIENT).addPcName(plr));
                return false;
            }
            if (!plr.isInsideRadius(player, 1000, true, true))
            {
                party.getCommandChannel().broadcastToChannelMembers(new SystemMessage(SystemMessageId.C1_IS_IN_LOCATION_THAT_CANNOT_BE_ENTERED).addPcName(plr));
                return false;
            }
            instanceTimes = InstanceManager.getInstance().getAllInstanceTimes(plr.getObjectId());
            if (instanceTimes != null && instanceTimes.containsValue(139))
            {
                if (System.currentTimeMillis() < instanceTimes.get(139))
                {
                    party.getCommandChannel().broadcastToChannelMembers(new SystemMessage(SystemMessageId.C1_MAY_NOT_REENTER_YET).addPcName(plr));
                    return false;
                }
            }

        }
        return true;
    }

    private synchronized void enterInstance(L2PcInstance player)
    {
        InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
        if (checkworld(player) == 1)
        {
            teleportplayer(player, new Location(113871, -112435, -11200), (FreyaWorld)world);
            return;
        }
        if (checkConditions(player))
        {
            L2Party party = player.getParty();
            world = new FreyaWorld();
            world.instanceId = InstanceManager.getInstance().createDynamicInstance(null);
            world.templateId = 139;
            final Instance instance = InstanceManager.getInstance().getInstance(world.instanceId);
            instance.addDoor(23140101, true);
            // final int time = ?;
            // instance.setDuration(time);        TODO: unknown time
            // instance.setEmptyDestroyTime(time);
            final int[] returnLoc = {player.getX(), player.getY(), player.getZ()};
            instance.setSpawnLoc(returnLoc);
            InstanceManager.getInstance().addWorld(world);
            instance.setName("Ice Queen's Castle");
            world.status = 0;
            _log.info("Instance Ice Queen's Castle created with id "+world.instanceId+" and created by player "+player.getName());
            if (debug)
            {
                if (party == null)
                    teleportplayer(player, new Location(113871, -112435, -11200), (FreyaWorld)world);
                else
                    if (party.isInCommandChannel())
                        for (L2PcInstance partyMember : party.getCommandChannel().getMembers())
                            teleportplayer(partyMember, new Location(113871, -112435, -11200), (FreyaWorld)world);
                    else
                        for (L2PcInstance partyMember : party.getPartyMembers())
                            teleportplayer(partyMember, new Location(113871, -112435, -11200), (FreyaWorld)world);
            }
            else
                for (L2PcInstance partyMember : party.getCommandChannel().getMembers())
                    teleportplayer(partyMember, new Location(113871, -112435, -11200), (FreyaWorld)world);
        }
    }

    private void teleportplayer(L2PcInstance player, Location loc, FreyaWorld world)
    {
        player.setInstanceId(world.instanceId);
        player.teleToLocation(loc._x, loc._y, loc._z);
        if (!world.allowed.contains(player.getObjectId()))
            world.allowed.add(player.getObjectId());
    }

    private static L2Npc spawn(int npcId, int X, int Y, int Z, int head, FreyaWorld world)
    {
		try
		{
			L2NpcTemplate template = NpcTable.getInstance().getTemplate(npcId);
			if (template != null)
			{
				L2Spawn spawn = new L2Spawn(template);
				spawn.setHeading(head);
				spawn.setLocx(X);
				spawn.setLocy(Y);
				spawn.setLocz(Z + 20);
                spawn.setInstanceId(world.instanceId);
                spawn.setAmount(spawn.getAmount()+1);
                spawn.setOnKillDelay(1500);
				return spawn.doSpawn();
			}
		}
		catch (Exception e1)
		{
			_log.info("Freya: Could not spawn Npc " + npcId);
		}
        return null;
    }

    public static void startWave(int stage, FreyaWorld world)
    {
        final FreyaWorld Wworld = world;
        if (stage == 1)
        {
            world.BossZone.broadcastMovie(15, world.instanceId);

            ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
            {
                public void run()
                {
                    Wworld.Freya = spawn(FreyaOnThrone, 114720, -117068, -11078, 16384, Wworld);
                    ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
                    {
                        public void run()
                        {
                            Wworld.BossZone.broadcastPacket(new ExShowScreenMessage2(1801086, 6000, ExShowScreenMessage2.ScreenMessageAlign.TOP_CENTER, true, false, -1, true));
                            Freya.spawnGlaciers(Wworld);
                        }
                    }, 1000);
                }
            }, 53500);
        }
        if (stage == 2)
        {
            world.BossZone.broadcastMovie(16, world.instanceId);
            ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
            {
                public void run()
                {
                    Wworld.Freya = spawn(FreyaOnThrone, 114719, -117450, -10673, 16384, Wworld);
                    Wworld.Freya.setIsOverloaded(true);
                    Wworld.Freya.setIsInvul(true);
                    ThreadPoolManager.getInstance().scheduleGeneral(new Freya.Timer(60, Wworld), 100);
                    ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
                    {
                        public void run()
                        {
                            Wworld.BossZone.broadcastPacket(new ExShowScreenMessage2(1801087, 6000, ExShowScreenMessage2.ScreenMessageAlign.TOP_CENTER, true, false, -1, true));
                            Freya.spawnKnights(Wworld);
                            Freya.spawnGlaciers(Wworld);
                        }
                    }, 60100);
                }
            }, 21100);
        }
        if (stage == 3)
        {
            world.BossZone.broadcastMovie(17, world.instanceId);
            ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
            {
                public void run()
                {
                    Wworld.status++;
                    Wworld.Freya.deleteMe();
                    Wworld.Freya = spawn(FreyaStand, 114720, -117068, -11078, 16384, Wworld);
                    moveTo(Wworld.Freya, new Location(114722, -114797, -11200));
                    Freya.spawnGlaciers(Wworld);
                    Wworld.BossZone.broadcastPacket(new ExShowScreenMessage2(1801088, 6000, ExShowScreenMessage2.ScreenMessageAlign.TOP_CENTER, true, false, -1, true));
                }
            }, 21600);
        }
    }

    private static void stopAll(FreyaWorld world)
    {
        for (int objId : InstanceManager.getInstance().getInstance(world.instanceId).getPlayer())
        {
            L2PcInstance plr = (L2PcInstance) L2World.getInstance().findObject(objId);
            plr.abortCast();
            plr.abortAttack();
            plr.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
            plr.setIsImmobilized(true);
            plr.setIsInvul(true);
        }
        for (L2Npc npc : world.activeMobs)
        {
            npc.abortCast();
            npc.abortAttack();
            npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
            npc.setIsImmobilized(true);
            npc.setIsInvul(true);
        }
        for (L2Npc npc : world.Glaciers)
        {
            npc.abortCast();
            npc.abortAttack();
            npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
            npc.setIsImmobilized(true);
            npc.setIsInvul(true);
        }
        if (world.Freya != null)
        {
            world.Freya.abortCast();
            world.Freya.abortAttack();
            world.Freya.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
            world.Freya.setIsImmobilized(true);
            world.Freya.setIsInvul(true);
        }
        if (world.Glaciers.size() > 0)
        {
            for (int objId : InstanceManager.getInstance().getInstance(world.instanceId).getPlayer())
            {
                L2PcInstance plr = L2World.getInstance().findPlayer(objId);
                for (L2Effect e : plr.getAllEffects())
                {
                    if (e.getSkill().getId() == 6437)
                        e.exit();
                }
            }
        }
        world.ArchersTimer.cancel(false);
        world.GlacierTimer.cancel(false);
    }

    private static void startAll(FreyaWorld world)
    {
        for (L2Npc npc : world.activeMobs)
        {
            npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
            npc.setIsImmobilized(false);
            npc.setIsInvul(false);
        }
        for (final L2Npc npc : world.Glaciers)
        {
            npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
            npc.setIsImmobilized(false);
            npc.setIsInvul(false);
            world.ArchersTimer = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Runnable()
            {
                public void run()
                {
                    FreyaWorld wrld = (FreyaWorld) InstanceManager.getInstance().getWorld(npc.getInstanceId());
                    wrld.activeMobs.add(spawn(ArchersBreath, npc.getX(), npc.getY(), npc.getZ(), 0, wrld));
                }
            }, 10000, 10000);
        }
        if (world.Freya != null)
        {
            world.Freya.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
            world.Freya.setIsImmobilized(false);
            world.Freya.setIsInvul(false);
        }
        if (world.Glaciers.size() > 0)
        {
            for (int objId : InstanceManager.getInstance().getInstance(world.instanceId).getPlayer())
            {
                L2PcInstance plr = L2World.getInstance().findPlayer(objId);
                SkillTable.getInstance().getInfo(6437, world.Glaciers.size()).getEffects(world.Glaciers.get(Rnd.get(world.Glaciers.size())), plr);
            }
        }
        spawnGlaciers(world);
        for (int objId : InstanceManager.getInstance().getInstance(world.instanceId).getPlayer())
        {
            L2PcInstance plr = (L2PcInstance) L2World.getInstance().findObject(objId);
            plr.setIsImmobilized(false);
            plr.setIsInvul(false);
        }
    }

    private static void endStage(FreyaWorld world)
    {
        for (L2Npc npc : world.activeMobs)
            npc.deleteMe();
        for (L2Npc npc : world.activeKnights)
            npc.deleteMe();
        if (world.Glaciers.size() > 0)
        {
            for (int objId : InstanceManager.getInstance().getInstance(world.instanceId).getPlayer())
            {
                L2PcInstance plr = L2World.getInstance().findPlayer(objId);
                for (L2Effect e : plr.getAllEffects())
                {
                    if (e.getSkill().getId() == 6437)
                        e.exit();
                }
            }
        }
        for (L2Npc npc : world.Glaciers)
            npc.deleteMe();
        if (world.Freya != null)
            world.Freya.deleteMe();
        world.ArchersTimer.cancel(false);
        world.GlacierTimer.cancel(false);
    }

    @Override
    public String onEnterZone(L2Character character, L2ZoneType zone)
    {
        if (character instanceof L2PcInstance && character.getInstanceId() > 0)
        {
            InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(character.getInstanceId());
            if (tmpworld instanceof FreyaWorld)
            {
                final FreyaWorld world = (FreyaWorld) tmpworld;
                if (zone.getId() == 12020 && world.status < 1)
                {
                    world.status = 1;
                    ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
                    {
                        public void run()
                        {
                            startWave(1, world);
                        }
                    }, 20000);
                }
            }
        }
        return null;
    }

    @Override
    public String onTalk(L2Npc npc, L2PcInstance player)
    {
        if (npc.getNpcId() == JiniaStart && player.isGM())
            enterInstance(player);
        return null;
    }

    @Override
    public String onKill(L2Npc npc, L2PcInstance player, boolean isPet)
    {
        if (npc.getInstanceId() > 0)
        {
            InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
            if (tmpworld instanceof FreyaWorld)
            {
                final FreyaWorld world = (FreyaWorld) tmpworld;
                if (npc.getNpcId() == FreyaOnThrone && world.status == 1)
                {
                    endStage(world);
                    world.status = 2;
                    startWave(2, world);
                }
                else if (npc.getNpcId() == ArcheryKnight)
                {
                    if (world.status >= 2 && world.status < 12)
                    {
                        world.status++;
                        if (world.status >= 12)
                        {
                            world.BossZone.broadcastMovie(23, world.instanceId);
                            stopAll(world);
                            ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
                            {
                                public void run()
                                {
                                    spawn(Glakias, 114722, -114797, -11200, 16384, world);
                                    startAll(world);
                                }
                            }, 7000);
                        }
                    }
                    else
                    {
                        final int x = npc.getSpawn().getLocx(), y = npc.getSpawn().getLocy(), z = npc.getSpawn().getLocz();
                        ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
                        {
                            public void run()
                            {
                                world.activeKnights.add(spawn(ArcheryKnight, x, y, z, 0, world));
                            }
                        }, 15000);
                    }
                }
                else if (npc.getNpcId() == Glakias && world.status == 12)
                {
                    world.status++;
                    endStage(world);
                    ThreadPoolManager.getInstance().scheduleGeneral(new Timer(60, world), 100);
                    ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
                    {
                        public void run()
                        {
                            startWave(3, world);
                        }
                    }, 60100);
                }
                else if (npc.getNpcId() == FreyaStand && world.status == 15)
                {
                    world.status++;
                    endStage(world);
                    DecayTaskManager.getInstance().cancelDecayTask(npc);
                    world.BossZone.broadcastMovie(19, world.instanceId);
                    ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
                    {
                        public void run()
                        {
                            world.status++;
                        }
                    }, 16000);
                }
                else if (npc.getNpcId() == Glacier)
                {
                    npc.setDisplayEffect(3);
                    world.Glaciers.remove(npc);
                    if (world.Glaciers.size() > 0)
                    {
                        L2Skill skill = SkillTable.getInstance().getInfo(6437, world.Glaciers.size());
                        for (int objId : InstanceManager.getInstance().getInstance(world.instanceId).getPlayer())
                        {
                            L2PcInstance plr = L2World.getInstance().findPlayer(objId);
                            skill.getEffects(npc, plr);
                        }
                    }
                    if (world.GlacierTimer == null)
                    {
                        world.GlacierTimer = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
                        {
                            public void run()
                            {
                                spawnGlaciers(world);
                            }
                        }, 15000);
                    }
                }
            }
        }
        return null;
    }

    @Override
    public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isPet)
    {
        if (npc.getInstanceId() > 0)
        {
            InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
            if (tmpworld instanceof FreyaWorld)
            {
                final FreyaWorld world = (FreyaWorld) tmpworld;
                if (npc.getNpcId() == FreyaStand && npc.getCurrentHp() < npc.getMaxHp()*0.45 && world.status == 14)
                {
                    world.status++;
                    stopAll(world);
                    world.BossZone.broadcastMovie(18, world.instanceId);
                    ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
                    {
                        public void run()
                        {
                            startAll(world);
                            world.Kegor = spawn(Kegor, 114722, -114797, -11200, 0, world);
                            //((L2Attackable)world.Kegor).addDamageHate(world.Freya, 0, 9999);
                            world.Kegor.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, world.Freya);
                            world.Kegor.setRunning();
                            world.Jinia = spawn(Jinia, 114722, -114797, -11200, 0, world);
                            //((L2Attackable)world.Jinia).addDamageHate(world.Freya, 0, 9999);
                            world.Jinia.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, world.Freya);
                            world.Jinia.setRunning();
                            world.BossZone.broadcastPacket(new ExShowScreenMessage2(1801089, 6000, ExShowScreenMessage2.ScreenMessageAlign.TOP_CENTER, true, false, -1, true));
                        }
                    }, 28000);
                }
                else if (npc.getNpcId() == ArcheryKnight && npc.isImmobilized())
                {
                    npc.setDisplayEffect(2);
                    npc.setIsImmobilized(false);
                    startQuestTimer("respawnKnight", 6000, npc, null);
                }
            }
        }
        return super.onAttack(npc, player, damage, isPet);
    }

    private static void spawnKnights(FreyaWorld world)
    {
        for (int[] spawn : KnightSpawns)
        {
            L2Npc mob = spawn(ArcheryKnight, spawn[0], spawn[1], spawn[2], 0, world);
            mob.setDisplayEffect(1);
            mob.setIsImmobilized(true);
            world.activeKnights.add(mob);
        }
        if (world.status == 2)
        {
            world.activeKnights.add(spawn(ArcheryKnight, 114405, -115555, -11200, 0, world));
            world.activeKnights.add(spawn(ArcheryKnight, 115023, -115555, -11200, 0, world));
            world.activeKnights.add(spawn(ArcheryKnight, 115023, -114058, -11200, 0, world));
            world.activeKnights.add(spawn(ArcheryKnight, 114405, -114058, -11200, 0, world));
            world.activeKnights.add(spawn(ArcheryKnight, 114412, -114053, -11200, 0, world));
            world.activeKnights.add(spawn(ArcheryKnight, 114940, -114053, -11200, 0, world));
            world.activeKnights.add(spawn(ArcheryKnight, 114940, -115325, -11200, 0, world));
            world.activeKnights.add(spawn(ArcheryKnight, 114412, -115325, -11200, 0, world));
        }
    }

    private static void spawnGlaciers(FreyaWorld world)
    {
        if (world.Glaciers.size() < 7)
        {
            final FreyaWorld Wworld = world;
            final int[] spawn = GlacierSpawns[Rnd.get(GlacierSpawns.length)];
            final L2Npc mob = spawn(Glacier, spawn[0], spawn[1], -11200, 0, world);
            mob.getSpawn().setOnKillDelay(0);
            mob.setIsOverloaded(true);
            world.Glaciers.add(mob);
            if (world.ArchersTimer == null)
            {
                world.ArchersTimer = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Runnable()
                {
                    public void run()
                    {
                        for (L2Npc glac : Wworld.Glaciers)
                        {
                            Wworld.activeMobs.add(spawn(ArchersBreath, glac.getX(), glac.getY(), glac.getZ(), 0, Wworld));
                        }
                    }
                }, 10000, 10000);
            }
            for (int objId : InstanceManager.getInstance().getInstance(world.instanceId).getPlayer())
            {
                L2PcInstance plr = L2World.getInstance().findPlayer(objId);
                SkillTable.getInstance().getInfo(6437, world.Glaciers.size()).getEffects(mob, plr);
            }
            world.GlacierTimer = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
            {
                public void run()
                {
                    spawnGlaciers(Wworld);
                }
            }, 30000);
        }
    }

    private static class Timer implements Runnable
    {
        private int time = 0;
        private FreyaWorld world = null;
        public Timer(int _time, FreyaWorld _world)
        {
            time = _time;
            world = _world;
        }

        public void run()
        {
            if (time > 10)
            {
                world.BossZone.broadcastPacket(new ExShowScreenMessage2("00 : "+time, 1500, ExShowScreenMessage2.ScreenMessageAlign.TOP_CENTER, true, false, -1, false));
                ThreadPoolManager.getInstance().scheduleGeneral(new Timer(time-1, world), 1000);
            }
        }
    }

    private static int moveTo(L2Npc npc, Location loc)
    {
        int time = 0;
        if (npc != null)
        {
            double distance = Util.calculateDistance(loc._x, loc._y, loc._z, npc.getX(), npc.getY(), npc.getZ(), true);
            int heading = Util.calculateHeadingFrom(npc.getX(), npc.getY(), loc._x, loc._y);
            time = (int) (distance/npc.getRunSpeed()*1000);
            npc.setRunning();
            npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(loc._x, loc._y, loc._z, heading));
            npc.getSpawn().setLocx(loc._x);
            npc.getSpawn().setLocy(loc._y);
            npc.getSpawn().setLocz(loc._z);
        }
        return time==0?100:time;
    }

    @Override
    public final String onSpawn(L2Npc npc)
    {
        npc.setDisplayEffect(1);
        startQuestTimer("changeEffect", 1900, npc, null);
        return super.onSpawn(npc);
    }

    
	@Override
    public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
    {
        if (npc != null && npc.getInstanceId() > 0 && InstanceManager.getInstance().getWorld(npc.getInstanceId()) instanceof FreyaWorld)
        {
            FreyaWorld world = (FreyaWorld) InstanceManager.getInstance().getWorld(npc.getInstanceId());
            if (event.equalsIgnoreCase("changeEffect"))
                npc.setDisplayEffect(2);
            else if (event.equalsIgnoreCase("respawnKnight") && npc != null)
            {
                L2Npc knight = addSpawn(ArcheryKnight, npc.getSpawn().getLocx(), npc.getSpawn().getLocy(), npc.getSpawn().getLocz(), npc.getSpawn().getHeading(), false, 0, true, world.instanceId);
                knight.setDisplayEffect(1);
                knight.setIsImmobilized(true);
                startQuestTimer("startAggro", 90000, knight, null);
            }
            else if (event.equalsIgnoreCase("startAggro"))
            {
                npc.setDisplayEffect(2);
                npc.setIsImmobilized(false);
                startQuestTimer("respawnKnight", 6000, npc, null);
            }
        }
        return null;
    }


    public Freya(int id, String name, String descr)
    {
        super(id, name, descr);

        addEnterZoneId(12020);
        addKillId(FreyaOnThrone);
        addKillId(ArcheryKnight);
        addKillId(Glakias);
        addKillId(FreyaStand);
        addKillId(Glacier);
        addFirstTalkId(Jinia);
        addFirstTalkId(Kegor);
        addAttackId(FreyaStand);
        addAttackId(ArcheryKnight);
        addStartNpc(JiniaStart);
        addTalkId(JiniaStart);
        addSpawnId(Glacier);
    }

    public static void main(String[] args)
    {
        new Freya(-1, "Freya", "instances");
    }
}
