001package net.minecraft.client.texturepacks;
002
003import cpw.mods.fml.relauncher.Side;
004import cpw.mods.fml.relauncher.SideOnly;
005import java.io.File;
006import java.util.ArrayList;
007import java.util.Arrays;
008import java.util.Collections;
009import java.util.HashMap;
010import java.util.Iterator;
011import java.util.List;
012import java.util.Map;
013import net.minecraft.client.Minecraft;
014import net.minecraft.client.gui.GuiProgress;
015import net.minecraft.client.multiplayer.ServerData;
016import net.minecraft.util.HttpUtil;
017
018@SideOnly(Side.CLIENT)
019public class TexturePackList
020{
021    /**
022     * An instance of TexturePackDefault for the always available builtin texture pack.
023     */
024    private static final ITexturePack defaultTexturePack = new TexturePackDefault();
025
026    /** The Minecraft instance. */
027    private final Minecraft mc;
028
029    /** The directory the texture packs will be loaded from. */
030    private final File texturePackDir;
031
032    /** Folder for the multi-player texturepacks. Returns File. */
033    private final File mpTexturePackFolder;
034
035    /** The list of the available texture packs. */
036    private List availableTexturePacks = new ArrayList();
037
038    /**
039     * A mapping of texture IDs to TexturePackBase objects used by updateAvaliableTexturePacks() to avoid reloading
040     * texture packs that haven't changed on disk.
041     */
042    private Map texturePackCache = new HashMap();
043
044    /** The TexturePack that will be used. */
045    private ITexturePack selectedTexturePack;
046
047    /** True if a texture pack is downloading in the background. */
048    private boolean isDownloading;
049
050    public TexturePackList(File par1File, Minecraft par2Minecraft)
051    {
052        this.mc = par2Minecraft;
053        this.texturePackDir = new File(par1File, "texturepacks");
054        this.mpTexturePackFolder = new File(par1File, "texturepacks-mp-cache");
055        this.createTexturePackDirs();
056        this.updateAvaliableTexturePacks();
057    }
058
059    /**
060     * Create the "texturepacks" and "texturepacks-mp-cache" directories if they don't already exist.
061     */
062    private void createTexturePackDirs()
063    {
064        if (!this.texturePackDir.isDirectory())
065        {
066            this.texturePackDir.delete();
067            this.texturePackDir.mkdirs();
068        }
069
070        if (!this.mpTexturePackFolder.isDirectory())
071        {
072            this.mpTexturePackFolder.delete();
073            this.mpTexturePackFolder.mkdirs();
074        }
075    }
076
077    /**
078     * Sets the new TexturePack to be used, returning true if it has actually changed, false if nothing changed.
079     */
080    public boolean setTexturePack(ITexturePack par1ITexturePack)
081    {
082        if (par1ITexturePack == this.selectedTexturePack)
083        {
084            return false;
085        }
086        else
087        {
088            this.isDownloading = false;
089            this.selectedTexturePack = par1ITexturePack;
090            this.mc.gameSettings.skin = par1ITexturePack.getTexturePackFileName();
091            this.mc.gameSettings.saveOptions();
092            return true;
093        }
094    }
095
096    /**
097     * filename must end in .zip
098     */
099    public void requestDownloadOfTexture(String par1Str)
100    {
101        String s1 = par1Str.substring(par1Str.lastIndexOf("/") + 1);
102
103        if (s1.contains("?"))
104        {
105            s1 = s1.substring(0, s1.indexOf("?"));
106        }
107
108        if (s1.endsWith(".zip"))
109        {
110            File file1 = new File(this.mpTexturePackFolder, s1);
111            this.downloadTexture(par1Str, file1);
112        }
113    }
114
115    private void downloadTexture(String par1Str, File par2File)
116    {
117        HashMap hashmap = new HashMap();
118        GuiProgress guiprogress = new GuiProgress();
119        hashmap.put("X-Minecraft-Username", this.mc.session.username);
120        hashmap.put("X-Minecraft-Version", "1.5");
121        hashmap.put("X-Minecraft-Supported-Resolutions", "16");
122        this.isDownloading = true;
123        this.mc.displayGuiScreen(guiprogress);
124        HttpUtil.downloadTexturePack(par2File, par1Str, new TexturePackDownloadSuccess(this), hashmap, 10000000, guiprogress);
125    }
126
127    /**
128     * Return true if a texture pack is downloading in the background.
129     */
130    public boolean getIsDownloading()
131    {
132        return this.isDownloading;
133    }
134
135    /**
136     * Called from Minecraft.loadWorld() if getIsDownloading() returned true to prepare the downloaded texture for
137     * usage.
138     */
139    public void onDownloadFinished()
140    {
141        this.isDownloading = false;
142        this.updateAvaliableTexturePacks();
143        this.mc.scheduleTexturePackRefresh();
144    }
145
146    /**
147     * check the texture packs the client has installed
148     */
149    public void updateAvaliableTexturePacks()
150    {
151        ArrayList arraylist = new ArrayList();
152        this.selectedTexturePack = defaultTexturePack;
153        arraylist.add(defaultTexturePack);
154        Iterator iterator = this.getTexturePackDirContents().iterator();
155
156        while (iterator.hasNext())
157        {
158            File file1 = (File)iterator.next();
159            String s = this.generateTexturePackID(file1);
160
161            if (s != null)
162            {
163                Object object = (ITexturePack)this.texturePackCache.get(s);
164
165                if (object == null)
166                {
167                    object = file1.isDirectory() ? new TexturePackFolder(s, file1, defaultTexturePack) : new TexturePackCustom(s, file1, defaultTexturePack);
168                    this.texturePackCache.put(s, object);
169                }
170
171                if (((ITexturePack)object).getTexturePackFileName().equals(this.mc.gameSettings.skin))
172                {
173                    this.selectedTexturePack = (ITexturePack)object;
174                }
175
176                arraylist.add(object);
177            }
178        }
179
180        this.availableTexturePacks.removeAll(arraylist);
181        iterator = this.availableTexturePacks.iterator();
182
183        while (iterator.hasNext())
184        {
185            ITexturePack itexturepack = (ITexturePack)iterator.next();
186            itexturepack.deleteTexturePack(this.mc.renderEngine);
187            this.texturePackCache.remove(itexturepack.getTexturePackID());
188        }
189
190        this.availableTexturePacks = arraylist;
191    }
192
193    /**
194     * Generate an internal texture pack ID from the file/directory name, last modification time, and file size. Returns
195     * null if the file/directory is not a texture pack.
196     */
197    private String generateTexturePackID(File par1File)
198    {
199        return par1File.isFile() && par1File.getName().toLowerCase().endsWith(".zip") ? par1File.getName() + ":" + par1File.length() + ":" + par1File.lastModified() : (par1File.isDirectory() && (new File(par1File, "pack.txt")).exists() ? par1File.getName() + ":folder:" + par1File.lastModified() : null);
200    }
201
202    /**
203     * Return a List<File> of file/directories in the texture pack directory.
204     */
205    private List getTexturePackDirContents()
206    {
207        return this.texturePackDir.exists() && this.texturePackDir.isDirectory() ? Arrays.asList(this.texturePackDir.listFiles()) : Collections.emptyList();
208    }
209
210    /**
211     * Returns a list of the available texture packs.
212     */
213    public List availableTexturePacks()
214    {
215        return Collections.unmodifiableList(this.availableTexturePacks);
216    }
217
218    public ITexturePack getSelectedTexturePack()
219    {
220        return this.selectedTexturePack;
221    }
222
223    public boolean func_77300_f()
224    {
225        if (!this.mc.gameSettings.serverTextures)
226        {
227            return false;
228        }
229        else
230        {
231            ServerData serverdata = this.mc.getServerData();
232            return serverdata == null ? true : serverdata.func_78840_c();
233        }
234    }
235
236    public boolean getAcceptsTextures()
237    {
238        if (!this.mc.gameSettings.serverTextures)
239        {
240            return false;
241        }
242        else
243        {
244            ServerData serverdata = this.mc.getServerData();
245            return serverdata == null ? false : serverdata.getAcceptsTextures();
246        }
247    }
248
249    static boolean func_77301_a(TexturePackList par0TexturePackList)
250    {
251        return par0TexturePackList.isDownloading;
252    }
253
254    /**
255     * Set the selectedTexturePack field (Inner class static accessor method).
256     */
257    static ITexturePack setSelectedTexturePack(TexturePackList par0TexturePackList, ITexturePack par1ITexturePack)
258    {
259        return par0TexturePackList.selectedTexturePack = par1ITexturePack;
260    }
261
262    /**
263     * Generate an internal texture pack ID from the file/directory name, last modification time, and file size. Returns
264     * null if the file/directory is not a texture pack. (Inner class static accessor method).
265     */
266    static String generateTexturePackID(TexturePackList par0TexturePackList, File par1File)
267    {
268        return par0TexturePackList.generateTexturePackID(par1File);
269    }
270
271    static ITexturePack func_98143_h()
272    {
273        return defaultTexturePack;
274    }
275
276    static Minecraft getMinecraft(TexturePackList par0TexturePackList)
277    {
278        return par0TexturePackList.mc;
279    }
280}