package com.fit.klinika.client.radnik;

import java.util.List;

import com.fit.klinika.client.doVr.DoktorOblast;
import com.fit.klinika.client.doVr.VrstaRadnika;
import com.fit.klinika.client.odeljenje.Odeljenje;
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.rpc.RPCResponse;
import com.smartgwt.client.types.FieldType;
import com.smartgwt.client.util.JSOHelper;
import com.smartgwt.client.widgets.grid.ListGridRecord;

public class RadnikDS extends RadnikRPC{

	private RadnikServiceAsync radnikService = GWT.create(RadnikService.class);
	
	public RadnikDS(){
		DataSourceField idRadnikDS = new DataSourceField("id", FieldType.INTEGER,"ID");
		DataSourceField nazivDS = new DataSourceField("naziv", FieldType.TEXT,"Naziv");
		idRadnikDS.setPrimaryKey(true);
		DataSourceField datumDS = new DataSourceField("datum", FieldType.DATE,"Datum");
		DataSourceField jmbgDS = new DataSourceField("jmbg", FieldType.INTEGER,"JMBG");
		DataSourceField strucnaSpremaDS = new DataSourceField("strucnaSprema", FieldType.TEXT,"Strucna sprema");
		DataSourceField idOdeljenjeDS = new DataSourceField("idodeljenje", FieldType.INTEGER,"Id odeljenja");
		DataSourceField nazivOdeljenjaDS = new DataSourceField("naziv", FieldType.TEXT,"Odeljenje");
		DataSourceField idVrstaRadnikaDS = new DataSourceField("vrsta_radnika_id", FieldType.INTEGER,"Id vrste radnika");
		DataSourceField nazivVrsteRadnikaDS = new DataSourceField("nazivVrsteRadnika", FieldType.TEXT,"Vrsta radnika");
		DataSourceField idDoktorOblastDS = new DataSourceField("doktor_oblast_id", FieldType.INTEGER,"id doktora oblasti");
		DataSourceField nazivDoktoraOblastiDS = new DataSourceField("nazivDoktoraOblasti", FieldType.TEXT,"Doktor oblasti");
		
		addField(idRadnikDS);
		addField(nazivDS);
		addField(datumDS);
		addField(jmbgDS);
		addField(strucnaSpremaDS);
		addField(idOdeljenjeDS);
		addField(nazivOdeljenjaDS);
		addField(idVrstaRadnikaDS);
		addField(nazivVrsteRadnikaDS);
		addField(idDoktorOblastDS);
		addField(nazivDoktoraOblastiDS);
	}
	
	
	@Override
	protected void executeFetch(final String requestId, DSRequest request,
			final DSResponse response) {
		final int startIndex = (request.getStartRow () < 0)?0:request.getStartRow ();
        final int endIndex = (request.getEndRow () == null)?-1:request.getEndRow ();

        radnikService.fetch(new AsyncCallback<List<Radnik>>() {
			
			@Override
			public void onSuccess(List<Radnik> result) {
				int size = result.size ();
                if (endIndex >= 0) {
                    if (endIndex < startIndex) {
                        size = 0;
                    }
                    else {
                        size = endIndex - startIndex + 1;
                    }
                }
				
				ListGridRecord[] list = new ListGridRecord[result.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 - startIndex] = record;
                        }
                    }
                }
			}
			
