001package squidpony.squidgrid.gui.gdx;
002
003import com.badlogic.gdx.Gdx;
004import com.badlogic.gdx.LifecycleListener;
005import com.badlogic.gdx.Application;
006import com.badlogic.gdx.graphics.Texture;
007import com.badlogic.gdx.graphics.g2d.BitmapFont;
008import com.badlogic.gdx.graphics.g2d.TextureRegion;
009import squidpony.squidmath.StatefulRNG;
010
011/**
012 * Default BitmapFonts, a sample image, and a central RNG for use with LibGDX.
013 * The fonts provided are all monospaced, with most looking rather similar (straight orthogonal lines and elbow curves),
014 * but the one that looks... better than the rest (Inconsolata-LGC, accessible by getLargeSmoothFont()) also supports
015 * Greek and Cyrillic, and is the only one to do so. The most Latin script support is in the font Mandrill, accessible
016 * by getDefaultUnicodeFont() and getLargeUnicodeFont() in two different sizes, and the latter should be suitable for
017 * everything from Polish to Vietnamese.
018 * <br>
019 * The sample image is a tentacle taken from a public domain icon collection graciously released by Henrique Lazarini;
020 * it's fitting for SquidLib to have a tentacle as a logo or something, I guess?
021 * <br>
022 * You can get a default RNG with getGuiRandom(); this should probably not be reused for non-GUI-related randomness,
023 * but is meant instead to be used wherever randomized purely-aesthetic effects are needed, such as a jiggling effect.
024 * Created by Tommy Ettinger on 7/11/2015.
025 */
026public class DefaultResources implements LifecycleListener {
027    private BitmapFont narrow1 = null, narrow2 = null, narrow3 = null,
028            smooth2 = null,
029            square1 = null, square2 = null,
030            unicode1 = null, unicode2 = null;
031    public final static String squareName = "Zodiac-Square-12x12.fnt",
032            narrowName = "Rogue-Zodiac-6x12.fnt",
033            unicodeName = "Mandrill-6x16.fnt",
034            squareNameLarge = "Zodiac-Square-24x24.fnt",
035            narrowNameLarge = "Rogue-Zodiac-12x24.fnt",
036            unicodeNameLarge = "Mandrill-12x32.fnt",
037            narrowNameExtraLarge = "Rogue-Zodiac-18x36.fnt",
038            smoothNameLarge = "Inconsolata-LGC-12x24.fnt";
039    private Texture tentacle = null;
040    private TextureRegion tentacleRegion = null;
041    private StatefulRNG guiRandom;
042
043    private static DefaultResources instance = null;
044
045    private DefaultResources()
046    {
047        Gdx.app.addLifecycleListener(this);
048    }
049
050    private static void initialize()
051    {
052        if(instance == null)
053            instance = new DefaultResources();
054    }
055
056    /**
057     * Returns a 12x12px, stretched but curvaceous font as an embedded resource. Caches it for later calls.
058     * @return the BitmapFont object representing Zodiac-Square.ttf at size 16 pt.
059     */
060    public static BitmapFont getDefaultFont()
061    {
062        initialize();
063        if(instance.square1 == null)
064        {
065            try {
066                instance.square1 = new BitmapFont(Gdx.files.classpath("Zodiac-Square-12x12.fnt"), Gdx.files.classpath("Zodiac-Square-12x12.png"), false);
067            } catch (Exception e) {
068            }
069        }
070        return instance.square1;
071    }
072    /**
073     * Returns a 24x24px, stretched but curvaceous font as an embedded resource. Caches it for later calls.
074     * @return the BitmapFont object representing Zodiac-Square.ttf at size 32 pt.
075     */
076    public static BitmapFont getLargeFont()
077    {
078        initialize();
079        if(instance.square2 == null)
080        {
081            try {
082                instance.square2 = new BitmapFont(Gdx.files.classpath("Zodiac-Square-24x24.fnt"), Gdx.files.classpath("Zodiac-Square-24x24.png"), false);
083            } catch (Exception e) {
084            }
085        }
086        return instance.square2;
087    }
088    /**
089     * Returns a 6x12px, narrow and curving font as an embedded resource. Caches it for later calls.
090     * @return the BitmapFont object representing Rogue-Zodiac.ttf at size 16 pt.
091     */
092    public static BitmapFont getDefaultNarrowFont()
093    {
094        initialize();
095        if(instance.narrow1 == null)
096        {
097            try {
098                instance.narrow1 = new BitmapFont(Gdx.files.classpath("Rogue-Zodiac-6x12.fnt"), Gdx.files.classpath("Rogue-Zodiac-6x12.png"), false);
099            } catch (Exception e) {
100            }
101        }
102        return instance.narrow1;
103    }
104
105    /**
106     * Returns a 12x24px, narrow and curving font as an embedded resource. Caches it for later calls.
107     * @return the BitmapFont object representing Rogue-Zodiac.ttf at size 32 pt.
108     */
109    public static BitmapFont getLargeNarrowFont()
110    {
111        initialize();
112        if(instance.narrow2 == null)
113        {
114            try {
115                instance.narrow2 = new BitmapFont(Gdx.files.classpath("Rogue-Zodiac-12x24.fnt"), Gdx.files.classpath("Rogue-Zodiac-12x24.png"), false);
116            } catch (Exception e) {
117            }
118        }
119        return instance.narrow2;
120    }
121    /**
122     * Returns a 12x24px, narrow and curving font as an embedded resource. Caches it for later calls.
123     * @return the BitmapFont object representing Rogue-Zodiac.ttf at size 32 pt.
124     */
125    public static BitmapFont getExtraLargeNarrowFont()
126    {
127        initialize();
128        if(instance.narrow3 == null)
129        {
130            try {
131                instance.narrow3 = new BitmapFont(Gdx.files.classpath("Rogue-Zodiac-18x36.fnt"), Gdx.files.classpath("Rogue-Zodiac-18x36.png"), false);
132            } catch (Exception e) {
133            }
134        }
135        return instance.narrow3;
136    }
137
138    /**
139     * Returns a 12x24px, very smooth and generally good-looking font (based on Inconsolata) as an embedded resource.
140     * This font fully supports Latin, Greek, Cyrillic, and of particular interest to SquidLib, Box Drawing characters.
141     * Caches the font for later calls.
142     * @return the BitmapFont object representing Inconsolata-LGC.ttf at size 32 pt.
143     */
144    public static BitmapFont getLargeSmoothFont()
145    {
146        initialize();
147        if(instance.smooth2 == null)
148        {
149            try {
150                instance.smooth2 = new BitmapFont(Gdx.files.classpath("Inconsolata-LGC-12x24.fnt"), Gdx.files.classpath("Inconsolata-LGC_0.png"), false);
151            } catch (Exception e) {
152            }
153        }
154        return instance.smooth2;
155    }
156    /**
157     * Returns a 6x16px, narrow and curving font with a lot of unicode chars as an embedded resource. Caches it for later calls.
158     * @return the BitmapFont object representing Mandrill.ttf at size 16 pt.
159     */
160    public static BitmapFont getDefaultUnicodeFont()
161    {
162        initialize();
163        if(instance.unicode1 == null)
164        {
165            try {
166                instance.unicode1 = new BitmapFont(Gdx.files.classpath("Mandrill-6x16.fnt"), Gdx.files.classpath("Mandrill-6x16.png"), false);
167            } catch (Exception e) {
168            }
169        }
170        return instance.unicode1;
171    }
172
173    /**
174     * Returns a 12x32px, narrow and curving font with a lot of unicode chars as an embedded resource. Caches it for later calls.
175     * @return the BitmapFont object representing Mandrill.ttf at size 32 pt.
176     */
177    public static BitmapFont getLargeUnicodeFont()
178    {
179        initialize();
180        if(instance.unicode2 == null)
181        {
182            try {
183                instance.unicode2 = new BitmapFont(Gdx.files.classpath("Mandrill-12x32.fnt"), Gdx.files.classpath("Mandrill-12x32.png"), false);
184            } catch (Exception e) {
185            }
186        }
187        return instance.unicode2;
188    }
189
190    /**
191     * Gets an image of a (squid-like, for SquidLib) tentacle, 32x32px.
192     * Source is public domain: http://opengameart.org/content/496-pixel-art-icons-for-medievalfantasy-rpg
193     * Created by Henrique Lazarini (7Soul1, http://7soul1.deviantart.com/ )
194     * @return a TextureRegion containing an image of a tentacle.
195     */
196    public static TextureRegion getTentacle()
197    {
198        initialize();
199        if(instance.tentacle == null || instance.tentacleRegion == null)
200        {
201            try {
202                instance.tentacle = new Texture(Gdx.files.classpath("Tentacle.png"));
203                instance.tentacleRegion = new TextureRegion(instance.tentacle);
204            } catch (Exception ignored) {
205            }
206        }
207        return instance.tentacleRegion;
208    }
209
210    /**
211     * This is a static global LightRNG that's meant for usage in cases where the seed does not matter and any changes
212     * to this LightRNG's state will not change behavior elsewhere in the program; this means the GUI mainly.
213     */
214    public static StatefulRNG getGuiRandom()
215    {
216        initialize();
217        if(instance.guiRandom == null)
218        {
219            instance.guiRandom =  new StatefulRNG();
220        }
221        return instance.guiRandom;
222    }
223
224    /**
225     * Special symbols that can be used as icons if you use the narrow default font.
226     */
227    public static final String narrowFontSymbols = "ሀሁሂሃሄህሆሇለሉሊላሌልሎሏሐሑሒሓሔሕሖሗመሙሚማሜ",
228                                  narrowFontAll = " !\"#$%&'()*+,-./0123\n" +
229                                          "456789:;<=>?@ABCDEFG\n" +
230                                          "HIJKLMNOPQRSTUVWXYZ[\n" +
231                                          "\\]^_`abcdefghijklmno\n" +
232                                          "pqrstuvwxyz{|}~¡¢£¤¥\n" +
233                                          "¦§¨©ª«¬\u00AD®¯°±²³´µ¶·¸¹\n" +
234                                          "º»¼½¾¿×ß÷øɍɎሀሁሂሃሄህሆሇ\n" +
235                                          "ለሉሊላሌልሎሏሐሑሒሓሔሕሖሗመሙሚማ\n" +
236                                          "ሜẞ‐‒–—―‖‗‘’‚‛“”„‟†‡•\n" +
237                                          "…‧‹›€™"+
238                                          "←↑→↓↷↺↻"+ // left, up, right, down, "tap", "counterclockwise", "clockwise"
239                                          "∀∁∂∃∄∅∆\n" +
240                                          "∇∈∉∋∌∎∏∐∑−∓∔∕∖∘∙√∛∜∝\n" +
241                                          "∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∮∯∱∲∳\n" +
242                                          "∴∵∶∷≈≋≠≡≢≣≤≥≦≧≨≩≪≫─━\n" +
243                                          "│┃┄┅┆┇┈┉┊┋┌┍┎┏┐┑┒┓└┕\n" +
244                                          "┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩\n" +
245                                          "┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽\n" +
246                                          "┾┿╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏═║\n" +
247                                          "╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥\n" +
248                                          "╦╧╨╩╪╫╬╭╮╯╰╱╲╳╴╵╶╷╸╹\n" +
249                                          "╺╻╼╽╾╿▁▄▅▆▇█▌▐░▒▓▔▖▗\n" +
250                                          "▘▙▚▛▜▝▞▟";
251
252    /**
253     * Called when the {@link Application} is about to pause
254     */
255    @Override
256    public void pause() {
257        if(narrow1 != null) {
258            narrow1.dispose();
259            narrow1 = null;
260        }
261        if(narrow2 != null) {
262            narrow2.dispose();
263            narrow2 = null;
264        }
265        if(narrow3 != null) {
266            narrow3.dispose();
267            narrow3 = null;
268        }
269        if(square1 != null) {
270            square1.dispose();
271            square1 = null;
272        }
273        if(square2 != null) {
274            square2.dispose();
275            square1 = null;
276        }
277        if (unicode1 != null) {
278            unicode1.dispose();
279            unicode1 = null;
280        }
281        if (unicode2 != null) {
282            unicode2.dispose();
283            unicode2 = null;
284        }
285        if(tentacle != null) {
286            tentacle.dispose();
287            tentacle = null;
288        }
289    }
290
291    /**
292     * Called when the Application is about to be resumed
293     */
294    @Override
295    public void resume() {
296        initialize();
297    }
298
299    /**
300     * Called when the {@link Application} is about to be disposed
301     */
302    @Override
303    public void dispose() {
304        pause();
305        Gdx.app.removeLifecycleListener(this);
306        instance = null;
307    }
308}