package com.mycompany.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.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridRecord;

/**
 * Credit to @original_author Aleksandras Novikovas
 */
public class ServiceNodeDataSource
    extends GwtRpcDataSource {

    public ServiceNodeDataSource () {
        DataSourceField field;
        
        field = new DataSourceIntegerField ("nodeId", "ID");
        field.setPrimaryKey (true);  // assigned as nodeId.        
        field.setRequired (false);
        addField (field);

        // TODO set requireds to true
        field = new DataSourceTextField ("institutionCode", "Code");
        field.setRequired (true);
        addField (field);
        
        field = new DataSourceTextField ("serviceName", "Service");
        field.setRequired (true);
        addField (field);
        
        field = new DataSourceTextField ("shortAddress", "Address");
        field.setRequired (true);
        addField (field);
        
        field = new DataSourceTextField ("nodeType", "Type");
        field.setRequired (true);
        addField (field);

        field = new DataSourceTextField ("info", "Info");
        field.setRequired (true);
        addField (field);

        field = new DataSourceTextField ("address", "Address");
        field.setRequired (true);
        addField (field);

        field = new DataSourceTextField ("port", "Port");
        field.setRequired (true);
        addField (field);
        
        field = new DataSourceTextField ("status", "Status");
        field.setRequired (true);
        addField (field);

        field = new DataSourceTextField ("color", "Color");
        field.setRequired (true);
        addField (field);

        field = new DataSourceTextField ("created", "Created");
        field.setRequired (true);
        addField (field);

        field = new DataSourceTextField ("setInactive", "*Inactive");
        field.setRequired (true);
        addField (field);

        field = new DataSourceTextField ("xpos", "xpos");
        field.setRequired (true);
        addField (field);

        field = new DataSourceTextField ("ypos", "ypos");
        field.setRequired (true);
        addField (field);

        field = new DataSourceTextField ("xlen", "xlen");
        field.setRequired (true);
        addField (field);

        field = new DataSourceTextField ("ylen", "ylen");
        field.setRequired (true);
        addField (field);
    }

    @Override
    protected void executeFetch (final String requestId, final DSRequest request, final DSResponse response) {
        // These can be used as parameters to create paging.
//        request.getStartRow ();
//        request.getEndRow ();
//        request.getSortBy ();
        ServiceNodesServiceAsync service = GWT.create (ServiceNodesService.class);
        service.fetch (new AsyncCallback<List<ServiceNodeRecord>> () {
            public void onFailure (Throwable caught) {
                response.setStatus (RPCResponse.STATUS_FAILURE);
                processResponse (requestId, response);
            }
            public void onSuccess (List<ServiceNodeRecord> result) {
                ListGridRecord[] list = new ListGridRecord[result.size ()];
                for (int i = 0; i < list.length; i++) {
                    ListGridRecord record = new ListGridRecord ();
                    copyValues (result.get (i), record);
                    list[i] = record;
                }
                response.setData (list);
                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);
        ServiceNodeRecord testRec = new ServiceNodeRecord ();
        copyValues (rec, testRec);
        ServiceNodesServiceAsync service = GWT.create (ServiceNodesService.class);
        service.add (testRec, new AsyncCallback<ServiceNodeRecord> () {
            public void onFailure (Throwable caught) {
                response.setStatus (RPCResponse.STATUS_FAILURE);
                processResponse (requestId, response);
            }
            public void onSuccess (ServiceNodeRecord 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) {
        // Retrieve record which should be updated.
        JavaScriptObject data = request.getData ();
        ListGridRecord rec = new ListGridRecord (data);
        // Find grid
        ListGrid grid = (ListGrid) Canvas.getById (request.getComponentId ());
        // Get record with old and new values combined
        int index = grid.getRecordIndex (rec);
        rec = (ListGridRecord) grid.getEditedRecord (index);
        ServiceNodeRecord testRec = new ServiceNodeRecord ();
        copyValues (rec, testRec);
        ServiceNodesServiceAsync service = GWT.create (ServiceNodesService.class);
        service.update (testRec, new AsyncCallback<ServiceNodeRecord> () {
            public void onFailure (Throwable caught) {
                response.setStatus (RPCResponse.STATUS_FAILURE);
                processResponse (requestId, response);
            }
            public void onSuccess (ServiceNodeRecord result) {
                ListGridRecord[] list = new ListGridRecord[1];
                ListGridRecord updRec = new ListGridRecord ();
                copyValues (result, updRec);
                list[0] = updRec;
                response.setData (list);
                processResponse (requestId, response);
            }
        });
    }

    @Override
    protected void executeRemove (final String requestId, final DSRequest request, final DSResponse response) {
        // Retrieve record which should be removed.
        JavaScriptObject data = request.getData ();
        final ListGridRecord rec = new ListGridRecord (data);
        ServiceNodeRecord testRec = new ServiceNodeRecord ();
        copyValues (rec, testRec);
        ServiceNodesServiceAsync service = GWT.create (ServiceNodesService.class);
        service.remove (testRec, new AsyncCallback () {
            public void onFailure (Throwable caught) {
                response.setStatus (RPCResponse.STATUS_FAILURE);
                processResponse (requestId, response);
            }
            public void onSuccess (Object result) {
                ListGridRecord[] list = new ListGridRecord[1];
                // We do not receive removed record from server.
                // Return record from request.
                list[0] = rec;
                response.setData (list);
                processResponse (requestId, response);
            }

        });
    }

    // fetch from, to
    private static void copyValues (ServiceNodeRecord from, ListGridRecord to) {
        to.setAttribute("id", from.getId ());
        to.setAttribute("serviceName", from.getServiceName ());
        to.setAttribute("institutionCode", from.getInstitutionCode ());
        to.setAttribute("shortAddress", from.getShortAddress());
        to.setAttribute("nodeType", from.getNodeType());
        to.setAttribute("info", from.getServiceInfo());
        to.setAttribute("address", from.getAddress());
        to.setAttribute("port", from.getPort());
        to.setAttribute("status", from.getStatus());
        to.setAttribute("created", from.getCreated());
        to.setAttribute("color", from.getColor());
        to.setAttribute("xpos", from.getXpos());
        to.setAttribute("ypos", from.getYpos());
        to.setAttribute("xlen", from.getXlen());
        to.setAttribute("ylen", from.getYlen());
    }
 
    // not fully implemented
    private static void copyValues (ListGridRecord from, ServiceNodeRecord to) {
        to.setId (from.getAttributeAsInt ("id"));
        to.setServiceName (from.getAttributeAsString ("serviceName"));
        to.setInstitutionCode (from.getAttributeAsString ("institutionCode"));
    }
   
}
