package com.artemis.managers;

import com.artemis.BaseSystem;
import com.artemis.World;
import com.artemis.io.InputStreamHelper;
import com.artemis.io.SaveFileFormat;
import com.artemis.utils.IntBag;

import java.io.*;

public class WorldSerializationManager extends BaseSystem {
	private static final String TAG = WorldSerializationManager.class.getSimpleName();
	private ArtemisSerializer<?> backend;
	public boolean alwaysLoadStreamMemory = true;


	@Override
	protected void processSystem() {
	}

	public void setSerializer(ArtemisSerializer<?> backend) {
		this.backend = backend;
	}

	public <T extends ArtemisSerializer> T getSerializer() {
		return (T) backend;
	}

	public <T extends SaveFileFormat> T load(InputStream is, Class<T> format) {
		if (alwaysLoadStreamMemory || !InputStreamHelper.isMarkSupported(is)) {
			try {
				byte[] buf = new byte[32768];
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				int read;
				while ((read = is.read(buf)) != -1) {
					baos.write(buf, 0, read);
				}
				is = new ByteArrayInputStream(baos.toByteArray());
				baos.close();
			} catch (IOException e) {
				throw new RuntimeException("Error copying inputstream", e);
			}
		}
		return backend.load(is, format);
	}

	public void save(Writer writer, SaveFileFormat format) {
		if (backend == null) {
			throw new RuntimeException("Missing ArtemisSerializer, see #setBackend.");
		}

		world.inject(format);
		backend.save(writer, format);
	}

	public static abstract class ArtemisSerializer<T> {
		protected World world;

		protected ArtemisSerializer(World world) {
			this.world = world;
		}

		protected final void save(Writer writer, IntBag entities) {
			save(writer, new SaveFileFormat(entities));
		}

		public abstract ArtemisSerializer register(Class<?> type, T serializer);
		protected abstract void save(Writer writer, SaveFileFormat format);
		protected abstract <T extends SaveFileFormat> T load(InputStream is, Class<T> format);
	}
}

@@ -490,24 +490,160 @@
 tem() %7B%0A%09%7D%0A%0A
+%09/**%0A%09 * Provide a serializer that can read or write data in your choice of format (likely%0A%09 * some form of data file, e.g. JSON).%0A%09 */%0A
 %09public void
@@ -795,32 +795,186 @@
 T) backend;%0A%09%7D%0A%0A
+%09/**%0A%09 * Loads data from an InputStream (usually a file) and provides a SaveFileFormat (or subclass)%0A%09 * object that contains the deserialized data.%0A%09 */%0A
 %09public %3CT exten
@@ -1751,272 +1751,904 @@
 %7D%0A%0A%09
-public static abstract class ArtemisSerializer%3CT%3E %7B%0A%09%09protected World world;%0A%0A%09%09protected ArtemisSerializer(World world) %7B%0A%09%09%09this.world = world;%0A%09%09%7D%0A%0A%09%09protected final void save(Writer writer, IntBag entities) %7B%0A%09%09%09save(writer, new SaveFileFormat(entities));%0A%09%09%7D%0A
+/**%0A%09 * Override this class to actually decide the format in which an object (not necessarily%0A%09 * of Artemis type) should be serialized.  A JSON serializer is provided, but by overriding%0A%09 * this class you may serialize to/from YAML, XML, UDP packets, or even your own JSON format!%0A%09 */%0A%09public static abstract class ArtemisSerializer%3CT%3E %7B%0A%09%09protected World world;%0A%0A%09%09protected ArtemisSerializer(World world) %7B%0A%09%09%09this.world = world;%0A%09%09%7D%0A%0A%09%09/**%0A%09%09 * Convenience method for immediately serializing a group of entities with the default%0A%09%09 * SaveFileFormat.  For finer control or SaveFileFormat subclasses, use #save.%0A%09%09 */%0A%09%09protected final void save(Writer writer, IntBag entities) %7B%0A%09%09%09save(writer, new SaveFileFormat(entities));%0A%09%09%7D%0A%0A%09%09/**%0A%09%09 * Register a custom serializer for some known class.  It is left to the implementation%0A%09%09 * to decide how this custom serializer is actually used.%0A%09%09 */
 %0A%09%09p
@@ -2719,16 +2719,19 @@
 lizer);%0A
+%09%09%0A
 %09%09protec
@@ -2792,16 +2792,109 @@
 ormat);%0A
+%09%09%0A%09%09/**%0A%09%09 * Deserializes data (usually a file) of a known class to a SaveFileFormat.%0A%09%09 */%0A
 %09%09protec

Add descriptions to ArtemisSerializer