/*
 * Copyright 2014 Matthew Collins
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package uk.co.thinkofdeath.thinkcraft.bukkit.commands;

import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import uk.co.thinkofdeath.command.Command;
import uk.co.thinkofdeath.command.CommandHandler;
import uk.co.thinkofdeath.command.bukkit.HasPermission;
import uk.co.thinkofdeath.command.types.Range;
import uk.co.thinkofdeath.thinkcraft.bukkit.ThinkMapPlugin;

import java.io.File;

@SuppressWarnings("unused")
public class Commands implements CommandHandler {

    private final ThinkMapPlugin plugin;

    public Commands(ThinkMapPlugin plugin) {
        this.plugin = plugin;
    }

    @Command("thinkmap user count")
    public void count(@HasPermission(value = "thinkmap.user.count", wildcard = true) CommandSender sender) {
        if (plugin.getWebHandler() == null) {
            sender.sendMessage(ChatColor.AQUA + "The map viewer has not started yet");
            return;
        }
        int count = plugin.getWebHandler().getChannelGroup().size();
        sender.sendMessage(ChatColor.AQUA + "There are "
                + count
                + " user" + (count != 1 ? "s" : "")
                + " currently connected to the map viewer");
    }

    @Command("thinkmap force-generate")
    public void forceGen(@HasPermission(value = "thinkmap.force-generate", wildcard = true) CommandSender sender) {
        forceGen(sender, 2);
    }

    @Command("thinkmap force-generate ?")
    public void forceGen(@HasPermission(value = "thinkmap.force-generate", wildcard = true) CommandSender sender,
                         @Range(min = 1) int regionsPerCycle) {
        for (World world : plugin.getServer().getWorlds()) {
            forceGen(sender, world, regionsPerCycle);
        }
    }

    @Command("thinkmap force-generate ?")
    public void forceGen(@HasPermission(value = "thinkmap.force-generate", wildcard = true) CommandSender sender,
                         World target) {
        forceGen(sender, target, 2);
    }

    @Command("thinkmap force-generate ? ?")
    public void forceGen(@HasPermission(value = "thinkmap.force-generate", wildcard = true) final CommandSender sender,
                         final World world,
                         @Range(min = 1) final int regionsPerCycle) {
        sender.sendMessage("Generating world data for " + world.getName() + " - Please wait, this may cause lag");
        new BukkitRunnable() {

            private int w = 0;
            private int r = 0;

            @Override
            public void run() {
                File worldFolder = new File(world.getWorldFolder(), "region");
                if (!worldFolder.exists()) {
                    // handle nether/end
                    worldFolder = new File(world.getWorldFolder(), String.format("DIM%d/region", world.getEnvironment().getId()));
                    if (!worldFolder.exists()) {
                        sender.sendMessage("Failed to generate: " + world.getName());
                        return;
                    }
                }
                String[] regions = worldFolder.list();
                int count = 0;
                for (; r < regions.length; r++) {
                    String region = regions[r];
                    if (!region.endsWith(".mca")) {
                        continue;
                    }
                    String[] parts = region.split("\\.");
                    int rx = Integer.parseInt(parts[1]);
                    int rz = Integer.parseInt(parts[2]);
                    for (int x = 0; x < 32; x++) {
                        for (int z = 0; z < 32; z++) {
                            int cx = (rx << 5) + x;
                            int cz = (rz << 5) + z;
                            boolean unload = !world.isChunkLoaded(cx, cz);
                            if (world.loadChunk(cx, cz, false)) {
                                world.getChunkAt(cx, cz); // Trigger a chunk load
                                if (unload) {
                                    world.unloadChunkRequest(cx, cz);
                                }
                            }
                        }
                    }
                    sender.sendMessage(String.format("Progress: %d/%d", r, regions.length));
                    if (count++ > regionsPerCycle) {
                        return;
                    }
                }
                r = 0;
                sender.sendMessage("Complete");
                cancel();
            }
        }.runTaskTimer(plugin, 0, 10);
    }
}

@@ -975,12 +975,17 @@
 and.
-type
+validator
 s.Ra
@@ -1319,26 +1319,8 @@
     
-public void count(
 @Has
@@ -1369,33 +1369,55 @@
 wildcard = true)
- 
+%0A    public void count(
 CommandSender se
@@ -1901,37 +1901,16 @@
 e%22)%0A    
-public void forceGen(
 @HasPerm
@@ -1959,33 +1959,58 @@
 wildcard = true)
- 
+%0A    public void forceGen(
 CommandSender se
@@ -2099,37 +2099,16 @@
 ?%22)%0A    
-public void forceGen(
 @HasPerm
@@ -2169,55 +2169,55 @@
 rue)
- CommandSender sender,%0A                        
+%0A    public void forceGen(CommandSender sender,
  @Ra
@@ -2430,37 +2430,16 @@
 ?%22)%0A    
-public void forceGen(
 @HasPerm
@@ -2500,55 +2500,55 @@
 rue)
- CommandSender sender,%0A                        
+%0A    public void forceGen(CommandSender sender,
  Wor
@@ -2652,37 +2652,16 @@
 ?%22)%0A    
-public void forceGen(
 @HasPerm
@@ -2718,17 +2718,42 @@
  = true)
- 
+%0A    public void forceGen(
 final Co
@@ -2775,77 +2775,27 @@
 der,
-%0A                         final World world,%0A                        
+ final World world,
  @Ra

Move HasPermission to the method + fix imports for latest command change