001    package com.google.gwt.maps.client.mvc;
002    
003    import com.google.gwt.ajaxloader.client.ArrayHelper;
004    import com.google.gwt.core.client.JavaScriptObject;
005    import com.google.gwt.core.client.JsArray;
006    import com.google.gwt.event.shared.HandlerRegistration;
007    import com.google.gwt.maps.client.events.MapEventType;
008    import com.google.gwt.maps.client.events.MapHandlerRegistration;
009    import com.google.gwt.maps.client.events.insertat.InsertAtEventFormatter;
010    import com.google.gwt.maps.client.events.insertat.InsertAtMapHandler;
011    import com.google.gwt.maps.client.events.removeat.RemoveAtEventFormatter;
012    import com.google.gwt.maps.client.events.removeat.RemoveAtMapHandler;
013    import com.google.gwt.maps.client.events.setat.SetAtEventFormatter;
014    import com.google.gwt.maps.client.events.setat.SetAtMapHandler;
015    
016    /**
017     * This class extends MVCObject.
018     * <br><br>
019     * See <a href="https://developers.google.com/maps/documentation/javascript/reference#MVCArray">MVCArray API Doc</a>
020     */
021    public class MVCArray<T extends JavaScriptObject> extends MVCObject<T> {
022      
023      /**
024       * This class extends MVCObject.
025       * use newInstance();
026       */
027      protected MVCArray() {}
028      
029      /**
030       * A mutable MVC Array.
031       */
032      public final static <T extends JavaScriptObject> MVCArray<T> newInstance() {
033        return createJso().cast();
034      }
035      
036      /**
037       * A mutable MVC Array.
038       * @param array
039       */
040      public final static <T extends JavaScriptObject> MVCArray<T> newInstance(JsArray<T> array) {
041        if (array == null) {
042          return null;
043        }
044        return createJso(array).cast();
045      }
046      
047      /**
048       * A mutable MVC Array.  
049       * @param array one ore more objects (like T[] or T)
050       */
051      public final static <T extends JavaScriptObject> MVCArray<T> newInstance(T... array) {
052        if (array == null) {
053          return null;
054        }
055        JsArray<T> a = ArrayHelper.toJsArray(array);
056        return createJso(a).cast();
057      }
058      
059      private final static native <T extends JavaScriptObject> JavaScriptObject createJso() /*-{
060        return new $wnd.google.maps.MVCArray();
061      }-*/;
062    
063      private final static native <T extends JavaScriptObject> JavaScriptObject createJso(JsArray<T> array) /*-{
064        return new $wnd.google.maps.MVCArray(array);
065      }-*/;
066    
067      /**
068       * Removes all elements from the array.
069       */
070      public final native void clear() /*-{
071        this.clear();
072      }-*/;
073      
074      /**
075       * Iterate over each element, calling the provided callback. The callback is called for each element like: callback(element, index).
076       * @param callback
077       */
078      public final void forEach(MVCArrayCallback<T> callback) {
079        onCallback(callback);
080      };
081        
082      /**
083       * used to process for each 
084       * @param callback
085       */
086      private final native void onCallback(MVCArrayCallback<T> callback) /*-{
087        var cb = function(element, index) {
088           @com.google.gwt.maps.client.mvc.MVCArray::forEachImplCallback(Lcom/google/gwt/core/client/JavaScriptObject;ILcom/google/gwt/maps/client/mvc/MVCArrayCallback;)(element, index, callback);
089        };
090        this.forEach(cb);
091      }-*/;
092      
093      /**
094       * send it to the callback interface
095       * @param element
096       * @param index
097       * @param callback
098       */
099      private static final <T extends JavaScriptObject> void forEachImplCallback(T element, int index, MVCArrayCallback<T> callback) {
100        callback.forEach(element, index);
101      }
102      
103      /**
104       * Returns a reference to the underlying Array. Warning: if the Array is mutated, no events will be fired by this object.
105       */
106      public final native JsArray<T> getArray() /*-{
107        return this.getArray();
108      }-*/;
109      
110      /**
111       * Get an element at the specified index.
112       * @param index
113       */
114      public final native T get(int index) /*-{
115        return this.getAt(index);
116      }-*/;
117      
118      /**
119       * Returns the number of elements in this array.
120       */
121      public final native int getLength() /*-{
122        return this.getLength();
123      }-*/;
124      
125      /**
126       * Inserts an element at the specified index.
127       * @param index
128       * @param element
129       */
130      public final native void insertAt(int index, T element) /*-{
131        this.insertAt(index, element);
132      }-*/;
133      
134      /**
135       * Removes the last element of the array and returns that element.
136       * @return the element that was popped
137       */
138      public final native T pop() /*-{
139        return this.pop();
140      }-*/;
141      
142      /**
143       * Adds one element to the end of the array and returns the new length of the array.
144       * @param element
145       * @return length of array
146       */
147      public final native int push(T element) /*-{
148        return this.push(element);
149      }-*/;
150      
151      /**
152       * Removes an element from the specified index.
153       * @param index
154       */
155      public final native T removeAt(int index) /*-{
156        return this.removeAt(index);
157      }-*/;
158      
159      /**
160       * Sets an element at the specified index.
161       * @param index
162       * @param element
163       */
164      public final native void setAt(int index, T element) /*-{
165        this.setAt(index, element);
166      }-*/;
167    
168      /**
169       * This event is fired when insertAt() is called. The event passes the index that was passed to insertAt().
170       * @param handler
171       */
172      public final HandlerRegistration addInsertAtHandler(InsertAtMapHandler handler) {
173        return MapHandlerRegistration.addHandlerMvc(this, MapEventType.INSERT_AT, handler, new InsertAtEventFormatter());
174      }
175      
176      /**
177       * This event is fired when removeAt() is called. The event passes the index that was passed to removeAt() and the element that was removed from the array.
178       * @param handler
179       */
180      public final HandlerRegistration addRemoveAtHandler(RemoveAtMapHandler handler) {
181        return MapHandlerRegistration.addHandlerMvc(this, MapEventType.REMOVE_AT, handler, new RemoveAtEventFormatter());
182      }
183      
184      /**
185       * This event is fired when setAt() is called. The event passes the index that was passed to setAt() and the element that was previously in the array at that index.
186       * @param handler
187       */
188      public final HandlerRegistration addSetAtHandler(SetAtMapHandler handler) {
189        return MapHandlerRegistration.addHandlerMvc(this, MapEventType.SET_AT, handler, new SetAtEventFormatter());
190      }
191      
192    }