package org.tessell.widgets;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.view.client.CellPreviewEvent;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.Range;
import com.google.gwt.view.client.RangeChangeEvent;
import com.google.gwt.view.client.RowCountChangeEvent;
import com.google.gwt.view.client.SelectionModel;
/** GWT's {@link HasDataPresenter} is DOM coupled, so this is a mediocre attempt at reproducing it's behavior. */
public class StubAbstractHasDataWidget<T> extends StubWidget implements IsAbstractHasData<T> {
private final List<T> rowData = new ArrayList<T>();
private int redraws = 0;
private int rowCount = 0;
private boolean rowCountExact = false;
private Range visibleRange;
public StubAbstractHasDataWidget() {
this(15);
}
public StubAbstractHasDataWidget(int pageSize) {
setPageSize(pageSize);
}
public void resetRedraws() {
redraws = 0;
}
public int getRedraws() {
return redraws;
}
@Override
public void setRowData(List<? extends T> values) {
setRowData(0, values);
}
@Override
public SelectionModel<? super T> getSelectionModel() {
return null;
}
@Override
public T getVisibleItem(int indexOnPage) {
return getVisibleItems().get(indexOnPage);
}
@Override
public int getVisibleItemCount() {
return Math.min(visibleRange.getLength(), rowData.size() - visibleRange.getStart());
}
@Override
public List<T> getVisibleItems() {
return rowData.subList(visibleRange.getStart(), Math.min(rowData.size(), visibleRange.getStart() + visibleRange.getLength()));
}
@Override
public void setRowData(final int start, final List<? extends T> values) {
// copy/paste from HasDataPresenter
int valuesLength = values.size();
int valuesEnd = start + valuesLength;
// Calculate the bounded start (inclusive) and end index (exclusive).
int pageStart = getPageStart();
int pageEnd = getPageStart() + getPageSize();
int boundedStart = Math.max(start, pageStart);
int boundedEnd = Math.min(valuesEnd, pageEnd);
if (start != pageStart && boundedStart >= boundedEnd) {
// The data is out of range for the current page.
// Intentionally allow empty lists that start on the page start.
return;
}
// Create placeholders up to the specified index.
// PendingState<T> pending = ensurePendingState();
// int cacheOffset = Math.max(0, boundedStart - pageStart - getVisibleItemCount());
// for (int i = 0; i < cacheOffset; i++) {
// pending.rowData.add(null);
//}
// Insert the new values into the data array.
for (int i = boundedStart; i < boundedEnd; i++) {
T value = values.get(i - start);
int dataIndex = i - pageStart;
if (dataIndex < getVisibleItemCount()) {
rowData.set(dataIndex, value);
} else {
rowData.add(value);
}
}
// Remember the range that has been replaced.
// pending.replaceRange(boundedStart - cacheOffset, boundedEnd);
// Fire a row count change event after updating the data.
if (valuesEnd > getRowCount()) {
setRowCount(valuesEnd, isRowCountExact());
}
}
@Override
public void setSelectionModel(SelectionModel<? super T> selectionModel) {
}
@Override
public void setVisibleRangeAndClearData(Range range, boolean forceRangeChangeEvent) {
}
@Override
public HandlerRegistration addRangeChangeHandler(RangeChangeEvent.Handler handler) {
return handlers.addHandler(RangeChangeEvent.getType(), handler);
}
@Override
public HandlerRegistration addRowCountChangeHandler(RowCountChangeEvent.Handler handler) {
return handlers.addHandler(RowCountChangeEvent.getType(), handler);
}
@Override
public int getRowCount() {
return rowCount;
}
@Override
public Range getVisibleRange() {
return visibleRange;
}
@Override
public boolean isRowCountExact() {
return rowCountExact;
}
@Override
public void setRowCount(final int count) {
setRowCount(count, true);
}
@Override
public void setRowCount(final int count, final boolean isExact) {
rowCount = count;
rowCountExact = isExact;
// Update the pager.
RowCountChangeEvent.fire(this, count, isExact);
}
@Override
public void setVisibleRange(int start, int length) {
setVisibleRange(new Range(start, length));
}
@Override
public void setVisibleRange(Range range) {
this.visibleRange = range;
}
@Override
public HandlerRegistration addCellPreviewHandler(CellPreviewEvent.Handler<T> handler) {
return null;
}
@Override
public ProvidesKey<T> getKeyProvider() {
return null;
}
@Override
public int getTabIndex() {
return 0;
}
@Override
public void setAccessKey(char key) {
}
@Override
public void setFocus(boolean focused) {
}
@Override
public void setTabIndex(int index) {
}
@Override
public KeyboardPagingPolicy getKeyboardPagingPolicy() {
return null;
}
@Override
public void setKeyboardPagingPolicy(KeyboardPagingPolicy policy) {
}
@Override
public KeyboardSelectionPolicy getKeyboardSelectionPolicy() {
return null;
}
@Override
public void setKeyboardSelectionPolicy(KeyboardSelectionPolicy policy) {
}
@Override
public int getPageSize() {
return getVisibleRange().getLength();
}
@Override
public int getPageStart() {
return 0;
}
@Override
public void setPageStart(int pageStart) {
setVisibleRange(pageStart, getPageSize());
}
@Override
public void setPageSize(int pageSize) {
setVisibleRange(getPageStart(), pageSize);
}
@Override
public void redraw() {
redraws++;
}
}