package nu.nerd.easyrider.commands;

import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.AbstractHorse;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Llama;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEntityEvent;

import nu.nerd.easyrider.Ability;
import nu.nerd.easyrider.EasyRider;
import nu.nerd.easyrider.IPendingInteraction;
import nu.nerd.easyrider.Util;
import nu.nerd.easyrider.db.SavedHorse;

//-----------------------------------------------------------------------------
/**
 * CommandExecutor implementation for the /horse-level command.
 */
public class HorseLevelsExecutor extends ExecutorBase {
    // ------------------------------------------------------------------------
    /**
     * Default constructor.
     */
    public HorseLevelsExecutor() {
        super("horse-levels", "help");
    }

    // ------------------------------------------------------------------------
    /**
     * @see org.bukkit.command.CommandExecutor#onCommand(org.bukkit.command.CommandSender,
     *      org.bukkit.command.Command, java.lang.String, java.lang.String[])
     */
    @Override
    public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
        if (!(sender instanceof Player)) {
            sender.sendMessage(ChatColor.RED + "You must be in game to use this command.");
            return true;
        }

        if (args.length == 0) {
            Player player = (Player) sender;
            if (player.getVehicle() instanceof AbstractHorse) {
                showLevels(player, (AbstractHorse) player.getVehicle());
            } else {
                sender.sendMessage(ChatColor.GOLD + "Right click on an animal to show level information.");
                EasyRider.PLUGIN.getState(player).setPendingInteraction(new IPendingInteraction() {
                    @Override
                    public void onPlayerInteractEntity(PlayerInteractEntityEvent event, SavedHorse savedHorse) {
                        showLevels(event.getPlayer(), (AbstractHorse) event.getRightClicked());
                    }
                });
            }
            return true;
        } else {
            return false;
        }
    }

    // ------------------------------------------------------------------------
    /**
     * Send the specified player information about the current levels of the
     * specified horse or the attributes of a llama.
     */
    protected void showLevels(Player player, AbstractHorse abstractHorse) {
        SavedHorse savedHorse = EasyRider.DB.findOrAddHorse(abstractHorse);
        String type = Util.entityTypeName(abstractHorse);
        type = Character.toUpperCase(type.charAt(0)) + type.substring(1);
        player.sendMessage(ChatColor.GOLD + type + ": " + ChatColor.YELLOW + abstractHorse.getUniqueId());
        AnimalTamer owner = abstractHorse.getOwner();
        String ownerName = (owner != null) ? owner.getName() : "<no owner>";
        player.sendMessage(ChatColor.GOLD + "Owner: " + ChatColor.YELLOW + ownerName);
        if (Util.isTrainable(abstractHorse)) {
            showLevel(player, EasyRider.CONFIG.SPEED, savedHorse);
            showLevel(player, EasyRider.CONFIG.HEALTH, savedHorse);
            showLevel(player, EasyRider.CONFIG.JUMP, savedHorse);
        } else if (abstractHorse instanceof Llama) {
            Llama llama = (Llama) abstractHorse;
            player.sendMessage(ChatColor.GOLD + "Strength: " + ChatColor.GRAY + llama.getStrength());
            showAttribute(player, EasyRider.CONFIG.SPEED, abstractHorse);
            showAttribute(player, EasyRider.CONFIG.HEALTH, abstractHorse);
            showAttribute(player, EasyRider.CONFIG.JUMP, abstractHorse);
        }
        player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1.0f, 1.0f);
    }

    // ------------------------------------------------------------------------
    /**
     * Show information about the current level of an ability, the corresponding
     * attribute value, and the total effort expended for that ability on a
     * specific horse.
     *
     * When the maximum possible level is exceeded by training, colour the level
     * text red.
     *
     * @param player the player to be send messages.
     * @param abililty the {@link Ability}.
     * @param savedHorse the database state of the horse.
     */
    protected void showLevel(Player player, Ability ability, SavedHorse savedHorse) {
        double fractionalLevel = ability.getFractionalLevel(savedHorse);
        ChatColor levelColour = (fractionalLevel >= ability.getMaxLevel()) ? ChatColor.RED : ChatColor.WHITE;
        player.sendMessage(ChatColor.GOLD + ability.getDisplayName() + ": " +
                           levelColour + "Level " + String.format("%5.3f", fractionalLevel) +
                           ChatColor.GOLD + " - " +
                           ChatColor.YELLOW + ability.getFormattedValue(savedHorse) +
                           ChatColor.GRAY + " (" + ability.getFormattedEffort(savedHorse) + ")");
    }

    // ------------------------------------------------------------------------
    /**
     * Show the attribute value in a specified Ability of an AbstractHorse.
     *
     * @param player the player to message.
     * @param ability the Ability.
     * @param abstractHorse the horse-like entity.
     */
    protected void showAttribute(Player player, Ability ability, AbstractHorse abstractHorse) {
        double attributeValue = ability.getAttribute(abstractHorse);
        double displayValue = ability.toDisplayValue(attributeValue);
        String formattedValue = ability.formatValue(displayValue);
        player.sendMessage(ChatColor.GOLD + ability.getDisplayName() + ": " + ChatColor.GRAY + formattedValue);
    }
} // class HorseLevelsExecutor

@@ -428,24 +428,65 @@
 .EasyRider;%0A
+import nu.nerd.easyrider.HorseEquipment;%0A
 import nu.ne
@@ -2480,26 +2480,16 @@
 end the 
-specified 
 player i
@@ -2530,23 +2530,16 @@
 s of the
-%0A     *
  specifi
@@ -2540,16 +2540,23 @@
 pecified
+%0A     *
  horse o
@@ -2584,16 +2584,103 @@
  llama.%0A
+     *%0A     * @param player the player.%0A     * @param asbtractHorse the AbstractHorse.%0A
      */%0A
@@ -3284,24 +3284,283 @@
 ownerName);%0A
+        player.sendMessage(ChatColor.GOLD + %22Appearance: %22 +%0A                           ChatColor.WHITE + Util.getAppearance(abstractHorse) + %22 %22 +%0A                           ChatColor.YELLOW + HorseEquipment.description(HorseEquipment.bits(abstractHorse)));%0A
         if (
@@ -3901,110 +3901,8 @@
 se;%0A
-            player.sendMessage(ChatColor.GOLD + %22Strength: %22 + ChatColor.GRAY + llama.getStrength());%0A
     
@@ -4038,32 +4038,32 @@
 abstractHorse);%0A
-
             show
@@ -4111,32 +4111,134 @@
 abstractHorse);%0A
+            player.sendMessage(ChatColor.GOLD + %22Strength: %22 + ChatColor.GRAY + llama.getStrength());%0A
         %7D%0A      

Add appearance and equipment line to /hinfo output. List llama strength last in /hinfo, for consistency with Zyin's HUD.