package ttftcuts.physis.client.texture;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import ttftcuts.physis.Physis;
import ttftcuts.physis.common.block.BlockDigSite;
import ttftcuts.physis.common.helper.TextureHelper;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.data.AnimationMetadataSection;
import net.minecraft.util.ResourceLocation;
@SideOnly(Side.CLIENT)
public class DigSiteAtlasSprite extends TextureAtlasSprite {
public String derivedname;
public String name;
public String base;
public String[] layers;
public ResourceLocation[] resources;
public DigSiteAtlasSprite(String name, String base, String[] names, ResourceLocation[] resources) {
super(getDerivedName(name, base, names));
this.derivedname = getDerivedName(name, base, names);
this.name = name;
this.base = base;
this.layers = names;
this.resources = resources;
}
public static String getDerivedName(String name, String base, String[] names) {
StringBuilder b = new StringBuilder(Physis.MOD_ID);
b.append(":").append(name).append("|").append(base != null ? base : "none").append("|");
for(int i=0; i<names.length; i++) {
if (i!=0) {
b.append("_");
}
b.append(names[i].toLowerCase());
}
return b.toString();
}
@Override
public boolean hasCustomLoader(IResourceManager manager, ResourceLocation location) {
return true;
}
@SuppressWarnings("rawtypes")
@Override
public boolean load(IResourceManager manager, ResourceLocation location) {
int mip = Minecraft.getMinecraft().gameSettings.mipmapLevels;
BufferedImage[] outputtextures = new BufferedImage[1 + mip];
BufferedImage basetexture;
BufferedImage[] layertextures = new BufferedImage[this.layers.length];
AnimationMetadataSection animation;
int w = 0;
try {
ResourceLocation baseresource = base != null ? getBlockResource(base) : BlockDigSite.blankTexture;
IResource baseiresource = manager.getResource(baseresource);
basetexture = ImageIO.read(baseiresource.getInputStream());
animation = (AnimationMetadataSection) baseiresource.getMetadata("animation");
for (int i=0; i<this.layers.length; i++) {
layertextures[i] = TextureHelper.getImageForResource(resources[i]);
}
w = layertextures[0].getWidth();
if (basetexture.getWidth() != width) {
List resourcePacks = manager.getAllResources(baseresource);
for (int i= resourcePacks.size() - 1; i >= 0; --i) {
IResource resource = (IResource) resourcePacks.get(i);
basetexture = ImageIO.read(resource.getInputStream());
if (basetexture.getWidth() == width) {
break;
}
}
}
} catch(IOException e) {
e.printStackTrace();
return true;
}
if (basetexture.getWidth() != w) {
Physis.logger.error("Failed to load base image of the right size for texture: "+name);
return true;
}
int h = basetexture.getHeight();
BufferedImage output = new BufferedImage(w, h, 2);
int[] basedata = new int[w*w];
int[][] layerdata = new int[layertextures.length][w*w];
for (int y=0; y<h; y+=w) {
basetexture.getRGB(0, y, w, w, basedata, 0, w);
for(int i=0; i<layertextures.length; i++) {
layertextures[i].getRGB(0, y, w, w, layerdata[i], 0, w);
}
int[] composited = buildTexture(w, basedata, layerdata);
output.setRGB(0, y, w, w, composited, 0, w);
}
outputtextures[0] = output;
this.loadSprite(outputtextures, animation, (float) Minecraft.getMinecraft().gameSettings.anisotropicFiltering > 1.0F);
//Physis.logger.info("Successfully built texture: "+this.derivedname);
return false;
}
private int[] buildTexture(int size, int[] data, int[][] layerdata) {
for (int i=0; i<data.length; i++) {
for (int n=0; n<layerdata.length; n++) {
int rd = red(data[i]);
int gd = green(data[i]);
int bd = blue(data[i]);
int ad = alpha(data[i]);
int rl = red(layerdata[n][i]);
int gl = green(layerdata[n][i]);
int bl = blue(layerdata[n][i]);
int al = alpha(layerdata[n][i]);
double alpha = al/255;
double oneminus = 1.0 - alpha;
int r = (int)(rd * oneminus + rl * alpha);
int g = (int)(gd * oneminus + gl * alpha);
int b = (int)(bd * oneminus + bl * alpha);
int a = (int)(255 * (alpha + (ad/255)*oneminus));
data[i] = compose(r,g,b,a);
}
}
return data;
}
public static ResourceLocation getBlockResource(String s2) {
String s1 = "minecraft";
int ind = s2.indexOf(58);
if (ind >= 0) {
if (ind > 1) {
s1 = s2.substring(0, ind);
}
s2 = s2.substring(ind + 1, s2.length());
}
s1 = s1.toLowerCase();
s2 = "textures/blocks/" + s2 + ".png";
return new ResourceLocation(s1, s2);
}
private int alpha(int c) {
return (c >> 24) & 0xFF;
}
private int red(int c) {
return (c >> 16) & 0xFF;
}
private int green(int c) {
return (c >> 8) & 0xFF;
}
private int blue(int c) {
return (c) & 0xFF;
}
private int compose(int r, int g, int b, int a) {
int rgb = a;
rgb = (rgb << 8) + r;
rgb = (rgb << 8) + g;
rgb = (rgb << 8) + b;
return rgb;
}
}