/*=============================================================================#
 # Copyright (c) 2012, 2021 Original NatTable authors and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0
 # 
 # Contributors:
 #     Original NatTable authors and others - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ecommons.waltable.data;

import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;


/**
 * Enables the use of a {@link List} containing POJO(s) as a backing data source.
 * 
 * By default a bean at position 'X' in the list is displayed in 
 * row 'X' in the table. The properties of the bean are used to 
 * populate the columns. A {@link IColumnPropertyResolver} is used to
 * retrieve column data from the bean properties. 
 * 
 * By implementing filter logic within {@link AbstractFilterListDataProvider#show(Object)}
 * it is possible to create a static filter. All data access methods will skip invisible
 * items within the wrapped list and delegate access to the visible items.
 * 
 * NOTE: This way of static filtering can cause performance issues for huge data sets
 * where a lot of items are filtered, because data access will always calculate the visible row
 * position. Trying to use a caching mechanism would create some issues for deleting or inserting
 * new data to the wrapped list.
 * 
 * TODO add caching that reacts on insert/delete actions on the wrapped list
 * 
 * @param <T> type of the Objects in the backing list.
 * @see IColumnPropertyResolver
 */
public abstract class AbstractFilterListDataProvider<T> extends ListDataProvider<T> {
	
	public AbstractFilterListDataProvider(final List<T> list, final IColumnAccessor<T> columnAccessor) {
		super(list, columnAccessor);
	}

	/**
	 * Iterates over the whole list of data objects and checks the visibility for
	 * every object. The number of non visible items will be subtracted from the
	 * size of the wrapped list to return the number of visible items.
	 */
	@Override
	public long getRowCount() {
		long numberOfInvisible= 0;
		for (final T object : this.list) {
			if (!show(object)) {
				numberOfInvisible++;
			}
		}
		return this.list.size() - numberOfInvisible;
	}

	/**
	 * Get the data value for the columnIndex and the visible rowIndex.
	 */
	@Override
	public Object getDataValue(final long columnIndex, final long rowIndex, final int flags, final IProgressMonitor monitor) {
		final T rowObj= getRowObject(rowIndex);
		return this.columnAccessor.getDataValue(rowObj, columnIndex);
	}
	
	/**
	 * Set the data value for the columnIndex and the visible rowIndex.
	 */
	@Override
	public void setDataValue(final long columnIndex, final long rowIndex, final Object newValue) {
		final T rowObj= getRowObject(rowIndex);
		this.columnAccessor.setDataValue(rowObj, columnIndex, newValue);
	}

	/**
	 * Returns the object for the visible rowIndex.
	 * To do this it is iterated over the wrapped list, taking the invisible
	 * items into account, so the real row index for the given visible row index
	 * is calculated.
	 */
	@Override
	public T getRowObject(final long rowIndex) {
		if (rowIndex >= Integer.MAX_VALUE) {
			return null;
		}
		T object= null;
		long count= 0;
		int realRowIndex= 0;
		while (count <= rowIndex) {
			object= this.list.get(realRowIndex);
			if (show(object)) {
				count++;
			}
			realRowIndex++;
		}
		
		return object;
	}
	
	/**
	 * Returns the visible rowIndex for the given object.
	 * To do this the real row index for the object within the wrapped list
	 * is searched and then all invisible items are subtracted from the
	 * real row index to calculate the visible row index.
	 */
	@Override
	public long indexOfRowObject(final T rowObject) {
		final int realRowIndex= this.list.indexOf(rowObject);
		int filteredIndex= realRowIndex;
		//now find number of not visible items
		T vf= null;
		for (int i= 0; i <= realRowIndex; i++) {
			vf= this.list.get(i);
			if (!show(vf)) {
				filteredIndex--;
			}
		}
		return filteredIndex;
	}
	
	/**
	 * Within this method the filter logic should be applied.
	 * Return false if the object should not be visible within the grid.
	 * Return true if it should be visible.
	 * @param object The object that should be checked.
	 * @return true if the object should be visible, false if not
	 */
	protected abstract boolean show(T object);
}
