/*
 * Copyright 2014 Matthew Collins
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package uk.co.thinkofdeath.mapviewer.shared.support;

import com.google.gwt.core.client.JavaScriptObject;
import uk.co.thinkofdeath.mapviewer.shared.world.Chunk;

import java.util.List;

public class ChunkMap<T extends Chunk> extends JavaScriptObject {
    protected ChunkMap() {
    }

    public static native <T extends Chunk> ChunkMap<T> create()/*-{
        return {
            map: [],
            values: @java.util.ArrayList::new()()
        };
    }-*/;

    public final native int size()/*-{
        return this.values.@java.util.ArrayList::size()();
    }-*/;

    public final native boolean contains(int x, int z)/*-{
        var cx = this.map[x];
        if (cx == null) {
            return false;
        }
        return cx[z] != null;
    }-*/;

    public final native void put(int x, int z, T chunk)/*-{
        var cx = this.map[x];
        if (cx == null) {
            this.map[x] = cx = [];
        }
        cx[z] = chunk;
        this.values.@java.util.ArrayList::add(Ljava/lang/Object;)(chunk);
    }-*/;

    public final native T get(int x, int z)/*-{
        var cx = this.map[x];
        if (cx == null) {
            return null;
        }
        return cx[z];
    }-*/;

    public final native T remove(int x, int z)/*-{
        var cx = this.map[x];
        if (cx == null) {
            return null;
        }
        var val = cx[z];
        delete cx[z];
        this.values.@java.util.ArrayList::remove(Ljava/lang/Object;)(val);
        return val;
    }-*/;

    public final native List<Chunk> values()/*-{
        return this.values;
    }-*/;
}

@@ -756,16 +756,44 @@
 Chunk;%0A%0A
+import java.util.ArrayList;%0A
 import j
@@ -1010,18 +1010,18 @@
    map: 
-%5B%5D
+%7B%7D
 ,%0A      
@@ -1039,57 +1039,180 @@
 s: @
-java.util.ArrayList::new()()%0A        %7D;%0A    %7D-*/;
+uk.co.thinkofdeath.mapviewer.shared.support.ChunkMap::createList()()%0A        %7D;%0A    %7D-*/;%0A%0A    private static ArrayList createList() %7B%0A        return new ArrayList();%0A    %7D
 %0A%0A  
@@ -1381,32 +1381,30 @@
 *-%7B%0A        
-var cx =
+return
  this.map%5Bx%5D
@@ -1406,91 +1406,17 @@
 ap%5Bx
-%5D;%0A        if (cx == null) %7B%0A            return false;%0A        %7D%0A        return cx%5B
+ + %22:%22 + 
 z%5D !
@@ -1506,112 +1506,27 @@
     
-var cx = this.map%5Bx%5D;%0A        if (cx == null) %7B%0A            this.map%5Bx%5D = cx = %5B%5D;%0A        %7D%0A        cx%5B
+this.map%5Bx + %22:%22 + 
 z%5D =
@@ -1670,32 +1670,30 @@
 *-%7B%0A        
-var cx =
+return
  this.map%5Bx%5D
@@ -1695,246 +1695,112 @@
 ap%5Bx
-%5D;%0A        if (cx == null) %7B%0A            return null;%0A        %7D%0A        return cx%5Bz%5D;%0A    %7D-*/;%0A%0A    public final native T remove(int x, int z)/*-%7B%0A        var cx = this.map%5Bx%5D;%0A        if (cx == null) %7B%0A            return null;%0A        %7D
+ + %22:%22 + z%5D;%0A    %7D-*/;%0A%0A    public final native T remove(int x, int z)/*-%7B%0A        var key = x + %22:%22 + z
 %0A   
@@ -1814,20 +1814,28 @@
 r val = 
-cx%5Bz
+this.map%5Bkey
 %5D;%0A     
@@ -1848,12 +1848,20 @@
 ete 
-cx%5Bz
+this.map%5Bkey
 %5D;%0A 

Make ChunkMap less leaky