package com.ramblingwood.minecraft.jsonapi.stringifier;

import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Logger;

import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.json.simpleForBukkit.JSONArray;
import org.json.simpleForBukkit.JSONObject;

import com.ramblingwood.minecraft.jsonapi.JSONAPI;

public class BukkitStringifier {
	public static HashMap<String, Class<?>> handle = new HashMap<String, Class<?>>();
	
	static {
		handle.put("Player", org.bukkit.entity.Player.class);
		handle.put("Player[]", org.bukkit.entity.Player[].class);
		handle.put("Server", org.bukkit.Server.class);
		handle.put("World", org.bukkit.World.class);
		handle.put("World[]", org.bukkit.World[].class);
		handle.put("Plugin", org.bukkit.plugin.Plugin.class);
		handle.put("Plugin[]", org.bukkit.plugin.Plugin[].class);
		handle.put("ItemStack", org.bukkit.inventory.ItemStack.class);
		handle.put("File", java.io.File.class);
		handle.put("ItemStack[]", org.bukkit.inventory.ItemStack[].class);
		handle.put("PlayerInventory", org.bukkit.inventory.PlayerInventory.class);
		handle.put("Location", org.bukkit.Location.class);
		handle.put("World.Environment", org.bukkit.World.Environment.class);
	}
	
	public static boolean canHandle(Class<?> c) {
		for(Class<?> cc : handle.values()) {
			// if (c instance of cc)
			if(cc.isAssignableFrom(c)) {
				return true;
			}
		}
		return false;
	}
	
	public static Object handle(Object obj) {
		if(obj instanceof World.Environment) {
			World.Environment e = (World.Environment)obj;
			if(e == World.Environment.NETHER) {
				return "nether";
			}
			else {
				return "normal";
			}
		}
		else if(obj instanceof File) {
			return ((File)obj).toString();
		}
		else if(obj instanceof Player) {
			Player p = (Player)obj;
			JSONObject o = new JSONObject();

			o.put("name", p.getName());
			o.put("op", p.isOp());
			o.put("health", p.getHealth());
			o.put("ip", p.getAddress().toString());
			o.put("itemInHand", p.getItemInHand());
			o.put("location", p.getLocation());
			o.put("inventory", p.getInventory());
			o.put("sneaking", p.isSneaking());
			o.put("inVehicle", p.isInsideVehicle());
			o.put("sleeping", p.isSleeping());
			o.put("world", p.getServer().getWorlds().indexOf(p.getWorld()));
			o.put("worldInfo", p.getWorld());
			
			return o;			
		}
		else if(obj instanceof Server) {
			Server s = (Server)obj;
			
			JSONObject o = new JSONObject();
			
			o.put("maxPlayers", s.getMaxPlayers());
			o.put("players", Arrays.asList(s.getOnlinePlayers()));
			o.put("port", s.getPort());
			o.put("name", s.getName());
			o.put("serverName", s.getServerName());
			o.put("version", s.getVersion());
			o.put("worlds", s.getWorlds());
			
			return o;
		}
		else if(obj instanceof World) {
			World w = (World)obj;
			
			JSONObject o = new JSONObject();
			
			o.put("environment", w.getEnvironment());
			o.put("fullTime", w.getFullTime());
			o.put("time", w.getTime());
			o.put("name", w.getName());
			o.put("isThundering", w.isThundering());
			o.put("hasStorm", w.hasStorm());
			
			return o;
		}
		else if(obj instanceof Plugin) {
			Plugin p = (Plugin)obj;
			PluginDescriptionFile d = p.getDescription();
			
			JSONObject o = new JSONObject();
			
			o.put("name", d.getName());
			o.put("description", d.getDescription());
			o.put("authors", d.getAuthors());
			o.put("version", d.getVersion());
			o.put("website", d.getWebsite());
			o.put("enabled", JSONAPI.instance.getServer().getPluginManager().isPluginEnabled(p));
			
			return o;
		}
		else if(obj instanceof ItemStack) {
			ItemStack i = (ItemStack)obj;
			
			JSONObject o = new JSONObject();
			
			o.put("type", i.getTypeId());
			o.put("durability", i.getDurability());
			o.put("amount", i.getAmount());
			
			return o;
		}
		else if(obj instanceof PlayerInventory) {
			PlayerInventory p = (PlayerInventory)obj;
			
			JSONObject o = new JSONObject();
			
			JSONObject armor = new JSONObject();
			armor.put("boots", p.getBoots());
			armor.put("chestplate", p.getChestplate());
			armor.put("helmet", p.getHelmet());
			armor.put("leggings", p.getLeggings());
			
			o.put("armor", armor);
			o.put("hand", p.getItemInHand());
			o.put("inventory", Arrays.asList(p.getContents()));
			
			return o;
		}
		else if(obj instanceof Location) {
			Location l = (Location)obj;
			
			JSONObject o = new JSONObject();
			
			o.put("x", l.getX());
			o.put("y", l.getY());
			o.put("z", l.getZ());
			o.put("pitch", l.getPitch());
			o.put("yaw", l.getYaw());
			
			return o;
		}
		else if(obj instanceof Plugin[]) {
			List<Plugin> l = Arrays.asList((Plugin[])obj);
			
			Collections.sort(l, new PluginSorter());
			
			return l;
		}
		else if(obj instanceof Object[]) {
			int l = ((Object[])obj).length;
			JSONArray a = new JSONArray();
			for(int i = 0; i < l; i++) {
				a.add(((Object[])obj)[i]);
			}
			
			return a; 
		}
		Logger.getLogger("JSONAPI").warning("Uncaugh object! Value:");
		Logger.getLogger("JSONAPI").warning(obj.toString());
		Logger.getLogger("JSONAPI").warning("Type:");
		Logger.getLogger("JSONAPI").warning(obj.getClass().getName());
		
		return new Object();
	}

	static class PluginSorter implements Comparator<Plugin> {
		@Override
		public int compare(Plugin o1, Plugin o2) {
			return o1.getDescription().getName().compareTo(o2.getDescription().getName());
		}
	}
}

@@ -3409,32 +3409,34 @@
 getName());%0D%0A%09%09%09
+//
 o.put(%22isThunder
@@ -3456,32 +3456,34 @@
 ndering());%0D%0A%09%09%09
+//
 o.put(%22hasStorm%22

fix #80. might add in later, api is unclear