package info.tregmine.commands;

import static org.bukkit.ChatColor.*;
import info.tregmine.Tregmine;
import info.tregmine.api.*;
import info.tregmine.api.math.MathUtil;
import info.tregmine.zones.Zone;

import java.util.List;

import org.bukkit.*;
import org.bukkit.entity.Horse;
import org.bukkit.potion.*;
import org.bukkit.scheduler.BukkitScheduler;

public class TeleportCommand extends AbstractCommand
{
    private static class TeleportTask implements Runnable
    {
        private TregminePlayer to;
        private TregminePlayer from;

        public TeleportTask(TregminePlayer to, TregminePlayer from)
        {
            this.to = to;
            this.from = from;
        }

        @Override
        public void run()
        {
            if (to.getCurrentZone() != null) {
                Zone toZone = to.getCurrentZone();
                Zone.Permission fromPermission = toZone.getUser(from);
                
                if (toZone.getEnterDefault()) {
                    if (fromPermission != null && fromPermission == Zone.Permission.Banned) { // Stop banned
                        from.sendMessage(RED + "You are banned from the zone " + to.getChatName() + RED + " is in!");
                        return;
                    }
                } else {
                    if (from.getRank().canModifyZones()) { // Allow Admins
                        
                    }else if (fromPermission == null) { // If doesn't have banned/allowed/maker/owner then stop as they are not allowed in
                        from.sendMessage(RED + "You are not allowed in the zone " + to.getChatName() + RED + " is in!");
                        return;
                    } else if (fromPermission == Zone.Permission.Banned) { // Stop banned, but let Allowed/Maker/Owner
                        from.sendMessage(RED + "You are banned from the zone " + to.getChatName() + RED + " is in!");
                        return;
                    }
                }
            }
            
            // Check position hasn't changed since task started.
            double distance = MathUtil.calcDistance2d(from.getLocation(), to.getLocation());
            
            if (distance > from.getRank().getTeleportDistanceLimit()) {
                from.sendMessage(RED + "Your teleportation spell is not strong enough for this long distance!");
                return;
            }
            
            Horse horse = null;

            if ((from.getVehicle() != null) && (from.getVehicle() instanceof Horse)){
                horse = (Horse)from.getVehicle();
            }

            if (horse != null){
                horse.eject();
                horse.teleport(to.getLocation());
                from.teleport(to.getLocation());
                horse.setPassenger(from.getDelegate());
            } else {
                from.teleport(to.getLocation());
            }

            from.setNoDamageTicks(200);
            if (!from.getRank().canDoHiddenTeleport()) {
                to.sendMessage(AQUA + from.getName() + " teleported to you!");
                PotionEffect ef =
                        new PotionEffect(PotionEffectType.BLINDNESS, 60, 100);
                from.addPotionEffect(ef);
            }
        }
    }

    public TeleportCommand(Tregmine tregmine)
    {
        super(tregmine, "tp");
    }

    @Override
    public boolean handlePlayer(TregminePlayer player, String[] args)
    {
        Rank rank = player.getRank();
        if (args.length != 1) {
            return false;
        }
        if (!rank.canTeleport()) {
            return true;
        }

        Server server = tregmine.getServer();
        BukkitScheduler scheduler = server.getScheduler();
        String name = args[0];

        List<TregminePlayer> candidates = tregmine.matchPlayer(name);
        if (candidates.size() != 1) {
            player.sendMessage(RED + "Can't find user.");
            return true;
        }

        TregminePlayer target = candidates.get(0);

        if (target.hasFlag(TregminePlayer.Flags.INVISIBLE)) {
            return true;
        }

        if (target.hasFlag(TregminePlayer.Flags.TPSHIELD) &&
            !player.getRank().canOverrideTeleportShield()) {
            player.sendMessage(RED + target.getName() + AQUA +
                    "'s teloptical deflector absorbed all motion. " +
                    "Teleportation failed.");
            target.sendMessage(player.getName() + AQUA +
                    "'s teleportation spell " +
                    "cannot bypass your sophisticated defenses.");
            return true;
        }

        World sourceWorld = player.getWorld();
        World targetWorld = target.getWorld();
        String targetWorldName = targetWorld.getName();
        String sourceWorldName = sourceWorld.getName();
        if (!sourceWorldName.equalsIgnoreCase(targetWorldName) &&
            !rank.canTeleportBetweenWorlds()) {
            player.sendMessage(RED + "The user is in another world called "
                    + BLUE + targetWorld.getName() + ".");
        }

        double distance = MathUtil.calcDistance2d(player.getLocation(),
                                          target.getLocation());
        if (distance <= rank.getTeleportDistanceLimit()) {
            player.sendMessage(AQUA + "You started teleport to " +
                    target.getName() + AQUA + " in " + BLUE +
                    targetWorld.getName() + ".");

            scheduler.scheduleSyncDelayedTask(
                    tregmine,
                    new TeleportTask(target, player),
                    rank.getTeleportTimeout());
        }
        else {
            player.sendMessage(RED
                    + "Your teleportation spell is not strong "
                    + "enough for the longer distances.");
        }

        return true;
    }
}

@@ -166,41 +166,8 @@
 til;
-%0Aimport info.tregmine.zones.Zone;
 %0A%0Aim
@@ -726,1169 +726,155 @@
 if (
-to.getCurrentZone() != null) %7B%0A                Zone toZone = to.getCurrentZone();%0A                Zone.Permission fromPermission = toZone.getUser(from);%0A                %0A                if (toZone.getEnterDefault()) %7B%0A                    if (fromPermission != null && fromPermission == Zone.Permission.Banned) %7B // Stop banned%0A                        from.sendMessage(RED + %22You are banned from the zone %22 + to.getChatName() + RED + %22 is in!%22);%0A                        return;%0A                    %7D%0A                %7D else %7B%0A                    if (from.getRank().canModifyZones()) %7B // Allow Admins%0A                        %0A                    %7Delse if (fromPermission == null) %7B // If doesn't have banned/allowed/maker/owner then stop as they are not allowed in%0A                        from.sendMessage(RED + %22You are not allowed in the zone %22 + to.getChatName() + RED + %22 is in!%22);%0A                        return;%0A                    %7D else if (fromPermission == Zone.Permission.Banned) %7B // Stop banned, but let Allowed/Maker/Owner%0A                        from.sendMessage(RED + %22You are banned from the zone %22 + to.getChatName() + RED + %22 is in!%22);%0A        
+!from.canBeHere(to.getLocation())) %7B%0A                from.sendMessage(RED + %22You do not have permission for the location of %22 + to.getChatName());%0A
     
@@ -909,62 +909,9 @@
     
-  
-      %7D%0A                %7D%0A            %7D%0A            
+%7D
 %0A   

Make use of new permission system canBeHere