package com.smartgwt.sample.client;

import java.util.Map;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Random;
import com.smartgwt.client.data.DSCallback;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.types.Autofit;
import com.smartgwt.client.types.FieldType;
import com.smartgwt.client.widgets.events.ScrolledEvent;
import com.smartgwt.client.widgets.events.ScrolledHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.EditCompleteEvent;
import com.smartgwt.client.widgets.grid.events.EditCompleteHandler;
import com.smartgwt.client.widgets.grid.events.FieldStateChangedEvent;
import com.smartgwt.client.widgets.grid.events.FieldStateChangedHandler;
import com.smartgwt.client.widgets.layout.VLayout;

public class BuiltInDS implements EntryPoint {

	private ListGrid gridTotals = new ListGrid();
	private ListGrid grid = new ListGrid();

	public void onModuleLoad() {

		DataSource ds = buildDataSource();

		// Main grid
		grid.setDataSource(ds);
		grid.setHeight100();
		grid.setWidth100();
		grid.setShowGroupSummary(true);
		grid.setShowGridSummary(false);
		grid.setAutoFetchData(false);
		grid.setCanEdit(true);
		grid.addEditCompleteHandler(new EditCompleteHandler() {		
			@Override
			public void onEditComplete(EditCompleteEvent event) {
				calcGridTotals(event.getOldRecord(), event.getNewValues());
			}
		});
		

		// Totals grid
		gridTotals.setDataSource(ds);
		gridTotals.setWidth100();
		gridTotals.setAutoFitData(Autofit.VERTICAL);
		gridTotals.setAutoFetchData(false);

		// Set grid columns to match width of main grid columns.
		// Hide column headings for the main grid.
		gridTotals.setShowHeader(false);
		grid.addFieldStateChangedHandler(new FieldStateChangedHandler() {
			@Override
			public void onFieldStateChanged(FieldStateChangedEvent event) {
				gridTotals.setFieldState(grid.getFieldState());
			}
		});
		grid.addScrolledHandler(new ScrolledHandler() {
			
			@Override
			public void onScrolled(ScrolledEvent event) {
				gridTotals.scrollBodyTo(grid.getScrollLeft(), grid.getScrollTop());
			}
		});

		// Put the two grids together in an VLayout.
		VLayout gridLayout = new VLayout(0);
		gridLayout.setWidth100();
		gridLayout.setHeight100();
		gridLayout.setMembers(grid, gridTotals);
		gridLayout.draw();

		// Load the main grid with data and after loading calculate gridTotals.
		grid.fetchData(null, new DSCallback() {			
			@Override
			public void execute(DSResponse response, Object rawData, DSRequest request) {
				calcGridTotals(null, null);
			}
		});

	}


	protected void calcGridTotals(Record oldRecord, Map newValues) {

		// If input params are null, recalculate the entire grid.
		int salesTotal = 0;
		int inventoryTotal = 0;
		for (Record rec : grid.getRecords()) {
			salesTotal += rec.getAttributeAsInt("Sales");
			inventoryTotal += rec.getAttributeAsInt("Inventory");
		}
		ListGridRecord totals = new ListGridRecord();
		totals.setAttribute("Store", "Total");
		totals.setAttribute("Group", "Total");
		totals.setAttribute("Sales", salesTotal);
		totals.setAttribute("Inventory", inventoryTotal);

		ListGridRecord averages = new ListGridRecord();
		averages.setAttribute("Store", "Average");
		averages.setAttribute("Group", "Average");
		averages.setAttribute("Sales", salesTotal / grid.getRecords().length);
		averages.setAttribute("Inventory", inventoryTotal / grid.getRecords().length);
		
		gridTotals.setData(new ListGridRecord[]{totals, averages});

		// TODO Calculate changes if we were passed old and new record values
	}

	/**
	 * @return
	 */
	private DataSource buildDataSource() {
		DataSource ds = new DataSource();
		ds.setClientOnly(true);
		DataSourceField pk = new DataSourceField();
		pk.setType(FieldType.TEXT);
		pk.setName("Store");
		pk.setPrimaryKey(true);
		DataSourceField group = new DataSourceField();
		group.setType(FieldType.TEXT);
		group.setName("Group");
		DataSourceField sales = new DataSourceField();
		sales.setType(FieldType.INTEGER);
		sales.setName("Sales");
		DataSourceField inventory = new DataSourceField();
		inventory.setType(FieldType.INTEGER);
		inventory.setName("Inventory");
		ds.setFields(pk, group, sales, inventory);
		loadData(ds);
		return ds;
	}

	private void loadData(DataSource ds) {
		RecordList recs = new RecordList();
		for (int i=1; i<10; i++) {
			for (int j=0; j<3; j++) {
				ListGridRecord rec = new ListGridRecord();
				rec.setAttribute("Group", "Group #" + (i*10));
				rec.setAttribute("Store", "Store #" + (i*10)+j);
				rec.setAttribute("Sales", Random.nextInt(300));
				rec.setAttribute("Inventory", Random.nextInt(1000));
				recs.add(rec);
			}
		}
		ds.setTestData(recs.toArray());
	}
}
