/*
 * This file is part of CitizensNpcProvider for NucleusFramework, licensed under the MIT License (MIT).
 *
 * Copyright (c) JCThePants (www.jcwhatever.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.jcwhatever.nucleus.providers.citizensnpc.traits.citizens;

import com.jcwhatever.nucleus.providers.citizensnpc.Npc;
import com.jcwhatever.nucleus.providers.citizensnpc.storage.DataNodeKey;
import com.jcwhatever.nucleus.providers.npc.INpc;
import com.jcwhatever.nucleus.providers.npc.traits.NpcTraitType;
import com.jcwhatever.nucleus.providers.npc.traits.NpcTrait;
import com.jcwhatever.nucleus.storage.IDataNode;
import com.jcwhatever.nucleus.utils.PreCon;

import org.bukkit.inventory.ItemStack;

import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.trait.trait.Equipment;
import net.citizensnpcs.api.trait.trait.Equipment.EquipmentSlot;

import javax.annotation.Nullable;

/**
 * Adapter for Citizens equipment trait.
 */
public class EquipmentTrait extends NpcTrait {

    private final Equipment _trait;

    /**
     * Constructor.
     *
     * @param npc  The NPC the trait is for.
     * @param type The parent type that instantiated the trait.
     */
    public EquipmentTrait(INpc npc, NpcTraitType type, IDataNode dataNode) {
        super(type);

        _trait = ((Npc)npc).getHandle().getTrait(Equipment.class);

        try {
            _trait.load(new DataNodeKey(dataNode.getNodePath(), dataNode, null));
        } catch (NPCLoadException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean isReusable() {
        return false;
    }

    /**
     * Get the {@link ItemStack} in the specified slot.
     *
     * @param slot  The slot. Can be a number (0-4) or the name of the slot:
     *              'HAND', 'HELMET', 'CHESTPLATE', 'LEGGINGS' or 'BOOTS'
     *
     * @return  The {@link ItemStack} in the slot or null if there is none.
     */
    @Nullable
    public ItemStack get(Object slot) {
        PreCon.notNull(slot);

        return _trait.get(getSlot(slot));
    }

    /**
     * Set the {@link ItemStack} in the specified equipment slot.
     *
     * @param slot  The slot. Can be a number (0-4) or the name of the slot:
     *              'HAND', 'HELMET', 'CHESTPLATE', 'LEGGINGS' or 'BOOTS'
     * @param item  The {@link ItemStack} to set into the slot. Null to empty the slot.
     *
     * @return  Self for chaining.
     */
    public EquipmentTrait set(Object slot, @Nullable ItemStack item) {
        PreCon.notNull(slot);

        _trait.set(getSlot(slot), item);

        return this;
    }

    @Override
    public String toString() {
        return _trait.toString();
    }

    private EquipmentSlot getSlot(Object slot) {

        EquipmentSlot equipmentSlot;

        if (slot instanceof Number) {
            int index = ((Number)slot).intValue();

            switch (index) {
                case 0:
                    equipmentSlot = EquipmentSlot.HAND;
                    break;
                case 1:
                    equipmentSlot = EquipmentSlot.HELMET;
                    break;
                case 2:
                    equipmentSlot = EquipmentSlot.CHESTPLATE;
                    break;
                case 3:
                    equipmentSlot = EquipmentSlot.LEGGINGS;
                    break;
                case 4:
                    equipmentSlot = EquipmentSlot.BOOTS;
                    break;
                default:
                    throw new IllegalArgumentException("Value of 'slot' must be a number from 0 to 4.");
            }
        }
        else if (slot instanceof EquipmentSlot) {
            equipmentSlot = (EquipmentSlot)slot;
        }
        else if (slot instanceof String) {

            String slotName = ((String)slot).toUpperCase();

            try {
                equipmentSlot = EquipmentSlot.valueOf(slotName);
            }
            catch (Exception e) {
                throw new IllegalArgumentException("Value of 'slot' must be one of: " +
                        "'HAND', 'HELMET', 'CHESTPLATE', 'LEGGINGS' or 'BOOTS'");
            }
        }
        else {
            throw new IllegalArgumentException("Value of 'slot' must be one of: " +
                    "'HAND', 'HELMET', 'CHESTPLATE', 'LEGGINGS' or 'BOOTS'");
        }

        return equipmentSlot;
    }
}

@@ -1542,20 +1542,16 @@
 NpcTrait
-Type
 ;%0Aimport
@@ -1595,32 +1595,36 @@
 .traits.NpcTrait
+Type
 ;%0Aimport com.jcw
@@ -1703,16 +1703,81 @@
 reCon;%0A%0A
+import org.bukkit.Material;%0Aimport org.bukkit.entity.EntityType;%0A
 import o
@@ -2109,24 +2109,53 @@
 NpcTrait %7B%0A%0A
+    private final INpc _npc;%0A
     private 
@@ -2426,24 +2426,44 @@
 per(type);%0A%0A
+        _npc = npc;%0A
         _tra
@@ -3711,32 +3711,293 @@
     
-_trait.set(getSlot(s
+EquipmentSlot eSlot = getSlot(slot);%0A%0A        if (_npc.getTraits().getType() == EntityType.ENDERMAN &&%0A                eSlot != EquipmentSlot.HAND) %7B%0A            return this;%0A        %7D%0A%0A        if (item == null)%0A            item = new ItemStack(Material.AIR);%0A%0A        _trait.set(eS
 lot
-)
 , it

fix exception in EquipmentTrait due to enderman