			@Override
			public void onFailure(Throwable caught) {
				response.setStatus (RPCResponse.STATUS_FAILURE);
                processResponse (requestId, response);
			}
		});
	}

	@Override
	protected void executeAdd(final String requestId, DSRequest request,
			final DSResponse response) {
		JavaScriptObject data = request.getData ();
        ListGridRecord rec = new ListGridRecord (data);
        Radnik radnik = new Radnik();
        copyValuesAdd(rec, radnik);
        radnikService.add(radnik, new AsyncCallback<Radnik>() {

			@Override
			public void onFailure(Throwable caught) {
				response.setStatus (RPCResponse.STATUS_FAILURE);
                processResponse (requestId, response);
			}

			@Override
			public void onSuccess(Radnik 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, DSRequest request,
			final DSResponse response) {
		final ListGridRecord rec = getEditedRecord(request);
		Radnik radnik = new Radnik();
		copyValues(rec, radnik);
		radnikService.update(radnik, new AsyncCallback<Radnik>() {

			@Override
			public void onFailure(Throwable caught) {
				response.setStatus (RPCResponse.STATUS_FAILURE);
                processResponse (requestId, response);
			}

			@Override
			public void onSuccess(Radnik 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, DSRequest request,
			final DSResponse response) {
		JavaScriptObject data = request.getData ();
        final ListGridRecord rec = new ListGridRecord (data);
        Radnik radnik = new Radnik();
        copyValues(rec, radnik);
        radnikService.remove(radnik, new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable caught) {
				response.setStatus (RPCResponse.STATUS_FAILURE);
                processResponse (requestId, response);
			}

			@Override
			public void onSuccess(Void 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);

			}
		});
		
	}
	
	private static void copyValues (ListGridRecord from, Radnik to) {
		
		to.setId (from.getAttributeAsInt ("id"));
        to.setNaziv (from.getAttributeAsString ("naziv"));
        to.setDatum(from.getAttributeAsDate("datum"));
        to.setJmbg(from.getAttributeAsInt("jmbg"));
        to.setStrucnaSprema(from.getAttributeAsString("strucnaSprema"));
        Odeljenje odeljenje = new Odeljenje();
        odeljenje.setIdodeljenje(from.getAttributeAsInt("idodeljenje"));
        odeljenje.setNaziv(from.getAttributeAsString("naziv"));
        to.setOdeljenje(odeljenje);
        VrstaRadnika vrstaRadnika = new VrstaRadnika();
        vrstaRadnika.setIdvr(from.getAttributeAsInt("vrsta_radnika_id"));
        vrstaRadnika.setNaziv(from.getAttributeAsString("nazivVrsteRadnika"));
        to.setVrstaRadnika(vrstaRadnika);
        DoktorOblast doktorOblast = new DoktorOblast();
        doktorOblast.setIddo(from.getAttributeAsInt("doktor_oblast_id"));
        doktorOblast.setNaziv(from.getAttributeAsString("nazivDoktoraOblasti"));
        to.setDoktorOblast(doktorOblast);
    }

    private static void copyValues (Radnik from, ListGridRecord to) {
        to.setAttribute ("id", from.getId() );
        to.setAttribute ("naziv", from.getNaziv());
        to.setAttribute("datum", from.getDatum());
        to.setAttribute("jmbg", from.getJmbg());
        to.setAttribute("strucnaSprema", from.getStrucnaSprema());
        to.setAttribute("idodeljenje", from.getOdeljenje().getIdodeljenje());
        to.setAttribute("naziv", from.getOdeljenje().getNaziv());
        to.setAttribute("vrsta_radnika_id", from.getVrstaRadnika().getIdvr());
        to.setAttribute("nazivVrsteRadnika", from.getVrstaRadnika().getNaziv());
        to.setAttribute("doktor_oblast_id", from.getDoktorOblast().getIddo());
        to.setAttribute("nazivDoktoraOblasti", from.getDoktorOblast().getNaziv());
       
    }
    private static void copyValuesAdd (ListGridRecord from, Radnik to) {
    	to.setNaziv (from.getAttributeAsString ("naziv"));
        to.setDatum(from.getAttributeAsDate("datum"));
        to.setJmbg(from.getAttributeAsInt("jmbg"));
        to.setStrucnaSprema(from.getAttributeAsString("strucnaSprema"));
        Odeljenje odeljenje = new Odeljenje();
        odeljenje.setIdodeljenje(from.getAttributeAsInt("idodeljenje"));
        odeljenje.setNaziv(from.getAttributeAsString("naziv"));
        to.setOdeljenje(odeljenje);
        VrstaRadnika vrstaRadnika = new VrstaRadnika();
        vrstaRadnika.setIdvr(from.getAttributeAsInt("vrsta_radnika_id"));
        vrstaRadnika.setNaziv(from.getAttributeAsString("nazivVrsteRadnika"));
        to.setVrstaRadnika(vrstaRadnika);
        DoktorOblast doktorOblast = new DoktorOblast();
        doktorOblast.setIddo(from.getAttributeAsInt("doktor_oblast_id"));
        doktorOblast.setNaziv(from.getAttributeAsString("nazivDoktoraOblasti"));
        to.setDoktorOblast(doktorOblast);
        
    }
    private ListGridRecord getEditedRecord (DSRequest request) {
        // Retrieving values before edit
        JavaScriptObject oldValues = request.getAttributeAsJavaScriptObject ("oldValues");
        // Creating new record for combining old values with changes
        ListGridRecord newRecord = new ListGridRecord ();
        // Copying properties from old record
        JSOHelper.apply (oldValues, newRecord.getJsObj ());
        // Retrieving changed values
        JavaScriptObject data = request.getData ();
        // Apply changes
        JSOHelper.apply (data, newRecord.getJsObj ());
        return newRecord;
    }

}
