// Path: api/src/main/java/net/techcable/npclib/Animation.java
// @RequiredArgsConstructor
// public enum Animation {
//     /**
//      * Makes the npc act hurt
//      * <p/>
//      * Only applicable to living entities
//      */
//     HURT,
//     /**
//      * Makes the npc lie on the ground
//      * <p/>
//      * Only applicable to living entities
//      */
//     DEAD,
// 
//     // Human Animations
// 
//     /**
//      * Makes the npc swing its arm
//      * <p/>
//      * Only applicable to human entities
//      */
//     ARM_SWING(HumanNPC.class),
//     /**
//      * Makes the npc eat the item it is holding
//      * <p/>
//      * Only applicable to human entities
//      */
//     EAT(HumanNPC.class),
//     /**
//      * A critical hit animation
//      * <p/>
//      * Only applicable to human entities
//      */
//     CRITICAL(HumanNPC.class),
//     /**
//      * A 'magic' critical hit animation
//      * <p/>
//      * Only applicable to human entities
//      */
//     MAGIC_CRITICAL(HumanNPC.class);
// 
// 
//     private final Class<? extends NPC> appliesTo;
// 
//     /**
//      * Get the type of npc this animation can be applied to
//      *
//      * @return the type of npc this animation can be applied to
//      */
//     public Class<? extends NPC> getAppliesTo() {
//         return appliesTo;
//     }
// 
//     private Animation() {
//         this(LivingNPC.class);
//     }
// }
// 
// Path: api/src/main/java/net/techcable/npclib/HumanNPC.java
// public interface HumanNPC extends LivingNPC {
// 
//     /**
//      * Return this npc's skin
//      * <p/>
//      * A value of null represents a steve skin
//      *
//      * @return this npc's skin
//      */
//     public UUID getSkin();
// 
//     /**
//      * Set the npc's skin
//      * <p/>
//      * A value of null represents a steve skin
//      *
//      * @param skin the player id with the skin you want
//      *
//      * @throws UnsupportedOperationException if skins aren't supported
//      */
//     public void setSkin(UUID skin);
// 
//     /**
//      * Set the npc's skin
//      * <p/>
//      * A value of null represents a steve skin
//      *
//      * @param skin the player name with the skin you want
//      *
//      * @throws UnsupportedOperationException if skins aren't supported
//      */
//     public void setSkin(String skin);
// 
//     /**
//      * Get the nmsEntity associated with this npc
//      *
//      * @return the nmsEntity
//      */
//     @Override
//     public Player getEntity();
// 
//     /**
//      * Set if the npc is shown in the tab list
//      *
//      * @param show whether or not to show this npc in the tab list
//      *
//      * @throws java.lang.IllegalStateException if the npcc is not spawned
//      */
//     public void setShowInTabList(boolean show);
// 
//     /**
//      * Return if the npc is shown in the tab list
//      *
//      * @return true if the npc is shown in the tab list
//      */
//     public boolean isShownInTabList();
// }


import java.util.UUID;
import com.google.common.base.Preconditions;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.util.PlayerAnimation;
import net.techcable.npclib.Animation;
import net.techcable.npclib.HumanNPC;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

    public void setSkin(String skin) {
        Preconditions.checkNotNull(skin, "Skin is null");
        // Hacky uuid load
        UUID id = Bukkit.getOfflinePlayer(skin).getUniqueId();
        // If the uuid's variant is '3' than it must be an offline uuid
        Preconditions.checkArgument(id.variant() != 3, "Invalid player name %s", skin);
        setSkin(id);
    }

    @Override
    public Player getEntity() {
        if (super.getEntity() == null) return null;
        return (Player) super.getEntity();

    }

    public static final String REMOVE_PLAYER_LIST_META = "removefromplayerlist";

    @Override
    public void setShowInTabList(boolean show) {
        Preconditions.checkState(isSpawned(), "Can not set shown in tablist if not spawned");
        getHandle().data().set(REMOVE_PLAYER_LIST_META, !show);
    }

    @Override
    public boolean isShownInTabList() {
        return !((Boolean) getHandle().data().get(REMOVE_PLAYER_LIST_META));
    }

    @Override

