package com.untamedears.PrisonPearl;

import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.block.DoubleChest;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;

public class PrisonPearl {
	private short id;
	private String imprisonedname;
	private InventoryHolder holder;
	private Item item;
	
	public PrisonPearl(short id, String imprisonedname, InventoryHolder holder) {
		this.id = id;
		this.imprisonedname = imprisonedname;
		this.holder = holder;
	}
	
	public short getID() {
		return id;
	}
	
	public String getImprisonedName() {
		return imprisonedname;
	}
	
	public Player getImprisonedPlayer() {
		return Bukkit.getPlayerExact(imprisonedname);
	}
	
	public InventoryHolder getHolder() {
		return holder;
	}
	
	public Entity getHolderEntity() {
		if (holder instanceof Entity)
			return (Entity)holder;
		else
			return null;
	}
	
	public BlockState getHolderBlockState() {
		if (holder instanceof BlockState) {
			return (BlockState)holder;
		} else if (holder instanceof DoubleChest) {
			return (BlockState)((DoubleChest)holder).getLeftSide();
		} else {
			return null;
		}
	}
	
	public Location getLocation() {
		if (holder != null) {
			if (holder instanceof Entity) {
				return ((Entity)holder).getLocation();
			} else if (holder instanceof BlockState) {
				return ((BlockState)holder).getLocation();
			} else if (holder instanceof DoubleChest) {
				return ((DoubleChest)holder).getLocation();
			} else {
				System.err.println("PrisonPearl " + id + " has an unexpected holder: " + holder);
				return null;
			}
		} else if (item != null) {
			return item.getLocation();
		} else {
			System.err.println("PrisonPearl " + id + " has no holder nor item");
			return null;
		}
	}
	
	public String getHolderName() {
		Entity entity;
		BlockState state;
		if ((entity = getHolderEntity()) != null) {
			if (entity instanceof Player) {
				return ((Player)entity).getDisplayName();
			} else {
				System.err.println("PrisonPearl " + id + " is held by a non-player entity");
				return "an unknown entity";
			}
		} else if ((state = getHolderBlockState()) != null) {
			switch (state.getType()) {
			case CHEST:
				return "a chest";
			case FURNACE:
				return "a furnace";
			case BREWING_STAND:
				return "a brewing stand";
			case DISPENSER:
				return "a dispenser";
			default:
				System.err.println("PrisonPearl " + id + " is inside an unknown block");
				return "an unknown block"; 
			}
		} else {
			System.err.println("PrisonPearl " + id + " has no holder nor item");
			return "unknown"; 
		}
	}
	
	public String describeLocation() {
		Location loc = getLocation();
		Vector vec = loc.toVector();
		String str = loc.getWorld().getName() + " " + vec.getBlockX() + " " + vec.getBlockY() + " " + vec.getBlockZ();
		
		if (holder != null)
			return "held by " + getHolderName() + " at " + str;
		else
			return "located at " + str;
	}
	
	public boolean verifyLocation() {
		Location loc = getLocation();
		
		if (item != null) {
			Chunk chunk = loc.getChunk();
			for (Entity entity : chunk.getEntities()) {
				if (entity == item)
					return true;
			}
			
			return false;
		} else {
			Inventory inv;
			if (holder instanceof Player) {
				inv = holder.getInventory();
			} else if (holder instanceof BlockState || holder instanceof DoubleChest) {
				BlockState newstate = loc.getBlock().getState();
				if (newstate.getClass() != holder.getClass())
					return false;
				inv = holder.getInventory();
			} else {
				return false;
			}

			for (ItemStack item : inv.all(Material.ENDER_PEARL).values()) {
				if (item.getDurability() == id)
					return true;
			}
			return false;
		}
	}
	
	public void setHolder(InventoryHolder holder) {
		this.holder = holder;
		item = null;
	}
	
	public void setItem(Item item) {
		holder = null;
		this.item = item;
	}
}

@@ -3423,26 +3423,8 @@
 e %7B%0A
-%09%09%09Inventory inv;%0A
 %09%09%09i
@@ -3463,166 +3463,256 @@
 %09%09%09i
-nv = holder.getInventory();%0A%09%09%09%7D else if (holder instanceof BlockState %7C%7C holder instanceof DoubleChest) %7B%0A%09%09%09%09BlockState newstate = loc.getBlock().getState()
+f (!((Player)holder).isOnline())%0A%09%09%09%09%09return false;%0A%09%09%09%7D else if (holder instanceof BlockState) %7B%0A%09%09%09%09if (!((BlockState)holder).update(true))%0A%09%09%09%09%09return false;%0A%09%09%09%7D else if (holder instanceof DoubleChest) %7B%0A%09%09%09%09DoubleChest dc = (DoubleChest)holder
 ;%0A%09%09
@@ -3721,47 +3721,51 @@
 if (
-news
+!((BlockS
 tate
+)dc
 .get
-Class() != holder.getClass(
+LeftSide()).update(true
 ))%0A%09
@@ -3785,17 +3785,36 @@
 lse;%0A%09%09%09
-%09
+%7D%0A%09%09%09%09%0A%09%09%09Inventory 
 inv = ho
@@ -3838,44 +3838,8 @@
 ();%0A
-%09%09%09%7D else %7B%0A%09%09%09%09return false;%0A%09%09%09%7D%0A%0A
 %09%09%09f

Remove some checks on prisonpearl validation causing double chests to always fail