package advancedsystemsmanager.registry;
import advancedsystemsmanager.AdvancedSystemsManager;
import advancedsystemsmanager.api.network.IPacketReader;
import advancedsystemsmanager.api.network.IPacketWriter;
import advancedsystemsmanager.nei.NEIConfig;
import advancedsystemsmanager.network.ASMPacket;
import advancedsystemsmanager.reference.Files;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
public class FactoryMappingRegistry implements IPacketReader, IPacketWriter
{
public static FactoryMappingRegistry INSTANCE = new FactoryMappingRegistry();
public static final TypeAdapter<FactoryMappingRegistry> TYPE_ADAPTER = new TypeAdapter<FactoryMappingRegistry>()
{
@Override
public void write(JsonWriter out, FactoryMappingRegistry value) throws IOException
{
out.beginObject();
TreeSet<Integer> values = new TreeSet<Integer>(value.factoryMapping.values());
for (Integer v : values)
{
out.name(value.factoryMapping.inverse().get(v)).value(v);
}
out.endObject();
}
@Override
public FactoryMappingRegistry read(JsonReader in) throws IOException
{
FactoryMappingRegistry result = new FactoryMappingRegistry();
in.beginObject();
while (in.peek() != JsonToken.END_OBJECT)
{
result.register(in.nextName(), in.nextInt());
}
in.endObject();
return result;
}
};
private static Gson GSON = new GsonBuilder().registerTypeAdapter(FactoryMappingRegistry.class, TYPE_ADAPTER).setPrettyPrinting()
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES).create();
private BiMap<String, Integer> factoryMapping = HashBiMap.create();
private List<String> toBeAssigned = new ArrayList<String>();
private int maxID;
public FactoryMappingRegistry()
{
maxID = BlockRegistry.BLOCKS_TO_REGISTER * 16 - 1;
toBeAssigned.addAll(ClusterRegistry.getKeys());
register(ClusterRegistry.CABLE.getKey(), 0);
register(ClusterRegistry.MANAGER.getKey(), 1);
}
private void register(String name, int val)
{
if (val < 0)
{
val += maxID;
}
if (!factoryMapping.containsKey(name) && !factoryMapping.containsValue(val) && (val < 2 || AdvancedSystemsManager.configHandler.shouldRegister(name, true)))
{
toBeAssigned.remove(name);
factoryMapping.put(name, val);
}
}
public static void load()
{
try
{
File file = new File(Files.WORLD_SAVE_DIR, "block_mapping.json");
if (!file.exists()) file.createNewFile();
JsonReader reader = new JsonReader(new FileReader(file));
INSTANCE = GSON.fromJson(reader, FactoryMappingRegistry.class);
reader.close();
if (INSTANCE == null)
{
INSTANCE = new FactoryMappingRegistry();
}
} catch (IOException ignored)
{
}
if (!INSTANCE.toBeAssigned.isEmpty())
{
INSTANCE.assignNewEntries();
if (!INSTANCE.toBeAssigned.isEmpty())
{
throw new IndexOutOfBoundsException("Too many tiles registered for the number of assigned blocks, increase registered_blocks in the config or disable some tiles");
}
save();
}
BlockRegistry.registerTiles();
}
private void assignNewEntries()
{
List<String> assign = new ArrayList<String>(toBeAssigned);
for (String key : assign)
{
Set<Integer> values = factoryMapping.values();
int i = 0;
while (values.contains(i)) i++;
register(key, i);
}
}
private static void save()
{
File file = new File(Files.WORLD_SAVE_DIR, "block_mapping.json");
try
{
if (!file.exists())
file.createNewFile();
FileWriter fileWriter = new FileWriter(file);
GSON.toJson(FactoryMappingRegistry.INSTANCE, FactoryMappingRegistry.class, fileWriter);
fileWriter.close();
} catch (IOException ignored)
{
}
}
public int getId(String key)
{
return factoryMapping.get(key);
}
@Override
public boolean readData(ASMPacket packet)
{
factoryMapping.clear();
int length = packet.readUnsignedByte();
for (int i = 0; i < length; i++)
{
register(packet.readStringFromBuffer(), packet.readUnsignedByte());
}
BlockRegistry.registerTiles();
NEIConfig.hideBlocks();
return false;
}
@Override
public boolean writeData(ASMPacket packet)
{
packet.writeByte(factoryMapping.size());
for (Map.Entry<String, Integer> entry : factoryMapping.entrySet())
{
packet.writeStringToBuffer(entry.getKey());
packet.writeByte(entry.getValue());
}
return false;
}
}