001/*
002 * Forge Mod Loader
003 * Copyright (c) 2012-2013 cpw.
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser Public License v2.1
006 * which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
008 * 
009 * Contributors:
010 *     cpw - implementation
011 */
012
013package cpw.mods.fml.common.registry;
014
015import java.util.Map;
016
017import net.minecraft.block.Block;
018import net.minecraft.item.Item;
019import net.minecraft.item.ItemBlock;
020import net.minecraft.nbt.NBTTagCompound;
021
022import com.google.common.base.Objects;
023import com.google.common.collect.HashMultiset;
024import com.google.common.collect.Maps;
025import com.google.common.collect.Multiset;
026
027import cpw.mods.fml.common.FMLLog;
028import cpw.mods.fml.common.Loader;
029import cpw.mods.fml.common.LoaderException;
030import cpw.mods.fml.common.ModContainer;
031
032public class ItemData {
033
034    private static Map<String, Multiset<String>> modOrdinals = Maps.newHashMap();
035    private final String modId;
036    private final String itemType;
037    private final int itemId;
038    private final int ordinal;
039    private String forcedModId;
040    private String forcedName;
041
042    public ItemData(Item item, ModContainer mc)
043    {
044        this.itemId = item.itemID;
045        if (item.getClass().equals(ItemBlock.class))
046        {
047            this.itemType =  Block.blocksList[this.getItemId()].getClass().getName();
048        }
049        else
050        {
051            this.itemType = item.getClass().getName();
052        }
053        this.modId = mc.getModId();
054        if (!modOrdinals.containsKey(mc.getModId()))
055        {
056            modOrdinals.put(mc.getModId(), HashMultiset.<String>create());
057        }
058        this.ordinal = modOrdinals.get(mc.getModId()).add(itemType, 1);
059    }
060
061    public ItemData(NBTTagCompound tag)
062    {
063        this.modId = tag.getString("ModId");
064        this.itemType = tag.getString("ItemType");
065        this.itemId = tag.getInteger("ItemId");
066        this.ordinal = tag.getInteger("ordinal");
067        this.forcedModId = tag.hasKey("ForcedModId") ? tag.getString("ForcedModId") : null;
068        this.forcedName = tag.hasKey("ForcedName") ? tag.getString("ForcedName") : null;
069    }
070
071    public String getItemType()
072    {
073        return this.forcedName !=null ? forcedName : itemType;
074    }
075
076    public String getModId()
077    {
078        return this.forcedModId != null ? forcedModId : modId;
079    }
080
081    public int getOrdinal()
082    {
083        return ordinal;
084    }
085
086    public int getItemId()
087    {
088        return itemId;
089    }
090
091    public NBTTagCompound toNBT()
092    {
093        NBTTagCompound tag = new NBTTagCompound();
094        tag.setString("ModId", modId);
095        tag.setString("ItemType", itemType);
096        tag.setInteger("ItemId", itemId);
097        tag.setInteger("ordinal", ordinal);
098        if (forcedModId != null)
099        {
100            tag.setString("ForcedModId", forcedModId);
101        }
102        if (forcedName != null)
103        {
104            tag.setString("ForcedName", forcedName);
105        }
106        return tag;
107    }
108
109    @Override
110    public int hashCode()
111    {
112        return Objects.hashCode(itemId, ordinal);
113    }
114
115    @Override
116    public boolean equals(Object obj)
117    {
118        try
119        {
120            ItemData other = (ItemData) obj;
121            return Objects.equal(getModId(), other.getModId()) && Objects.equal(getItemType(), other.getItemType()) && Objects.equal(itemId, other.itemId) && ( isOveridden() || Objects.equal(ordinal, other.ordinal));
122        }
123        catch (ClassCastException cce)
124        {
125            return false;
126        }
127    }
128
129    @Override
130    public String toString()
131    {
132        return String.format("Item %d, Type %s, owned by %s, ordinal %d, name %s, claimedModId %s", itemId, itemType, modId, ordinal, forcedName, forcedModId);
133    }
134
135    public boolean mayDifferByOrdinal(ItemData rightValue)
136    {
137        return Objects.equal(getItemType(), rightValue.getItemType()) && Objects.equal(getModId(), rightValue.getModId());
138    }
139
140    public boolean isOveridden()
141    {
142        return forcedName != null;
143    }
144
145    public void setName(String name, String modId)
146    {
147        if (name == null)
148        {
149            this.forcedName = null;
150            this.forcedModId = null;
151            return;
152        }
153        String localModId = modId;
154        if (modId == null)
155        {
156            localModId = Loader.instance().activeModContainer().getModId();
157        }
158        if (modOrdinals.get(localModId).count(name)>0)
159        {
160            FMLLog.severe("The mod %s is attempting to redefine the item at id %d with a non-unique name (%s.%s)", Loader.instance().activeModContainer(), itemId, localModId, name);
161            throw new LoaderException();
162        }
163        modOrdinals.get(localModId).add(name);
164        this.forcedModId = modId;
165        this.forcedName = name;
166    }
167}