001package net.minecraftforge.common;
002
003import java.util.HashMap;
004import java.util.HashSet;
005import java.util.Map;
006import java.util.Set;
007
008import net.minecraft.entity.item.EntityMinecart;
009import net.minecraft.item.Item;
010import net.minecraft.item.ItemStack;
011
012public class MinecartRegistry
013{
014    private static Map<MinecartKey, ItemStack> itemForMinecart = new HashMap<MinecartKey, ItemStack>();
015    private static Map<ItemStack, MinecartKey> minecartForItem = new HashMap<ItemStack, MinecartKey>();
016    /**
017     * Registers a custom minecart and its corresponding item.
018     * This should be the item used to place the minecart by the user,
019     * not the item dropped by the cart.
020     * @param cart The minecart.
021     * @param item The item used to place the cart.
022     */
023    public static void registerMinecart(Class<? extends EntityMinecart> cart, ItemStack item)
024    {
025        registerMinecart(cart, 0, item);
026    }
027
028    /**
029     * Registers a minecart and its corresponding item.
030     * This should be the item used to place the minecart by the user,
031     * not the item dropped by the cart.
032     * @param minecart The minecart.
033     * @param type The minecart type, used to differentiate carts that have the same class.
034     * @param item The item used to place the cart.
035     */
036    public static void registerMinecart(Class<? extends EntityMinecart> minecart, int type, ItemStack item)
037    {
038        MinecartKey key = new MinecartKey(minecart, type);
039        itemForMinecart.put(key, item);
040        minecartForItem.put(item, key);
041    }
042
043    /**
044     * Removes a previously registered Minecart. Useful for replacing the vanilla minecarts.
045     * @param minecart
046     * @param type
047     */
048    public static void removeMinecart(Class<? extends EntityMinecart> minecart, int type)
049    {
050        MinecartKey key = new MinecartKey(minecart, type);
051        ItemStack item = itemForMinecart.remove(key);
052        if (item != null)
053        {
054            minecartForItem.remove(item);
055        }
056    }
057
058    /**
059     * This function returns an ItemStack that represents this cart.
060     * The player should be able to use this item to place the minecart.
061     * This is the item that was registered with the cart via the registerMinecart function,
062     * but is not necessary the item the cart drops when destroyed.
063     * @param minecart The cart class
064     * @return An ItemStack that can be used to place the cart.
065     */
066    public static ItemStack getItemForCart(Class<? extends EntityMinecart> minecart)
067    {
068        return getItemForCart(minecart, 0);
069    }
070
071    /**
072     * This function returns an ItemStack that represents this cart.
073     * The player should be able to use this item to place the minecart.
074     * This is the item that was registered with the cart via the registerMinecart function,
075     * but is not necessary the item the cart drops when destroyed.
076     * @param minecart The cart class
077     * @param type The minecartType value
078     * @return An ItemStack that can be used to place the cart.
079     */
080    public static ItemStack getItemForCart(Class<? extends EntityMinecart> minecart, int type)
081    {
082        ItemStack item = itemForMinecart.get(new MinecartKey(minecart, type));
083        if (item == null)
084        {
085            return null;
086        }
087        return item.copy();
088    }
089
090    /**
091     * This function returns an ItemStack that represents this cart.
092     * The player should be able to use this item to place the minecart.
093     * This is the item that was registered with the cart via the registerMinecart function,
094     * but is not necessary the item the cart drops when destroyed.
095     * @param cart The cart entity
096     * @return An ItemStack that can be used to place the cart.
097     */
098    public static ItemStack getItemForCart(EntityMinecart cart)
099    {
100        return getItemForCart(cart.getClass(), cart.getMinecartType());
101    }
102
103    /**
104     * The function will return the cart class for a given item.
105     * If the item was not registered via the registerMinecart function it will return null.
106     * @param item The item to test.
107     * @return Cart if mapping exists, null if not.
108     */
109    public static Class<? extends EntityMinecart> getCartClassForItem(ItemStack item)
110    {
111        MinecartKey key = null;
112        for (Map.Entry<ItemStack, MinecartKey> entry : minecartForItem.entrySet())
113        {
114            if (entry.getKey().isItemEqual(item))
115            {
116                key = entry.getValue();
117                break;
118            }
119        }
120        if (key != null)
121        {
122            return key.minecart;
123        }
124        return null;
125    }
126
127    /**
128     * The function will return the cart type for a given item.
129     * Will return -1 if the mapping doesn't exist.
130     * If the item was not registered via the registerMinecart function it will return null.
131     * @param item The item to test.
132     * @return the cart minecartType value.
133     */
134    public static int getCartTypeForItem(ItemStack item)
135    {
136        MinecartKey key = null;
137        for (Map.Entry<ItemStack, MinecartKey> entry : minecartForItem.entrySet())
138        {
139            if (entry.getKey().isItemEqual(item))
140            {
141                key = entry.getValue();
142                break;
143            }
144        }
145        if (key != null)
146        {
147            return key.type;
148        }
149        return -1;
150    }
151
152    /**
153     * Will return a set of all registered minecart items.
154     * @return a copy of the set of all minecart items
155     */
156    public static Set<ItemStack> getAllCartItems()
157    {
158        Set<ItemStack> ret = new HashSet<ItemStack>();
159        for (ItemStack item : minecartForItem.keySet())
160        {
161            ret.add(item.copy());
162        }
163        return ret;
164    }
165    
166    static
167    {
168        registerMinecart(EntityMinecart.class, 0, new ItemStack(Item.minecartEmpty));
169        registerMinecart(EntityMinecart.class, 1, new ItemStack(Item.minecartCrate));
170        registerMinecart(EntityMinecart.class, 2, new ItemStack(Item.minecartPowered));
171    }
172    
173    public static class MinecartKey
174    {
175        public final Class<? extends EntityMinecart> minecart;
176        public final int type;
177
178        public MinecartKey(Class<? extends EntityMinecart> cls, int typtID)
179        {
180            minecart = cls;
181            type = typtID;
182        }
183
184        @Override
185        public boolean equals(Object obj)
186        {
187            if (obj == null)
188            {
189                return false;
190            }
191
192            if (getClass() != obj.getClass())
193            {
194                return false;
195            }
196
197            final MinecartKey other = (MinecartKey)obj;
198            if (this.minecart != other.minecart && (this.minecart == null || !this.minecart.equals(other.minecart)))
199            {
200                return false;
201            }
202
203            return (this.type == other.type);
204        }
205
206        @Override
207        public int hashCode()
208        {
209            int hash = 7;
210            hash = 59 * hash + (this.minecart != null ? this.minecart.hashCode() : 0);
211            hash = 59 * hash + this.type;
212            return hash;
213        }
214    }
215}