package com.pointcliki.dizgruntled.map;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.HashMap;
import java.util.TreeSet;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import com.pointcliki.dizgruntled.GruntzGame;
import com.pointcliki.dizgruntled.rez.MonolithPID;
public class TileSet {
private String fName;
private boolean fInternal;
private String fArea;
private int[] fMapping;
private JSONObject fDuplicates;
private String[] fTypes;
private SpriteSheet fSheet;
private int fCount = 0;
private int fDefault = 1;
private HashMap<String, Integer> fTypeCache;
public TileSet(String file) {
// Load json content
try {
JSONObject obj = new JSONObject(new JSONTokener(new FileReader("tilesets/" + file)));
fName = obj.getString("name");
fTypeCache = new HashMap<String, Integer>();
if (obj.has("rez")) {
JSONArray arr = obj.getJSONArray("rez");
fMapping = new int[arr.length()];
for (int i = 0; i < fMapping.length; i++) fMapping[i] = arr.getInt(i);
}
if (obj.has("default")) fDefault = obj.getInt("default");
fInternal = obj.getString("source").equals("internal");
if (fInternal) {
fArea = obj.getString("area");
loadInternalImages();
} else {
loadExternalImages(obj.getString("source"), obj.getInt("width"), obj.getInt("height"));
}
if (obj.has("rezMapping")) fDuplicates = obj.getJSONObject("rezMapping");
JSONArray arr = obj.getJSONArray("types");
fTypes = new String[arr.length()];
for (int i = 0; i < fTypes.length; i++) {
fTypes[i] = arr.getString(i);
if (!fTypeCache.containsKey(arr.getString(i))) fTypeCache.put(arr.getString(i), i + 1);
}
} catch (JSONException e) {
System.err.println("Failed to read tileset " + file);
System.err.println(e.getMessage());
} catch (FileNotFoundException e) {
System.err.println("Failed to find tileset " + file);
System.err.println(e.getMessage());
}
}
private void loadExternalImages(String src, int w, int h) {
try {
fSheet = new SpriteSheet("tilesets/" + src, 32, 32);
fCount = fSheet.getHeight() / 2;
} catch (SlickException e) {
System.err.println("Failed to load source " + src);
}
}
private void loadInternalImages() {
try {
Image image = new Image(512, 512);
int n = 0;
for (int i: fMapping) {
String j = i + "";
while (j.length() < 3) j = "0" + j;
MonolithPID pid = GruntzGame.resourceManager().pid(fArea + "/TILEZ/ACTION/" + j);
if (pid != null) {
image.getGraphics().drawImage(pid.image(), n % 16 * 32, n / 16 * 32);
}
n++;
}
image.getGraphics().flush();
fCount = n;
fSheet = new SpriteSheet(image, 32, 32);
} catch (SlickException e) {
e.printStackTrace();
}
}
public TreeSet<String> traits(int id) {
if (id == -1) {
TreeSet<String> set = new TreeSet<String>();
set.add("nogo");
return set;
}
return GruntzGame.resourceManager().traits(type(id));
}
public String area() {
return fArea;
}
public int count() {
return fCount;
}
public Image tile(int id) {
if (id < 0)
try {
return new Image(0, 0);
} catch (SlickException e) {
return null;
}
return fSheet.getSubImage(id % 16, (int) Math.floor(id / 16));
}
public byte wapValue(int i) {
if (i == -1) return 0;
try {
if (fDuplicates.has(i + "")) i = fDuplicates.getInt(i + "");
} catch (Exception e) {
// Do nothing
}
if (fMapping == null) return (byte) fDefault;
for (int x = 0; x < fMapping.length; x++) if (i == fMapping[x]) return (byte) (x + 1);
return (byte) fDefault;
}
public String type(int id) {
if (id == 0) return "EMPTY";
if (fTypes.length <= id - 1) return null;
return fTypes[id - 1];
}
public String name() {
return fName;
}
public void render(Map map, int tileset, int sx, int sy, int w, int h) {
fSheet.startUse();
for (int y = sy; y < h; y++) {
for (int x = sx; x < w; x++) {
int tile = map.tile(tileset, x, y) - 1;
if (tile >= 0) fSheet.renderInUse(x * 32, y * 32, tile % 16, tile / 16);
}
}
fSheet.endUse();
}
/**
* Return the tile for the supplied type
* @param The type of tile to find in the tileset
*/
public int tile(String type) {
if (fTypeCache.containsKey(type)) return fTypeCache.get(type);
return -1;
}
}