package com.devotedmc.ExilePearl;

import java.util.Collection;
import java.util.UUID;

import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import com.devotedmc.ExilePearl.holder.PearlHolder;

public interface PearlAccess {
	
	/**
	 * Binds a player to an exile pearl
	 * @param exiledId The exiled player Id
	 * @param killerId The killing player ID
	 * @param holder The pearl holder
	 * @return The new ExilePearl if the operation succeeds, otherwise null
	 */
	ExilePearl exilePlayer(UUID exiledId, UUID killerId, PearlHolder holder);
	
	/**
	 * Binds a player to an exile pearl
	 * @param exiledId The exiled player Id
	 * @param killerId The killing player ID
	 * @param location The location to place the pearl
	 * @return The new ExilePearl if the operation succeeds, otherwise null
	 */
	ExilePearl exilePlayer(UUID exiledId, UUID killerId, Location location);
	
	/**
	 * Binds a player to an exile pearl
	 * @param exiledId The exiled player Id
	 * @param killer The killing player
	 * @return The new ExilePearl if the operation succeeds, otherwise null
	 */
	ExilePearl exilePlayer(UUID exiledId, Player killer);
	
	/**
	 * Gets a pearl instance by name
	 * @param name The name to search for
	 * @return The instance if it is found, otherwise null
	 */
	ExilePearl getPearl(String name);
	
	/**
	 * Gets a pearl instance by UUID
	 * @param uid The UUID to search for
	 * @return The instance if it is found, otherwise null
	 */
	ExilePearl getPearl(UUID uid);
	
	/**
	 * Gets the collection of all pearled instances.
	 * This collection is not modifiable.
	 * @return The pearl instance collection
	 */
	Collection<ExilePearl> getPearls();

	/**
	 * Gets whether a player is exiled
	 * @param player The player to check
	 * @return true if the player is exiled
	 */
	boolean isPlayerExiled(Player player);
	
	/**
	 * Gets whether a player is exiled
	 * @param uid The player UUID to check
	 * @return true if the player is exiled
	 */
	boolean isPlayerExiled(UUID uid);
	
	/**
	 * Gets an exile pearl instance from an item stack
	 * if it is valid 
	 * @param is The item stack to check
	 * @return The pearl instance if it exists, otherwise null
	 */
	ExilePearl getPearlFromItemStack(ItemStack is);
	
	/**
	 * Frees an exile pearl
	 * @param pearl The pearl to free
	 * @param reason The free reason
	 * @return true if the pearl is freed, otherwise false
	 */
	boolean freePearl(ExilePearl pearl, PearlFreeReason reason);
}

package com.devotedmc.ExilePearl;

import java.util.Collection;
import java.util.UUID;

import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import com.devotedmc.ExilePearl.holder.PearlHolder;

/**
 * Interface for exiling players and checking exile statuses
 * @author Gordon
 */
public interface PearlAccess {
	
	/**
	 * Binds a player to an exile pearl with the resulting pearl being placed
	 * in the given {@link PearlHolder} instance.
	 * <p>
	 * It's possible for the exile operation to fail, so the return value
	 * should be checked for success. A non-null value indicates success.
	 * <p>
	 * An exile operation can fail and return null for several reasons:
	 * <li> The player to be exiled is already exiled
	 * <li> The {@link PlayerPearledEvent} is canceled by another plugin
	 * @param exiledId The exiled player ID
	 * @param killerId The killing player ID
	 * @param holder The pearl holder
	 * @return The new {@link ExilePearl} instance if the operation succeeds, 
	 * otherwise null
	 */
	ExilePearl exilePlayer(UUID exiledId, UUID killerId, PearlHolder holder);
	
	/**
	 * Binds a player to an exile pearl with the resulting pearl being placed
	 * in the inventory of a specific location.
	 * <p>
	 * This method will return null if the block at the given location doesn't
	 * contain an inventory.
	 * @see PearlAccess#exilePlayer(UUID, UUID, PearlHolder)
	 * @param exiledId The exiled player ID
	 * @param killerId The killing player ID
	 * @param location The location to place the pearl
	 * @return The new {@link ExilePearl} instance if the operation succeeds, 
	 * otherwise null
	 */
	ExilePearl exilePlayer(UUID exiledId, UUID killerId, Location location);
	
	/**
	 * Binds a player to an exile pearl with the resulting pearl being placed
	 * in the inventory of the killing player.
	 * <p>
	 * This method will return null if the killing player is offline.
	 * <p>
	 * For instances when the killer could be offline, 
	 * {@link PearlAccess#exilePlayer(UUID, UUID, Location)} or
	 * {@link PearlAccess#exilePlayer(UUID, UUID, PearlHolder)} should be used.
	 * @see PearlAccess#exilePlayer(UUID, UUID, PearlHolder)
	 * @param exiledId The exiled player Id
	 * @param killer The killing player
	 * @return The new {@link ExilePearl} instance if the operation succeeds, 
	 * otherwise null
	 */
	ExilePearl exilePlayer(UUID exiledId, Player killer);
	
	/**
	 * Gets a pearl instance by player name
	 * @param name The player name to search for
	 * @return The {@link ExilePearl} instance if found, otherwise null
	 */
	ExilePearl getPearl(String name);
	
	/**
	 * Gets a pearl instance by player UUID
	 * @param uid The player UUID to search for
	 * @return The {@link ExilePearl} instance if found, otherwise null
	 */
	ExilePearl getPearl(UUID uid);
	
	/**
	 * Gets an immutable collection of all {@link ExilePearl} instances.
	 * This collection can't be modified.
	 * @return A collection of all {@link ExilePearl} instances
	 */
	Collection<ExilePearl> getPearls();

	/**
	 * Checks whether a player is exiled
	 * @param player The player to check
	 * @return true if the player is exiled
	 */
	boolean isPlayerExiled(Player player);
	
	/**
	 * Checks whether a player is exiled
	 * @param uid The player UUID to check
	 * @return true if the player is exiled
	 */
	boolean isPlayerExiled(UUID uid);
	
	/**
	 * Attempts to get an {@link ExilePearl} instance from the item stack of
	 * of the pearl.
	 * <p>
	 * This will only return a non-null value if the item stack parameter is
	 * a valid ExilePearl item.
	 * @param is The item stack to check
	 * @return The {@link ExilePearl} instance if found, otherwise null
	 */
	ExilePearl getPearlFromItemStack(ItemStack is);
	
	/**
	 * Frees an exile pearl
	 * <p>
	 * It's possible for the free operation to fail if the
	 * {@link PlayerFreedEvent} is canceled.
	 * @param pearl The pearl instance to free
	 * @param reason The reason that the pearl is being freed
	 * @return true if the pearl is freed, otherwise false
	 */
	boolean freePearl(ExilePearl pearl, PearlFreeReason reason);
}

Update docs