package wdl.worldgaurd;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.bukkit.entity.Player;

import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.WGBukkit;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;

import wdl.range.IRangeGroup;
import wdl.range.IRangeProducer;
import wdl.range.ProtectionRange;

/**
 * IRangeProducer that gets the ranges owned by a player.
 * 
 * TODO:
 * 1. Make sure that ProtectedRegion#isPhysicalArea is true.
 * 2. Make sure that all of the regions are loaded.
 * 3. Handle new regions dynamically. (there doesn't _seem_ to be events for it)
 * 4. Maybe there is a better way to get all of the regions owned by a player.
 */
public class WorldGuardRangeProducer implements IRangeProducer {
	private final IRangeGroup group;
	private final OwnershipType ownershipType;
	private final boolean preservePolygons;
	
	public WorldGuardRangeProducer(IRangeGroup group, OwnershipType ownershipType, 
			boolean preservePolygons) {
		this.group = group;
		this.ownershipType = ownershipType;
		this.preservePolygons = preservePolygons;
	}
	
	@Override
	public List<ProtectionRange> getInitialRanges(Player player) {
		ArrayList<ProtectionRange> ranges = new ArrayList<>();
		LocalPlayer localPlayer = WGBukkit.getPlugin().wrapPlayer(player);
		
		RegionManager manager = WGBukkit.getRegionManager(player.getWorld());
		
		Collection<ProtectedRegion> regions = manager.getRegions().values();
		for (ProtectedRegion region : regions) {
			if (ownershipType.has(localPlayer, region)) {
				ranges.addAll(regionToRange(region));
			}
		}
		
		return ranges;
	}

	@Override
	public IRangeGroup getRangeGroup() {
		return group;
	}

	/**
	 * Converts a {@link ProtectedRegion} to a collection of
	 * {@link ProtectionRange}s.
	 */
	private List<ProtectionRange> regionToRange(ProtectedRegion region) {
		BlockVector max = region.getMaximumPoint();
		BlockVector min = region.getMinimumPoint();
		
		int x1 = min.getBlockX() / 16;
		int z1 = min.getBlockZ() / 16;
		int x2 = max.getBlockX() / 16;
		int z2 = max.getBlockZ() / 16;
		
		List<ProtectionRange> ranges = new ArrayList<>();
		
		if (preservePolygons && region instanceof ProtectedPolygonalRegion) {
			//TODO: there's probably something I can do to improve this logic.
			
			for (int x = x1; x <= x2; x++) {
				for (int z = z1; z <= z2; z++) {
					// Only checking the corners - probably a bad idea, but this
					// should cover _most_ parts.
					
					if (region.contains(new BlockVector2D(x * 16, z * 16))
							|| region.contains(new BlockVector2D(x * 16 + 15,
									z * 16))
							|| region.contains(new BlockVector2D(x * 16,
									z * 16 + 15))
							|| region.contains(new BlockVector2D(x * 16 + 15,
									z * 16 + 15))) {
						ranges.add(new ProtectionRange(region.getId(), x, z, x,
								z));
					}
				}
			}
		} else {
			ranges.add(new ProtectionRange(region.getId(), x1, z1, x2, z2));
		}
		
		return ranges;
	}
	
	@Override
	public void dispose() { }
}

@@ -708,70 +708,8 @@
 * 1.
- Make sure that ProtectedRegion#isPhysicalArea is true.%0D%0A * 2.
  Mak
@@ -759,9 +759,9 @@
 %0A * 
-3
+2
 . Ha
@@ -841,9 +841,9 @@
 %0A * 
-4
+3
 . Ma
@@ -2415,16 +2415,108 @@
 );%0D%0A%09%09%0D%0A
+%09%09if (!region.isPhysicalArea()) %7B%0D%0A%09%09%09// Return an empty list.%0D%0A%09%09%09return ranges;%0D%0A%09%09%7D%0D%0A%09%09%0D%0A
 %09%09if (pr

Check that each reigon is a phyiscal area.