package org.gcube.portlets.user.gisviewer.client.datafeature;

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

import org.gcube.portlets.user.gisviewer.client.Constants;
import org.gcube.portlets.user.gisviewer.client.GisViewerPanel;
import org.gcube.portlets.user.gisviewer.client.event.TableRowSelectedEvent;

import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.StoreEvent;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.grid.filters.GridFilters;
import com.extjs.gxt.ui.client.widget.grid.filters.StringFilter;
import com.google.gwt.core.client.GWT;


/**
 * The Class GxtGridFilter.
 *
 * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy)
 * May 12, 2020
 */
public class GxtGridFilter {

	private Grid<BaseModel> grid;
	private ListStore<BaseModel> store;

	/**
	 * Instantiates a new gxt grid filter group panel.
	 *
	 * @param columnNames the column names
	 * @param dataRows the data rows
	 */
	public GxtGridFilter(List<String> columnNames, List<BaseModel> dataRows) {
		List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
		store = new ListStore<BaseModel>();

		// adding filters as String filter
		GridFilters filters = new GridFilters();
		filters.setLocal(true);

		for (final String columnName : columnNames) {
			ColumnConfig column = new ColumnConfig();
			column.setId(columnName);
			column.setHeader(columnName);
			// set the renderer for the grid cell. Adding the tool-tip 'title'
			column.setRenderer(new GridCellRenderer<BaseModel>() {
				@Override
				public Object render(BaseModel model, String property, ColumnData config, int rowIndex, int colIndex,
						ListStore<BaseModel> store, Grid<BaseModel> grid) {
					String value = model.get(property);
					if (value != null) {
//			                     return "<div qtitle='" + Format.htmlEncode(value) + 
//			                            "' qtip='" + Format.htmlEncode(value) + 
//			                            "'>" + value + "</div>";
						// String thevalue = Format.htmlEncode(value);
						String thevalue = value;
						// GWT.log("value is: "+thevalue);
						return "<span title='" + thevalue + "'>" + thevalue + "</span>";
					}
					return value;
				}
			});
			column.setWidth(Constants.WFS_COLUMN_WIDTH);
			configs.add(column);
			
			StringFilter theStringFilter = new StringFilter(columnName);
			filters.addFilter(theStringFilter);
		}

		store.add(dataRows);
		ColumnModel cm = new ColumnModel(configs);

		grid = new Grid<BaseModel>(store, cm);
		grid.setBorders(false);
		grid.setStripeRows(true);
		grid.setColumnLines(true);

		//grid.getView().setAutoFill(true);
		//grid.getView().setForceFit(true);
		//grid.getView().setShowDirtyCells(false);
		grid.getView().setEmptyText("No data");

		// adding plugin filter
		grid.addPlugin(filters);

		// selection listener
		grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);

		grid.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<BaseModel>() {

			@Override
			public void selectionChanged(SelectionChangedEvent<BaseModel> se) {

				ModelData target = se.getSelectedItem();
				if (target != null) {
					GWT.log("selection grid change: "+target);
					GisViewerPanel.getEventbus().fireEvent(new TableRowSelectedEvent(target));
				}

			}
		});

		grid.setContextMenu(null); // add context menu null - ignore browse event right click
		addDataChangedStoreListener();

	}

	
	/**
	 * Gets the grid.
	 *
	 * @return the grid
	 */
	public Grid<BaseModel> getGrid() {
		return grid;
	}


	/**
	 * Gets the selected item.
	 *
	 * @return the selected item
	 */
	public BaseModel getSelectedItem() {

		return grid.getSelectionModel().getSelectedItem();
	}

	/**
	 * Gets the store.
	 *
	 * @return the store
	 */
	public ListStore<BaseModel> getStore() {
		return store;
	}

	/**
	 * Adds the data changed store listener.
	 */
	private void addDataChangedStoreListener() {

		store.addListener(Store.Add, new Listener<StoreEvent<ModelData>>() {

			@Override
			public void handleEvent(StoreEvent<ModelData> be) {

			}
		});

		store.addListener(Store.Remove, new Listener<StoreEvent<ModelData>>() {

			@Override
			public void handleEvent(StoreEvent<ModelData> be) {

			}
		});

		store.addListener(Store.Clear, new Listener<StoreEvent<ModelData>>() {

			@Override
			public void handleEvent(StoreEvent<ModelData> be) {

			}
		});

	}

}