// Path: api/src/main/java/net/techcable/npclib/Animation.java
// @RequiredArgsConstructor
// public enum Animation {
//     /**
//      * Makes the npc act hurt
//      * <p/>
//      * Only applicable to living entities
//      */
//     HURT,
//     /**
//      * Makes the npc lie on the ground
//      * <p/>
//      * Only applicable to living entities
//      */
//     DEAD,
// 
//     // Human Animations
// 
//     /**
//      * Makes the npc swing its arm
//      * <p/>
//      * Only applicable to human entities
//      */
//     ARM_SWING(HumanNPC.class),
//     /**
//      * Makes the npc eat the item it is holding
//      * <p/>
//      * Only applicable to human entities
//      */
//     EAT(HumanNPC.class),
//     /**
//      * A critical hit animation
//      * <p/>
//      * Only applicable to human entities
//      */
//     CRITICAL(HumanNPC.class),
//     /**
//      * A 'magic' critical hit animation
//      * <p/>
//      * Only applicable to human entities
//      */
//     MAGIC_CRITICAL(HumanNPC.class);
// 
// 
//     private final Class<? extends NPC> appliesTo;
// 
//     /**
//      * Get the type of npc this animation can be applied to
//      *
//      * @return the type of npc this animation can be applied to
//      */
//     public Class<? extends NPC> getAppliesTo() {
//         return appliesTo;
//     }
// 
//     private Animation() {
//         this(LivingNPC.class);
//     }
// }
// 
// Path: api/src/main/java/net/techcable/npclib/HumanNPC.java
// public interface HumanNPC extends LivingNPC {
// 
//     /**
//      * Return this npc's skin
//      * <p/>
//      * A value of null represents a steve skin
//      *
//      * @return this npc's skin
//      */
//     public UUID getSkin();
// 
//     /**
//      * Set the npc's skin
//      * <p/>
//      * A value of null represents a steve skin
//      *
//      * @param skin the player id with the skin you want
//      *
//      * @throws UnsupportedOperationException if skins aren't supported
//      */
//     public void setSkin(UUID skin);
// 
//     /**
//      * Set the npc's skin
//      * <p/>
//      * A value of null represents a steve skin
//      *
//      * @param skin the player name with the skin you want
//      *
//      * @throws UnsupportedOperationException if skins aren't supported
//      */
//     public void setSkin(String skin);
// 
//     /**
//      * Get the nmsEntity associated with this npc
//      *
//      * @return the nmsEntity
//      */
//     @Override
//     public Player getEntity();
// 
//     /**
//      * Set if the npc is shown in the tab list
//      *
//      * @param show whether or not to show this npc in the tab list
//      *
//      * @throws java.lang.IllegalStateException if the npcc is not spawned
//      */
//     public void setShowInTabList(boolean show);
// 
//     /**
//      * Return if the npc is shown in the tab list
//      *
//      * @return true if the npc is shown in the tab list
//      */
//     public boolean isShownInTabList();
// }


// Path: citizens/src/main/java/net/techcable/npclib/citizens/HumanCitizensNPC.java
import java.util.UUID;
import com.google.common.base.Preconditions;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.util.PlayerAnimation;
import net.techcable.npclib.Animation;
import net.techcable.npclib.HumanNPC;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

    public void setSkin(String skin) {
        Preconditions.checkNotNull(skin, "Skin is null");
        // Hacky uuid load
        UUID id = Bukkit.getOfflinePlayer(skin).getUniqueId();
        // If the uuid's variant is '3' than it must be an offline uuid
        Preconditions.checkArgument(id.variant() != 3, "Invalid player name %s", skin);
        setSkin(id);
    }

    @Override
    public Player getEntity() {
        if (super.getEntity() == null) return null;
        return (Player) super.getEntity();

    }

    public static final String REMOVE_PLAYER_LIST_META = "removefromplayerlist";

    @Override
    public void setShowInTabList(boolean show) {
        Preconditions.checkState(isSpawned(), "Can not set shown in tablist if not spawned");
        getHandle().data().set(REMOVE_PLAYER_LIST_META, !show);
    }

    @Override
    public boolean isShownInTabList() {
        return !((Boolean) getHandle().data().get(REMOVE_PLAYER_LIST_META));
    }

    @Override

    public void animate(Animation animation) {
