package com.graphicsengine.io;

import java.util.Arrays;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.graphicsengine.component.SpriteAttributeComponent;
import com.graphicsengine.component.SpriteComponent;
import com.graphicsengine.exporter.GraphicsEngineNodeExporter;
import com.graphicsengine.geometry.GraphicsEngineMeshFactory;
import com.graphicsengine.io.gson.ComponentDeserializer;
import com.graphicsengine.io.gson.NodeDeserializer;
import com.graphicsengine.scene.GraphicsEngineNodeFactory;
import com.graphicsengine.scene.GraphicsEngineNodeType;
import com.nucleus.common.Type;
import com.nucleus.common.TypeResolver;
import com.nucleus.component.Component;
import com.nucleus.exporter.NucleusNodeExporter;
import com.nucleus.geometry.MeshFactory;
import com.nucleus.io.GSONSceneFactory;
import com.nucleus.renderer.NucleusRenderer;
import com.nucleus.scene.Node;
import com.nucleus.scene.NodeFactory;

/**
 * Implementation of the scenefactory for the graphics engine, this shall take care of all nodes/datatypes that
 * are specific for the graphics engine.
 * 
 * @author Richard Sahlin
 *
 */
public class GSONGraphicsEngineFactory extends GSONSceneFactory {

    /**
     * The types that can be used to represent classes when importing/exporting
     * This is used as a means to decouple serialized name from implementing class.
     * 
     */
    public enum GraphicsEngineClasses implements Type<Object> {

        spriteattributecomponent(SpriteAttributeComponent.class),
        spritecomponent(SpriteComponent.class);

        private final Class<?> theClass;

        private GraphicsEngineClasses(Class<?> theClass) {
            this.theClass = theClass;
        }

        @Override
        public Class<Object> getTypeClass() {
            return (Class<Object>) theClass;
        }

        @Override
        public String getName() {
            return name();
        }
    }

    private ComponentDeserializer componentDeserializer = new ComponentDeserializer();

    /**
     * Creates a default scenefactory with {@link NucleusNodeExporter}.
     * Calls {@link #createNodeExporter()} and {@link #registerNodeExporters()}
     * This constructor will call {@link #init(NucleusRenderer, NodeFactory, MeshFactory)}
     * 
     * @param renderer
     * @param nodeFactory
     * @param meshFactory
     * @param types Implementation specific types that shall be registered to the {@linkplain TypeResolver}, may be null
     */
    public GSONGraphicsEngineFactory(NucleusRenderer renderer, NodeFactory nodeFactory, MeshFactory meshFactory,
            List<Type<?>> types) {
        super(renderer, nodeFactory, meshFactory, Arrays.asList((Type<?>[]) GraphicsEngineClasses.values()));
        if (types != null) {
            TypeResolver.getInstance().registerTypes(types);
        }
    }

    @Override
    protected void createNodeDeserializer() {
        nodeDeserializer = new NodeDeserializer();
    }

    @Override
    protected void createNodeExporter() {
        nodeExporter = new GraphicsEngineNodeExporter();
    }

    @Override
    protected void registerNodeExporters() {
        super.registerNodeExporters();
        nodeExporter.registerNodeExporter(GraphicsEngineNodeType.values(), new GraphicsEngineNodeExporter());
    }

    /**
     * Utility method to get the default nodefactory
     * 
     * @return
     */
    public static NodeFactory getNodeFactory() {
        return new GraphicsEngineNodeFactory();
    }

    /**
     * Utility method to get the default mesh factory
     * 
     * @return
     */
    public static MeshFactory getMeshFactory(NucleusRenderer renderer) {
        return new GraphicsEngineMeshFactory(renderer);
    }

    @Override
    protected void registerTypeAdapter(GsonBuilder builder) {
        super.registerTypeAdapter(builder);
        builder.registerTypeAdapter(Node.class, nodeDeserializer);
        builder.registerTypeAdapter(Component.class, componentDeserializer);
    }

    @Override
    protected void setGson(Gson gson) {
        super.setGson(gson);
        nodeDeserializer.setGson(gson);
        componentDeserializer.setGson(gson);
    }

}

@@ -29,57 +29,8 @@
 o;%0A%0A
-import java.util.Arrays;%0Aimport java.util.List;%0A%0A
 impo
@@ -54,16 +54,16 @@
 n.Gson;%0A
+
 import c
@@ -670,57 +670,8 @@
 nt;%0A
-import com.nucleus.exporter.NucleusNodeExporter;%0A
 impo
@@ -739,32 +739,71 @@
 ONSceneFactory;%0A
+import com.nucleus.io.SceneSerializer;%0A
 import com.nucle
@@ -1058,16 +1058,96 @@
 engine.%0A
+ * Uses %7B@link NodeDeserializer%7D and %7B@link TypeResolver%7D to lookup classnames.%0A
  * %0A * @
@@ -2072,311 +2072,214 @@
     
-/**%0A     * Creates a default scenef
+protected GSONGraphicsEngineF
 actory
- with %7B@link NucleusNodeExporter%7D.%0A     * Calls %7B@link #createNodeExporter()%7D and %7B@link #registerNodeExporters()%7D%0A     * This constructor will call %7B@link #init(NucleusRenderer, NodeFactory, MeshFactory)%7D%0A 
+() %7B%0A        super();%0A    %7D%0A%0A    public static SceneSerializer getInstance() %7B%0A        if (sceneFactory == null) %7B%0A
     
-* %0A
+ 
      
-* @param renderer%0A     * @param nod
+  sceneFactory = new GSONGraphicsEngin
 eFactory
 %0A   
@@ -2278,200 +2278,92 @@
 tory
+();
 %0A     
-* @param meshFactory%0A     * @param types Implementation specific types that shall be registered to the %7B@linkplain TypeResolver%7D, may be null%0A     */%0A    public GSONGraphicsEngineFactory
+   %7D%0A        return sceneFactory;%0A    %7D%0A%0A    @Override%0A    public void init
 (Nuc
@@ -2438,34 +2438,18 @@
 ory,
-%0A            List%3C
+ 
 Type%3C?%3E
-%3E
+%5B%5D
  typ
@@ -2467,16 +2467,21 @@
    super
+.init
 (rendere
@@ -2513,34 +2513,38 @@
 ry, 
-Arrays.asList((
+types);%0A        register
 Type
-%3C?%3E%5B%5D) 
+s(
 Grap
@@ -2574,110 +2574,9 @@
 s())
-);%0A        if (types != null) %7B%0A            TypeResolver.getInstance().registerTypes(types);%0A        %7D
+;
 %0A   

Change scenefactory to singleton