package com.blarg.gdx.tilemap3d.serialization;

import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Base64Coder;
import com.badlogic.gdx.utils.Json;
import com.blarg.gdx.Strings;
import com.blarg.gdx.tilemap3d.ChunkVertexGenerator;
import com.blarg.gdx.tilemap3d.TileChunk;
import com.blarg.gdx.tilemap3d.TileMap;
import com.blarg.gdx.tilemap3d.lighting.TileMapLighter;
import com.blarg.gdx.tilemap3d.tilemesh.TileMeshCollection;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

import java.nio.ByteBuffer;

public class TileMapLoader {
	public static TileMap load(FileHandle mapFile, TileMeshCollection tileMeshes) {
		if (mapFile == null)
			throw new IllegalArgumentException();
		if (tileMeshes == null)
			throw new IllegalArgumentException();

		Json json = new Json();
		JsonTileMap jsonMap = json.fromJson(JsonTileMap.class, mapFile);

		if (jsonMap.chunks == null || jsonMap.chunks.size() == 0)
			throw new RuntimeException("Invalid map: no chunks.");
		int numChunks = (jsonMap.widthInChunks * jsonMap.heightInChunks * jsonMap.depthInChunks);
		if (jsonMap.chunks.size() != numChunks)
			throw new RuntimeException("Inconsistent map dimensions and number of chunks.");

		ChunkVertexGenerator chunkVertexGenerator = null;
		TileMapLighter lighter = null;

		if (Strings.isNullOrEmpty(jsonMap.lightingMode)) {
			chunkVertexGenerator = new ChunkVertexGenerator();
			lighter = null;
		} else if (jsonMap.lightingMode.equalsIgnoreCase("simple")) {
			throw new NotImplementedException();
		} else if (jsonMap.lightingMode.equalsIgnoreCase("skyAndSources")) {
			throw new NotImplementedException();
		} else
			throw new RuntimeException("Invalid lighting mode.");

		TileMap tileMap = new TileMap(
				jsonMap.chunkWidth, jsonMap.chunkHeight, jsonMap.chunkDepth,
				jsonMap.widthInChunks, jsonMap.heightInChunks, jsonMap.depthInChunks,
				tileMeshes,
				chunkVertexGenerator,
				lighter
		);

		for (int i = 0; i < jsonMap.chunks.size(); ++i) {
			String encodedChunk = jsonMap.chunks.get(i);
			TileChunk outputChunk = tileMap.getChunks()[i];

			byte[] chunkBytes = Base64Coder.decode(encodedChunk);
			ByteBuffer buffer = ByteBuffer.wrap(chunkBytes);

			TileChunkSerializer.deserialize(buffer, outputChunk);
		}

		return tileMap;
	}
}

@@ -37,24 +37,53 @@
 alization;%0A%0A
+import com.badlogic.gdx.Gdx;%0A
 import com.b
@@ -112,16 +112,16 @@
 Handle;%0A
-
 import c
@@ -571,16 +571,44 @@
 eBuffer;
+%0Aimport java.util.ArrayList;
 %0A%0Apublic
@@ -2324,16 +2324,16 @@
 );%0A%09%09%7D%0A%0A
-
 %09%09return
@@ -2344,11 +2344,1464 @@
 eMap;%0A%09%7D
+%0A%0A%09public static void save(TileMap tileMap, String outputFilename) %7B%0A%09%09if (tileMap == null)%0A%09%09%09throw new IllegalArgumentException();%0A%0A%09%09JsonTileMap jsonMap = new JsonTileMap();%0A%09%09jsonMap.chunkWidth = tileMap.getChunks()%5B0%5D.getWidth();%0A%09%09jsonMap.chunkHeight = tileMap.getChunks()%5B0%5D.getHeight();%0A%09%09jsonMap.chunkDepth = tileMap.getChunks()%5B0%5D.getDepth();%0A%09%09jsonMap.widthInChunks = tileMap.getWidth() / jsonMap.chunkWidth;%0A%09%09jsonMap.heightInChunks = tileMap.getWidth() / jsonMap.chunkHeight;%0A%09%09jsonMap.depthInChunks = tileMap.getWidth() / jsonMap.chunkDepth;%0A%0A%09%09// TODO: figure out real lighting mode from the types of vertex generator / lighter objects set%0A%09%09jsonMap.lightingMode = null;%0A%0A%09%09// each serialized chunk will be the same size in bytes (same number of tiles in each)%0A%09%09int chunkSizeInBytes = tileMap.getChunks()%5B0%5D.getData().length * TileChunkSerializer.TILE_SIZE_BYTES;%0A%0A%09%09jsonMap.chunks = new ArrayList%3CString%3E(tileMap.getChunks().length);%0A%09%09for (int i = 0; i %3C tileMap.getChunks().length; ++i) %7B%0A%09%09%09TileChunk chunk = tileMap.getChunks()%5Bi%5D;%0A%0A%09%09%09byte%5B%5D chunkBytes = new byte%5BchunkSizeInBytes%5D;%0A%09%09%09ByteBuffer buffer = ByteBuffer.wrap(chunkBytes);%0A%0A%09%09%09TileChunkSerializer.serialize(chunk, buffer);%0A%0A%09%09%09jsonMap.chunks.add(new String(Base64Coder.encode(chunkBytes)));%0A%09%09%7D%0A%0A%09%09Json json = new Json();%0A%09%09String output = json.prettyPrint(jsonMap);%0A%09%09FileHandle outputFile = Gdx.files.local(outputFilename);%0A%09%09outputFile.writeString(output, false);%0A%09%7D
 %0A%7D%0A

add TileMap saving