package com.vaadin.components.grid.data;

import static com.google.gwt.query.client.GQuery.$$;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayMixed;
import com.google.gwt.query.client.js.JsUtils;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.vaadin.components.grid.GridComponent;

/**
 * Datasource where requestRows() is delegated to a js native function
 *
 * @author manolo
 */
public class GridJsFuncDataSource extends GridDataSource {
    private JavaScriptObject f;

    public GridJsFuncDataSource(JavaScriptObject jso, int rows, GridComponent grid) {
        super(grid);
        assert JsUtils.isFunction(jso);
        f = jso;
        size = rows;
    }

    @Override
    protected void requestRows(
            final int firstRowIndex,
            final int numberOfRows,
            final com.vaadin.client.data.AbstractRemoteDataSource.RequestRowsCallback<JsArrayMixed> callback) {
        JsArrayMixed o = exec(f, firstRowIndex, numberOfRows,
                new AsyncCallback<JsArrayMixed>() {
                    public void onFailure(Throwable caught) {
                    }

                    public void onSuccess(JsArrayMixed result) {
                        setRowData(firstRowIndex, result);
                    }
                });
        if (o != null) {
            setRowData(firstRowIndex, o);
        }
    }

    @Override
    public Object getRowKey(JsArrayMixed row) {
        return JsUtils.JSON2String(row);
    }

    private native JsArrayMixed exec(JavaScriptObject f, int idx,
            int count, AsyncCallback<JsArrayMixed> cb)
   /*-{
       return f(idx, count, function(r) {
           cb.@com.google.gwt.user.client.rpc.AsyncCallback::onSuccess(*)(r);
       });
   }-*/;
}

@@ -85,17 +85,131 @@
 GQuery.$
-$
+;%0Aimport static com.google.gwt.query.client.GQuery.console;%0Aimport static com.google.gwt.query.client.GQuery.window
 ;%0A%0Aimpor
@@ -303,16 +303,61 @@
 yMixed;%0A
+import com.google.gwt.query.client.Function;%0A
 import c
@@ -399,61 +399,8 @@
 ls;%0A
-import com.google.gwt.user.client.rpc.AsyncCallback;%0A
 impo
@@ -524,29 +524,8 @@
 ion%0A
- *%0A * @author manolo%0A
  */%0A
@@ -583,16 +583,17 @@
 ource %7B%0A
+%0A
     priv
@@ -613,17 +613,26 @@
 tObject 
-f
+jsFunction
 ;%0A%0A    p
@@ -781,17 +781,26 @@
         
-f
+jsFunction
  = jso;%0A
@@ -1054,24 +1054,25 @@
 callback) %7B%0A
+%0A
         JsAr
@@ -1072,108 +1072,70 @@
    J
-sArrayMixed o = exec(f, firstRowIndex, numberOfRows,%0A                new AsyncCallback%3CJsArrayMixed%3E
+avaScriptObject jsCallback = JsUtils.wrapFunction(new Function
 () %7B
@@ -1143,32 +1143,24 @@
             
-        
 public void 
@@ -1163,103 +1163,30 @@
 oid 
-onFailure(Throwable caught) %7B%0A                    %7D%0A%0A                    public void onSuccess(
+f() %7B%0A                
 JsAr
@@ -1200,28 +1200,33 @@
 d result
-) %7B%0A        
+ = arguments(0);%0A
         
@@ -1272,32 +1272,34 @@
 t);%0A            
+%7D%0A
         %7D%0A      
@@ -1283,32 +1283,35 @@
      %7D%0A        %7D
+);%0A
 %0A               
@@ -1303,25 +1303,260 @@
         
-        %7D
+// When we call the native function, it could return the array of rows directly%0A        // or via the provided callback function.%0A        JsArrayMixed result = JsUtils.jsni(jsFunction, %22call%22, jsFunction, firstRowIndex, numberOfRows, jsCallback
 );%0A     
@@ -1562,17 +1562,22 @@
     if (
-o
+result
  != null
@@ -1618,17 +1618,22 @@
 wIndex, 
-o
+result
 );%0A     
@@ -1756,277 +1756,7 @@
    %7D
-%0A%0A    private native JsArrayMixed exec(JavaScriptObject f, int idx,%0A            int count, AsyncCallback%3CJsArrayMixed%3E cb)%0A   /*-%7B%0A       return f(idx, count, function(r) %7B%0A           cb.@com.google.gwt.user.client.rpc.AsyncCallback::onSuccess(*)(r);%0A       %7D);%0A   %7D-*/;
 %0A%7D%0A

Refactor execution of js datasource functions