package com.fircosoft.cdb.client.api.application.test;

import java.util.ArrayList;
import java.util.List;

import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.types.RecordComponentPoolingMode;
import com.smartgwt.client.types.SortDirection;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;

abstract class ComponentGrid<T extends Canvas> extends ListGrid{
	public static final String FIELD_ID = "ID";
	public static final String FIELD_DATA = "DATA";
	public int MAX = 1000;
	
	private DataSource dataSource;
	private List<ListGridField> fields = new ArrayList<ListGridField>();
	private boolean deleteOldRecords = false;
	private int maxRecrod = MAX;
	private int count = 0;
	
	private List<ListGridRecord> records = new ArrayList<ListGridRecord>();
	
	public ComponentGrid(){
		setShowHeader(false);
		setWidth100();
		
		dataSource = new DataSource();
		dataSource.setClientOnly(true);
		
		DataSourceIntegerField pkField = new DataSourceIntegerField(FIELD_ID);
	    pkField.setHidden(true);
	    pkField.setPrimaryKey(true);
	    dataSource.setFields(pkField);
		setDataSource(dataSource);
		
		ListGridField dataField = new ListGridField(FIELD_DATA);
		fields.add(dataField);
		
		setFields(dataField);
		
		setAutoFetchData(true);
		
		setShowRecordComponents(true);
		setRecordComponentPoolingMode(RecordComponentPoolingMode.RECYCLE);
	}
	
	/**
	 * Updates the record component with new values.
	 * @param record The corresponding ListGridRecord
	 * @param component The record component
	 */
	public abstract void updateRecordComponent(final ListGridRecord record, final T component);
	
	/**
	 * Creates and initialize a new record component to display in the list grid.
	 * @param record The corresponding ListGridRecord
	 * @return The record component
	 */
	public abstract T createNewRecordComponent(final ListGridRecord record);
	
	/**
	 * Adds the specified record to the list. And if deleteOldRecords it set to true and that the maximum record is reached,
	 * remove the first record added (First In First Out)
	 * @param record The record
	 */
	public void addRecordToGrid(ListGridRecord record){
		
		record.setAttribute(FIELD_ID,count);
		
		if(deleteOldRecords && records.size()>=maxRecrod){
			ListGridRecord toDelete = records.get(0);
			int index = getRecordIndex(toDelete);
			toDelete = getRecord(index);
			removeEmbeddedComponent(toDelete);
			removeData(toDelete);
			records.remove(0);
		}
		
		addData(record);
		if(deleteOldRecords)
			records.add(record);
		count++;	
	}
	
	/**
	 * Sets the sort direction for the added record. 
	 * The default sort is newest record on the top of the list (SortDirection.DESCENDING)
	 */
	public void setRecordSortDirection(SortDirection sortDirection){
		setSortDirection(sortDirection);
	}
	
	/**
	 * Specifies if old record must be deleted when the specified maximum size is reached.
	 * @param deleteOldRecords True to delete old record
	 */
	public void setDeleteOldRecords(boolean deleteOldRecords) {
		this.deleteOldRecords = deleteOldRecords;
	}

	/**
	 * Specifies the max record size, default is MAX_RECORD
	 * @param maxRecrod The maximum record
	 */
	public void setMaxRecrod(int maxRecrod) {
		this.maxRecrod = maxRecrod;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Canvas updateRecordComponent(final ListGridRecord record, Integer colNum, Canvas component, boolean recordChanged) {
		updateRecordComponent(record, (T)component);
		return component;
	}
	
	@Override
	protected Canvas createRecordComponent(final ListGridRecord record, Integer colNum) {
		return createNewRecordComponent(record);
	}
}
