package com.smartgwt.sample.client;

import java.util.Map;

import com.google.gwt.core.client.EntryPoint;
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.util.SC;
import com.smartgwt.client.widgets.events.ResizedEvent;
import com.smartgwt.client.widgets.events.ResizedHandler;
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();

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

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

		// Set grid columns to match width of main grid columns.
		// Hide column headings for the main grid.
		grid.setShowHeader(false);
		gridTotals.addFieldStateChangedHandler(new FieldStateChangedHandler() {
			@Override
			public void onFieldStateChanged(FieldStateChangedEvent event) {
				matchGridColumns();
			}
		});
		gridTotals.addResizedHandler(new ResizedHandler() {			
			@Override
			public void onResized(ResizedEvent event) {
				matchGridColumns();
			}
		});

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

		// 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 matchGridColumns() {
		for (int c=0; c<gridTotals.getFields().length; c++) {
			Integer width = gridTotals.getFieldWidth(c);
			if (width==null)
				SC.logWarn("Width for column " + c + " is null");
			else
				grid.resizeField(c, width);
		}
	}

	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("Sales", salesTotal);
		totals.setAttribute("Inventory", inventoryTotal);
		gridTotals.setData(new ListGridRecord[]{totals});

		// 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 sales = new DataSourceField();
		sales.setType(FieldType.INTEGER);
		sales.setName("Sales");
		DataSourceField inventory = new DataSourceField();
		inventory.setType(FieldType.INTEGER);
		inventory.setName("Inventory");
		ds.setFields(pk, 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("Store", "Store #" + (i*10)+j);
				rec.setAttribute("Sales", i);
				rec.setAttribute("Inventory", j);
				recs.add(rec);
			}
		}
		ds.setTestData(recs.toArray());
	}
}
