001package net.minecraft.client.renderer.texture;
002
003import cpw.mods.fml.relauncher.Side;
004import cpw.mods.fml.relauncher.SideOnly;
005import java.awt.image.BufferedImage;
006import java.io.BufferedReader;
007import java.io.IOException;
008import java.io.InputStream;
009import java.io.InputStreamReader;
010import java.util.ArrayList;
011import java.util.Arrays;
012import java.util.HashMap;
013import java.util.Iterator;
014import java.util.List;
015import java.util.Map;
016import net.minecraft.block.Block;
017import net.minecraft.client.Minecraft;
018import net.minecraft.client.renderer.StitcherException;
019import net.minecraft.client.renderer.entity.RenderManager;
020import net.minecraft.client.texturepacks.ITexturePack;
021import net.minecraft.item.Item;
022import net.minecraft.util.Icon;
023import net.minecraftforge.client.ForgeHooksClient;
024import net.minecraftforge.common.ForgeDummyContainer;
025
026@SideOnly(Side.CLIENT)
027public class TextureMap implements IconRegister
028{
029    /** 0 = terrain.png, 1 = items.png */
030    public final int textureType;
031    public final String textureName;
032    public final String basePath;
033    public final String textureExt;
034    private final HashMap mapTexturesStiched = new HashMap();
035    private BufferedImage missingImage = new BufferedImage(64, 64, 2);
036    private TextureStitched missingTextureStiched;
037    private Texture atlasTexture;
038    private final List listTextureStiched = new ArrayList();
039    private final Map textureStichedMap = new HashMap();
040
041    public TextureMap(int par1, String par2, String par3Str, BufferedImage par4BufferedImage)
042    {
043        this.textureType = par1;
044        this.textureName = par2;
045        this.basePath = par3Str;
046        this.textureExt = ".png";
047        this.missingImage = par4BufferedImage;
048    }
049
050    public void refreshTextures()
051    {
052        this.textureStichedMap.clear();
053        ForgeHooksClient.onTextureStitchedPre(this);
054        int i;
055        int j;
056
057        if (this.textureType == 0)
058        {
059            Block[] ablock = Block.blocksList;
060            i = ablock.length;
061
062            for (j = 0; j < i; ++j)
063            {
064                Block block = ablock[j];
065
066                if (block != null)
067                {
068                    block.registerIcons(this);
069                }
070            }
071
072            Minecraft.getMinecraft().renderGlobal.registerDestroyBlockIcons(this);
073            RenderManager.instance.updateIcons(this);
074        }
075
076        Item[] aitem = Item.itemsList;
077        i = aitem.length;
078
079        for (j = 0; j < i; ++j)
080        {
081            Item item = aitem[j];
082
083            if (item != null && item.getSpriteNumber() == this.textureType)
084            {
085                item.updateIcons(this);
086            }
087        }
088
089        HashMap hashmap = new HashMap();
090        Stitcher stitcher = TextureManager.instance().createStitcher(this.textureName);
091        this.mapTexturesStiched.clear();
092        this.listTextureStiched.clear();
093        Texture texture = TextureManager.instance().makeTexture("missingno", 2, this.missingImage.getWidth(), this.missingImage.getHeight(), 10496, 6408, 9728, 9728, false, this.missingImage);
094        StitchHolder stitchholder = new StitchHolder(texture);
095        stitcher.addStitchHolder(stitchholder);
096        hashmap.put(stitchholder, Arrays.asList(new Texture[] {texture}));
097
098        for (Map.Entry<String, TextureStitched> entry : ((Map<String, TextureStitched>)textureStichedMap).entrySet())
099        {
100            String name = entry.getKey();
101            String path;
102            if (name.indexOf(':') == -1)
103            {
104                path = this.basePath + name + this.textureExt;
105            }
106            else
107            {
108                String domain = name.substring(0, name.indexOf(':'));
109                String file = name.substring(name.indexOf(':') + 1);
110                path = "mods/" + domain +"/" + basePath + file + textureExt;
111            }
112            List list = TextureManager.instance().createNewTexture(name, path, entry.getValue());
113            if (!list.isEmpty())
114            {
115                StitchHolder stitchholder1 = new StitchHolder((Texture)list.get(0));
116                stitcher.addStitchHolder(stitchholder1);
117                hashmap.put(stitchholder1, list);
118            }
119        }
120
121        try
122        {
123            stitcher.doStitch();
124        }
125        catch (StitcherException stitcherexception)
126        {
127            throw stitcherexception;
128        }
129
130        this.atlasTexture = stitcher.getTexture();
131        Iterator iterator = stitcher.getStichSlots().iterator();
132
133        while (iterator.hasNext())
134        {
135            StitchSlot stitchslot = (StitchSlot)iterator.next();
136            StitchHolder stitchholder2 = stitchslot.getStitchHolder();
137            Texture texture1 = stitchholder2.func_98150_a();
138            String s2 = texture1.getTextureName();
139            List list1 = (List)hashmap.get(stitchholder2);
140            TextureStitched texturestitched = (TextureStitched)this.textureStichedMap.get(s2);
141            boolean flag = false;
142
143            if (texturestitched == null)
144            {
145                flag = true;
146                texturestitched = TextureStitched.makeTextureStitched(s2);
147
148                if (!s2.equals("missingno"))
149                {
150                    Minecraft.getMinecraft().getLogAgent().logWarning("Couldn\'t find premade icon for " + s2 + " doing " + this.textureName);
151                }
152            }
153
154            texturestitched.init(this.atlasTexture, list1, stitchslot.getOriginX(), stitchslot.getOriginY(), stitchholder2.func_98150_a().getWidth(), stitchholder2.func_98150_a().getHeight(), stitchholder2.isRotated());
155            this.mapTexturesStiched.put(s2, texturestitched);
156
157            if (!flag)
158            {
159                this.textureStichedMap.remove(s2);
160            }
161
162            if (list1.size() > 1)
163            {
164                this.listTextureStiched.add(texturestitched);
165                String s3;
166                if (s2.indexOf(':') == -1)
167                {
168                    s3 = basePath + s2 + ".txt";
169                }
170                else
171                {
172                    String domain = s2.substring(0, s2.indexOf(':'));
173                    String file = s2.substring(s2.indexOf(':') + 1);
174                    s3 = "mods/" + domain + "/" + basePath + file + ".txt";
175                }
176                ITexturePack itexturepack = Minecraft.getMinecraft().texturePackList.getSelectedTexturePack();
177                boolean flag1 = !itexturepack.func_98138_b("/" + this.basePath + s2 + ".png", false);
178
179                try
180                {
181                    InputStream inputstream = itexturepack.func_98137_a("/" + s3, flag1);
182                    Minecraft.getMinecraft().getLogAgent().logInfo("Found animation info for: " + s3);
183                    texturestitched.readAnimationInfo(new BufferedReader(new InputStreamReader(inputstream)));
184                }
185                catch (IOException ioexception)
186                {
187                    ;
188                }
189            }
190        }
191
192        this.missingTextureStiched = (TextureStitched)this.mapTexturesStiched.get("missingno");
193        iterator = this.textureStichedMap.values().iterator();
194
195        while (iterator.hasNext())
196        {
197            TextureStitched texturestitched1 = (TextureStitched)iterator.next();
198            texturestitched1.copyFrom(this.missingTextureStiched);
199        }
200
201        if (!ForgeDummyContainer.disableStitchedFileSaving)
202        {
203            this.atlasTexture.writeImage("debug.stitched_" + this.textureName + ".png");
204        }
205        ForgeHooksClient.onTextureStitchedPost(this);
206        this.atlasTexture.createTexture();
207    }
208
209    public void updateAnimations()
210    {
211        Iterator iterator = this.listTextureStiched.iterator();
212
213        while (iterator.hasNext())
214        {
215            TextureStitched texturestitched = (TextureStitched)iterator.next();
216            texturestitched.updateAnimation();
217        }
218    }
219
220    public Texture getTexture()
221    {
222        return this.atlasTexture;
223    }
224
225    public Icon registerIcon(String par1Str)
226    {
227        if (par1Str == null)
228        {
229            (new RuntimeException("Don\'t register null!")).printStackTrace();
230            par1Str = "null"; //Don't allow things to actually register null.. 
231        }
232
233        TextureStitched texturestitched = (TextureStitched)this.textureStichedMap.get(par1Str);
234
235        if (texturestitched == null)
236        {
237            texturestitched = TextureStitched.makeTextureStitched(par1Str);
238            this.textureStichedMap.put(par1Str, texturestitched);
239        }
240
241        return texturestitched;
242    }
243
244    public Icon getMissingIcon()
245    {
246        return this.missingTextureStiched;
247    }
248
249    //===================================================================================================
250    //                                           Forge Start
251    //===================================================================================================
252    /**
253     * Grabs the registered entry for the specified name, returning null if there was not a entry. 
254     * Opposed to func_94245_a, this will not instantiate the entry, useful to test if a maping exists.
255     * 
256     * @param name The name of the entry to find
257     * @return The registered entry, null if nothing was registered.
258     */
259    public TextureStitched getTextureExtry(String name)
260    {
261        return (TextureStitched)textureStichedMap.get(name);
262    }
263
264    /**
265     * Adds a texture registry entry to this map for the specified name if one does not already exist.
266     * Returns false if the map already contains a entry for the specified name. 
267     * 
268     * @param name Entry name
269     * @param entry Entry instance
270     * @return True if the entry was added to the map, false otherwise.
271     */
272    public boolean setTextureEntry(String name, TextureStitched entry)
273    {
274        if (!textureStichedMap.containsKey(name))
275        {
276            textureStichedMap.put(name, entry);
277            return true;
278        }
279        return false;
280    }
281}