package com.eas.grid.rows;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.eas.bound.JsArrayList;
import com.eas.core.Utils;
import com.eas.core.Utils.JsObject;
import com.eas.grid.processing.TreeAdapter;
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;
public class JsTree extends TreeAdapter<JavaScriptObject> implements JsDataContainer {
protected JavaScriptObject data;
protected HandlerRegistration boundToData;
protected HandlerRegistration boundToDataElements;
protected String parentField;
protected String childrenField;
public JsTree(String aParentField, String aChildrenField) {
super();
parentField = aParentField;
childrenField = aChildrenField;
}
protected ScheduledCommand changesQueued;
protected void enqueueChanges() {
changesQueued = new ScheduledCommand() {
@Override
public void execute() {
if (changesQueued == this) {
changesQueued = null;
if (data != null) {
List<JavaScriptObject> items = new JsArrayList(data);
for (int i = 0; i < items.size(); i++) {
JavaScriptObject item = items.get(i);
changed(item);
}
}
}
}
};
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;
}
if (data != null) {
boundToDataElements = Utils.listenElements(data, new Utils.OnChangeHandler() {
@Override
public void onChange(JavaScriptObject anEvent) {
enqueueChanges();
}
});
}
everythingChanged();
}
}
};
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 JavaScriptObject getData() {
return data;
}
@Override
public void setData(JavaScriptObject aValue) {
if (data != aValue) {
unbind();
data = aValue;
bind();
}
}
protected boolean hasRowChildren(JavaScriptObject parent) {
List<JavaScriptObject> children = findChildren(parent);
return children != null && !children.isEmpty();
}
protected List<JavaScriptObject> findChildren(JavaScriptObject aParent) {
if (aParent == null) {
if (data != null) {
List<JavaScriptObject> items = new JsArrayList(data);
List<JavaScriptObject> roots = new ArrayList<>();
for (int i = 0; i < items.size(); i++) {
JavaScriptObject item = items.get(i);
if (item != null && item.<JsObject> cast().getJs(parentField) == null) {
roots.add(item);
}
}
return roots;
} else {
return null;
}
} else {
JavaScriptObject children = aParent.<JsObject> cast().getJs(childrenField);
return children != null ? new JsArrayList(children) : null;
}
}
// Tree structure of a rowset
@Override
public JavaScriptObject getParentOf(JavaScriptObject anElement) {
return anElement.<JsObject> cast().getJs(parentField);
}
@Override
public List<JavaScriptObject> getChildrenOf(JavaScriptObject anElement) {
List<JavaScriptObject> found = findChildren(anElement);
return found != null ? found : Collections.<JavaScriptObject> emptyList();
}
@Override
public boolean isLeaf(JavaScriptObject anElement) {
return !hasRowChildren(anElement);
}
// Tree mutation methods
@Override
public void add(JavaScriptObject aParent, JavaScriptObject anElement) {
}
@Override
public void add(int aIndex, JavaScriptObject aParent, JavaScriptObject anElement) {
}
@Override
public void addAfter(JavaScriptObject afterElement, JavaScriptObject anElement) {
}
@Override
public void remove(JavaScriptObject anElement) {
}
@Override
public void changedItems(JavaScriptObject anArray) {
enqueueChanges();
}
@Override
public void addedItems(JavaScriptObject anArray) {
enqueueReadd();
}
@Override
public void removedItems(JavaScriptObject anArray) {
enqueueReadd();
}
}