package net.rainbowcode.jpixelface.skin;
import net.rainbowcode.jpixelface.HttpUtil;
import net.rainbowcode.jpixelface.profile.Profile;
import net.rainbowcode.jpixelface.redis.RedisKey;
import net.rainbowcode.jpixelface.redis.RedisUtils;
import net.rainbowcode.jpixelface.skin.Mutate;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.imgscalr.Scalr;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class SkinManager
{
private final Logger logger = LogManager.getLogger();
private byte[] defaultSkin;
public SkinManager()
{
try
{
defaultSkin = IOUtils.toByteArray(getClass().getResourceAsStream("/char.png"));
}
catch (IOException e)
{
e.printStackTrace();
logger.fatal("Unable to load char.png! Shutting down!");
System.exit(1);
}
}
public byte[] getSkinFromProfile(Profile profile) throws IOException
{
byte[] skin;
if (profile.getSkinUrl() != null)
{
byte[] key = RedisKey.SKIN.buildByteKey(profile.getUuid().toString());
if (RedisUtils.exists(key))
{
skin = RedisUtils.getAsBytes(key);
}
else
{
skin = HttpUtil.getAsBytes(profile.getSkinUrl());
RedisUtils.setAndExpire(key, skin, 14400);
}
}
else
{
skin = defaultSkin;
}
return skin;
}
public byte[] getMutated(Profile profile, int size, Mutate mutate) throws IOException
{
byte[] newSkin = getSkinFromProfile(profile);
if (!mutate.equals(Mutate.NONE))
{
InputStream in = new ByteArrayInputStream(newSkin);
BufferedImage bImageFromConvert = ImageIO.read(in);
in.close();
bImageFromConvert = mutate.act(bImageFromConvert, size);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bImageFromConvert, "png", baos);
baos.flush();
newSkin = baos.toByteArray();
baos.close();
bImageFromConvert.flush();
}
return newSkin;
}
public BufferedImage getBufferedMutated(Profile profile, int size, Mutate mutate)
{
try
{
byte[] newSkin = getSkinFromProfile(profile);
InputStream in = new ByteArrayInputStream(newSkin);
BufferedImage bImageFromConvert = ImageIO.read(in);
in.close();
if (!mutate.equals(Mutate.NONE))
{
bImageFromConvert = mutate.act(bImageFromConvert, size);
}
return bImageFromConvert;
}
catch (IOException e)
{
e.printStackTrace();
return null;
}
}
public static BufferedImage getHelm(BufferedImage bufferedImage)
{
BufferedImage combined = new BufferedImage(8, 8, BufferedImage.TYPE_INT_ARGB);
BufferedImage head = Scalr.crop(bufferedImage, 8, 8, 8, 8);
BufferedImage overlay = Scalr.crop(bufferedImage, 40, 8, 8, 8);
//Iterate over pixels to see if overlay is all black.
// This is only to support dumb users using MS paint.
boolean allBlack = true;
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
int rgb = overlay.getRGB(x, y);
if (rgb != -16777216)
{
allBlack = false;
}
}
}
if (allBlack)
{
return head;
}
Graphics graphics = combined.getGraphics();
graphics.drawImage(head, 0, 0, null);
graphics.drawImage(overlay, 0, 0, null);
graphics.dispose();
return combined;
}
public static BufferedImage getBody(BufferedImage bufferedImage, boolean naked)
{
BufferedImage combined = new BufferedImage(18, 32, BufferedImage.TYPE_INT_ARGB);
BufferedImage head = getHelm(bufferedImage);
BufferedImage rightArm = Scalr.crop(bufferedImage, 44, 20, 4, 12);
BufferedImage leftArm;
BufferedImage chest = Scalr.crop(bufferedImage, 20, 20, 8, 12);
BufferedImage rightLeg = Scalr.crop(bufferedImage, 4, 20, 4, 12);
BufferedImage leftLeg;
Graphics graphics = combined.getGraphics();
graphics.drawImage(head, 5, 0, null);
graphics.drawImage(rightArm, 13, 8, null);
graphics.drawImage(chest, 5, 8, null);
graphics.drawImage(rightLeg, 5, 20, null);
if (bufferedImage.getHeight() == 64 && bufferedImage.getWidth() == 64)
{
BufferedImage rightArm2 = Scalr.crop(bufferedImage, 44, 36, 4, 12);
BufferedImage leftArm2 = Scalr.crop(bufferedImage, 52, 52, 4, 12);
BufferedImage chest2 = Scalr.crop(bufferedImage, 20, 36, 8, 12);
BufferedImage rightLeg2 = Scalr.crop(bufferedImage, 4, 36, 4, 12);
BufferedImage leftLeg2 = Scalr.crop(bufferedImage, 4, 52, 4, 12);
leftArm = Scalr.crop(bufferedImage, 36, 52, 4, 12);
leftLeg = Scalr.crop(bufferedImage, 20, 52, 4, 12);
graphics.drawImage(leftArm, 1, 8, null);
graphics.drawImage(leftLeg, 9, 20, null);
if (!naked)
{
graphics.drawImage(rightArm2, 13, 8, null);
graphics.drawImage(leftArm2, 1, 8, null);
graphics.drawImage(chest2, 5, 8, null);
graphics.drawImage(rightLeg2, 5, 20, null);
graphics.drawImage(leftLeg2, 9, 20, null);
}
}
else
{
leftArm = Scalr.rotate(rightArm, Scalr.Rotation.FLIP_HORZ);
leftLeg = Scalr.rotate(rightLeg, Scalr.Rotation.FLIP_HORZ);
graphics.drawImage(leftArm, 1, 8, null);
graphics.drawImage(leftLeg, 9, 20, null);
}
graphics.dispose();
return combined;
}
}