package com.eas.grid.rows;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.eas.bound.JsArrayList;
import com.eas.core.Utils;
import com.eas.core.Utils.JsObject;
import com.eas.grid.processing.IndexOfProvider;
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.view.client.ListDataProvider;
public class JsArrayListDataProvider extends ListDataProvider<JavaScriptObject> implements IndexOfProvider<JavaScriptObject>, JsDataContainer {
protected JsObject data;
protected HandlerRegistration boundToData;
protected HandlerRegistration boundToDataElements;
protected Map<JavaScriptObject, Integer> indicies;
protected Runnable onResize;
protected Runnable onChange;
protected Callback<Void, String> onError;
public JsArrayListDataProvider(Runnable aOnResize, Runnable aOnChange, Callback<Void, String> aOnError) {
super();
onResize = aOnResize;
onChange = aOnChange;
onError = aOnError;
}
@Override
public JavaScriptObject getData() {
return data;
}
protected ScheduledCommand changesQueued;
protected void enqueueChanges() {
changesQueued = new ScheduledCommand() {
@Override
public void execute() {
if (changesQueued == this) {
changesQueued = null;
if (onChange != null)
onChange.run();
}
}
};
Scheduler.get().scheduleDeferred(changesQueued);
}
protected ScheduledCommand readdQueued;
private void enqueueReadd() {
readdQueued = new ScheduledCommand() {
@Override
public void execute() {
if (readdQueued == this) {
readdQueued = null;
if (boundToDataElements != null) {
boundToDataElements.removeHandler();
boundToDataElements = null;
}
getList().clear();
if (data != null) {
getList().addAll(new JsArrayList(data));
boundToDataElements = Utils.listenElements(data, new Utils.OnChangeHandler() {
@Override
public void onChange(JavaScriptObject anEvent) {
enqueueChanges();
}
});
}
if (onResize != null)
onResize.run();
}
}
};
Scheduler.get().scheduleDeferred(readdQueued);
}
protected void bind() {
if (data != null) {
boundToData = Utils.listenPath(data, "length", new Utils.OnChangeHandler() {
@Override
public void onChange(JavaScriptObject anEvent) {
enqueueReadd();
}
});
enqueueReadd();
}
}
protected void unbind() {
if (boundToData != null) {
boundToData.removeHandler();
boundToData = null;
enqueueReadd();
}
}
@Override
public void setData(JavaScriptObject aValue) {
if (data != aValue) {
unbind();
data = aValue != null ? aValue.<JsObject> cast() : null;
bind();
}
}
protected void invalidate() {
indicies = null;
}
protected void validate() {
if (indicies == null) {
indicies = new HashMap<>();
List<JavaScriptObject> targetList = getList();
if (targetList != null) {
for (int i = 0; i < targetList.size(); i++) {
indicies.put(targetList.get(i), i);
}
}
}
}
@Override
public int indexOf(JavaScriptObject aItem) {
validate();
Integer idx = indicies.get(aItem);
return idx != null ? idx.intValue() : -1;
}
@Override
public void rescan() {
invalidate();
validate();
}
@Override
public void changedItems(JavaScriptObject anArray) {
enqueueChanges();
}
@Override
public void addedItems(JavaScriptObject anArray) {
enqueueReadd();
}
@Override
public void removedItems(JavaScriptObject anArray) {
enqueueReadd();
}
}