package gueei.binding.collections;
import java.util.ArrayList;
import java.util.Collection;
import gueei.binding.BindingLog;
import gueei.binding.CollectionChangedEventArg;
import gueei.binding.CollectionObserver;
import gueei.binding.IObservableCollection;
import gueei.binding.Observable;
import gueei.binding.collections.ArrayListObservable;
public abstract class DependentCollectionObservable<T> extends Observable<T> implements CollectionObserver {
protected IObservableCollection<?>[] mDependents;
public DependentCollectionObservable(Class<T> type, IObservableCollection<?>... dependents) {
super(type);
for(IObservableCollection<?> o : dependents){
o.subscribe((CollectionObserver)this);
}
this.mDependents = dependents;
ArrayList<Object> initiators = new ArrayList<Object>();
initiators.add(this);
this.onCollectionChanged(new ArrayListObservable<Object>(null), null, initiators);
}
// This is provided in case the constructor can't be used.
// Not intended for normal usage
public void addDependents(IObservableCollection<?>... dependents){
IObservableCollection<?>[] temp = mDependents;
mDependents = new IObservableCollection<?>[temp.length + dependents.length];
int len = temp.length;
for(int i=0; i<len; i++){
mDependents[i] = temp[i];
}
int len2 = dependents.length;
for(int i=0; i<len2; i++){
mDependents[i+len] = dependents[i];
dependents[i].subscribe((CollectionObserver)this);
}
ArrayList<Object> initiators = new ArrayList<Object>();
initiators.add(this);
this.onCollectionChanged(new ArrayListObservable<Object>(null), null, initiators);
}
public abstract T calculateValue(CollectionChangedEventArg e, Object... args) throws Exception;
@Override
public final void onCollectionChanged
(IObservableCollection<?> collection, CollectionChangedEventArg args, Collection<Object> initiators) {
dirty = true;
changedArgs = args;
initiators.add(collection);
this.notifyChanged(initiators);
}
private boolean dirty = false;
private CollectionChangedEventArg changedArgs = null;
@Override
public T get() {
if (dirty){
int len = mDependents.length;
Object[] values = new Object[len];
for(int i=0; i<len; i++){
values[i] = mDependents[i].get();
}
try{
T value = this.calculateValue(changedArgs, values);
this.setWithoutNotify(value);
}catch(Exception e){
BindingLog.exception
("DependentCollectionObservable.CalculateValue()", e);
}
dirty = false;
changedArgs = null;
}
return super.get();
}
public boolean isDirty() {
return dirty;
}
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
}