package my.client;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.fields.DataSourceDateField;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.grid.ListGridRecord;

/**
 * Example <code>GwtRpcDataSource</code> implementation.
 * 
 * @author Aleksandras Novikovas
 * @author System Tier
 * @version 1.0
 */
public class SimpleGwtRPCDS extends GwtRpcDataSource {
  public static final int LIST_SIZE = 1000;
  
  public SimpleGwtRPCDS() {
    DataSourceField field;
    field = new DataSourceIntegerField("id", "ID");
    field.setPrimaryKey(true);
    // AutoIncrement on server.
    field.setRequired(false);
    addField(field);
    field = new DataSourceTextField("name", "NAME");
    field.setRequired(true);
    addField(field);
    field = new DataSourceDateField("date", "DATE");
    field.setRequired(false);
    addField(field);
  }

  @Override
  protected void executeFetch(final String requestId, final DSRequest request,
      final DSResponse response) {
    // This can be used as parameter for server side sorting.
    // request.getSortBy ();

    // Finding which rows were requested
    // Normaly these two indexes should be passed to server
    // but for this example I will do "paging" on client side
    
    SC.logWarn ("Start row:" + Integer.toString (request.getStartRow ()));
    SC.logWarn ("End row:" + request.getEndRow ().toString ());
//    SC.logWarn ("Sort by:" + request.getSortBy ());
    
    final int startIndex = (request.getStartRow() < 0) ? 0 : request
        .getStartRow();
    final int endIndex = (request.getEndRow() == null) ? -1 : request
        .getEndRow();
    SimpleGwtRPCDSServiceAsync service = GWT
        .create(SimpleGwtRPCDSService.class);
    service.fetch(startIndex, endIndex, new AsyncCallback<List<SimpleGwtRPCDSRecord>>() {
      public void onFailure(Throwable caught) {
        response.setStatus(RPCResponse.STATUS_FAILURE);
        processResponse(requestId, response);
      }

      public void onSuccess(List<SimpleGwtRPCDSRecord> result) {
        // Calculating size of return list
        int size = result.size();
        if (endIndex >= 0) {
          if (endIndex < startIndex) {
            size = 0;
          } else {
            size = endIndex - startIndex + 1;
          }
        }
        // Create list for return - it is just requested records
        ListGridRecord[] list = new ListGridRecord[size];
        if (size > 0) {
          for (int i = 0; i < result.size(); i++) {
//            if (i >= startIndex && i <= endIndex) {
              ListGridRecord record = new ListGridRecord();
              copyValues(result.get(i), record);
              list[i] = record;
//              list[i - startIndex] = record;
//            }
          }
        }
        response.setData(list);
        // IMPORTANT: for paging to work we have to specify size of full result
        // set
        response.setTotalRows(LIST_SIZE);
        processResponse(requestId, response);
      }
    });
  }

  @Override
  protected void executeAdd(final String requestId, final DSRequest request,
      final DSResponse response) {
    // Retrieve record which should be added.
    JavaScriptObject data = request.getData();
    ListGridRecord rec = new ListGridRecord(data);
    SimpleGwtRPCDSRecord testRec = new SimpleGwtRPCDSRecord();
    copyValues(rec, testRec);
    SimpleGwtRPCDSServiceAsync service = GWT
        .create(SimpleGwtRPCDSService.class);
    service.add(testRec, new AsyncCallback<SimpleGwtRPCDSRecord>() {
      public void onFailure(Throwable caught) {
        response.setStatus(RPCResponse.STATUS_FAILURE);
        processResponse(requestId, response);
      }

      public void onSuccess(SimpleGwtRPCDSRecord result) {
        ListGridRecord[] list = new ListGridRecord[1];
        ListGridRecord newRec = new ListGridRecord();
        copyValues(result, newRec);
        list[0] = newRec;
        response.setData(list);
        processResponse(requestId, response);
      }
    });
  }

  @Override
  protected void executeUpdate(final String requestId, final DSRequest request,
      final DSResponse response) {
  }

  @Override
  protected void executeRemove(final String requestId, final DSRequest request,
      final DSResponse response) {
  }

  private static void copyValues(ListGridRecord from, SimpleGwtRPCDSRecord to) {
    to.setId(from.getAttributeAsInt("id"));
    to.setName(from.getAttributeAsString("name"));
    to.setDate(from.getAttributeAsDate("date"));
  }

  private static void copyValues(SimpleGwtRPCDSRecord from, ListGridRecord to) {
    to.setAttribute("id", from.getId());
    to.setAttribute("name", from.getName());
    to.setAttribute("date", from.getDate());
  }

}
