package openblocks.common.sync;
import com.google.common.collect.Lists;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.nbt.NBTTagCompound;
import openblocks.common.Stencil;
import openmods.sync.SyncableObjectBase;
public class SyncableBlockLayers extends SyncableObjectBase {
public static class Layer {
private int color;
private Stencil stencil;
private byte rotation;
private boolean hasStencilCover = false;
public Layer() {}
public Layer(int col) {
this.color = col;
}
public int getColor() {
return color;
}
/***
* If the layer has a cover on it, return white.
* Otherwise we render on the stored color
*/
public int getColorForRender() {
return hasStencilCover()? 0xFFFFFF : getColor();
}
public Stencil getStencil() {
return stencil;
}
public byte getRotation() {
return rotation;
}
public boolean hasStencilCover() {
return hasStencilCover;
}
public void setHasStencilCover(boolean cover) {
this.hasStencilCover = cover;
}
public void setRotation(byte rotation) {
this.rotation = rotation;
}
public void setStencil(Stencil st) {
this.stencil = st;
}
public boolean setColor(int color) {
if (this.color != color) {
this.color = color;
return true;
}
return false;
}
public static Layer createFromStream(DataInput stream) {
Layer layer = new Layer();
try {
layer.setColor(stream.readInt());
layer.setRotation(stream.readByte());
byte b = stream.readByte();
if (b > -1) {
layer.setStencil(Stencil.values()[b]);
}
layer.setHasStencilCover(stream.readBoolean());
} catch (Exception e) {
}
return layer;
}
public void rotate() {
rotation++;
if (rotation > 3) {
rotation = 0;
}
}
public NBTTagCompound getNBT() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setByte("rotation", rotation);
nbt.setString("stencil", stencil.name());
nbt.setBoolean("hasStencilCover", hasStencilCover);
nbt.setInteger("color", color);
return nbt;
}
public static Layer createFromNBT(NBTTagCompound compoundTag) {
Layer layer = new Layer();
layer.setColor(compoundTag.getInteger("color"));
layer.setHasStencilCover(compoundTag.getBoolean("hasStencilCover"));
layer.setRotation(compoundTag.getByte("rotation"));
layer.setStencil(Stencil.valueOf(compoundTag.getString("stencil")));
return layer;
}
}
public final LinkedList<Layer> layers = Lists.newLinkedList();
public SyncableBlockLayers() {}
@Override
public void readFromStream(DataInputStream stream) throws IOException {
int size = stream.readByte();
layers.clear();
for (byte i = 0; i < size; i++) {
layers.add(Layer.createFromStream(stream));
}
}
@Override
public void writeToStream(DataOutputStream stream)
throws IOException {
stream.writeByte(layers.size());
for (Layer layer : layers) {
stream.writeInt(layer.getColor());
stream.writeByte(layer.getRotation());
if (layer.getStencil() != null) {
stream.writeByte(layer.getStencil().ordinal());
} else {
stream.writeByte(-1);
}
stream.writeBoolean(layer.hasStencilCover());
}
}
@Override
public void writeToNBT(NBTTagCompound nbt, String name) {
NBTTagCompound subTag = new NBTTagCompound();
subTag.setInteger("size", layers.size());
int i = 0;
for (Layer layer : layers) {
subTag.setTag("layer_" + i, layer.getNBT());
i++;
}
nbt.setTag(name, subTag);
}
@Override
public void readFromNBT(NBTTagCompound nbt, String name) {
NBTTagCompound subTag = nbt.getCompoundTag(name);
int size = subTag.getInteger("size");
layers.clear();
for (int i = 0; i < size; i++) {
layers.add(Layer.createFromNBT(subTag.getCompoundTag("layer_" + i)));
}
}
public List<Layer> getAllLayers() {
return layers;
}
public boolean isLastLayerStencil() {
Layer last = layers.peekLast();
return last != null && last.hasStencilCover && last.stencil != null;
}
public void setLastLayerColor(int color) {
Layer last = getOrCreateLastLayer();
final boolean hasChanged = last.setColor(color);
if (hasChanged) markDirty();
}
public void setLastLayerStencil(Stencil stencil) {
Layer last = getOrCreateLastLayer();
last.hasStencilCover = true;
last.stencil = stencil;
markDirty();
}
private Layer getOrCreateLastLayer() {
Layer last = layers.peekLast();
if (last == null) {
last = new Layer();
layers.addLast(last);
}
return last;
}
public void moveStencilToNextLayer() {
Layer prevTop = layers.getLast();
prevTop.setHasStencilCover(false);
Layer newLayer = new Layer();
newLayer.setStencil(prevTop.getStencil());
newLayer.setHasStencilCover(true);
newLayer.setRotation(prevTop.getRotation());
layers.addLast(newLayer);
markDirty();
}
public void pushNewStencil(Stencil stencil) {
Layer newLayer = new Layer();
newLayer.setStencil(stencil);
newLayer.setHasStencilCover(true);
layers.addLast(newLayer);
markDirty();
}
public Layer getLayer(int i) {
if (i < layers.size()) { return layers.get(i); }
return null;
}
public void removeCover() {
Layer last = layers.peekLast();
if (last != null && last.hasStencilCover()) {
layers.removeLast();
markDirty();
}
}
public Stencil getTopStencil() {
Layer top = layers.peekLast();
return top != null? top.stencil : null;
}
public void rotateCover() {
Layer lastLayer = layers.peekLast();
if (lastLayer != null && lastLayer.hasStencilCover()) {
lastLayer.rotate();
markDirty();
}
}
public void clear() {
if (!layers.isEmpty()) {
layers.clear();
markDirty();
}
}
public boolean isEmpty() {
return layers.isEmpty();
}
}