package gueei.binding.collections;
import gueei.binding.CollectionChangedEventArg;
import gueei.binding.CollectionChangedEventArg.Action;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import android.os.Parcel;
import android.os.Parcelable;
public class ArrayListObservable<T>
extends ObservableCollection<T>
implements List<T>, Parcelable{
private final Class<T> mType;
protected ArrayList<T> mArray;
public ArrayListObservable(Class<T> type){
this(type, null);
}
public ArrayListObservable(Class<T> type, T[] initArray){
mType = type;
mArray = new ArrayList<T>();
if (initArray!=null)
{
for(int i=0; i<initArray.length; i++){
mArray.add(initArray[i]);
}
}
}
public T getItem(int position) {
return mArray.get(position);
}
public void onLoad(int position) {
}
public void clear(){
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Reset, (List<?>)null);
mArray.clear();
this.notifyCollectionChanged(e);
}
/**
* set from array and clear
*
* @param newArray
*/
public void setArray(T[] newArray){
Object [] oldItems = mArray.toArray();
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Replace, Arrays.asList(newArray), Arrays.asList(oldItems));
mArray.clear();
int size = newArray.length;
for (int i=0; i<size; i++){
mArray.add(newArray[i]);
}
this.notifyCollectionChanged(e);
}
public void replaceItem(int position, T item){
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Replace, item, mArray.get(position), position);
mArray.set(position, item);
this.notifyCollectionChanged(e);
}
public int indexOf(Object item){
return mArray.indexOf(item);
}
public Class<T> getComponentType() {
return mType;
}
public boolean addAll(Collection<? extends T> arg0) {
boolean result = mArray.addAll(arg0);
if (result){
@SuppressWarnings("unchecked")
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Add, Arrays.asList(arg0), mArray.size()-arg0.size()-1);
this.notifyCollectionChanged(e);
}
return result;
}
/**
* set from list and clear
*
* @param arg0
*/
public void setAll(Collection<? extends T> arg0) {
Object [] oldItems = mArray.toArray();
mArray.clear();
mArray.addAll(arg0);
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Replace, mArray, Arrays.asList(oldItems));
this.notifyCollectionChanged(e);
}
public boolean containsAll(Collection<?> arg0) {
return mArray.containsAll(arg0);
}
public boolean isEmpty() {
return mArray.isEmpty();
}
public Iterator<T> iterator() {
return mArray.iterator();
}
public boolean removeAll(Collection<?> arg0) {
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Remove, mArray);
boolean result = mArray.removeAll(arg0);
if (result){
this.notifyCollectionChanged(e);
}
return result;
}
public boolean retainAll(Collection<?> arg0) {
List<Object>inverseIntersect = new ArrayList<Object>();
if(arg0.size() > mArray.size()) {
for(Object o : arg0){
if(!mArray.contains(o))
inverseIntersect.add(o);
}
} else {
for(Object o : mArray){
if(!arg0.contains(o))
inverseIntersect.add(o);
}
}
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Remove, inverseIntersect);
boolean result = mArray.retainAll(arg0);
if (result){
this.notifyCollectionChanged(e);
}
return result;
}
public T remove(int index){
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Remove,
Arrays.asList(new Object[]{mArray.get(index)}), index);
T obj = mArray.remove(index);
this.notifyCollectionChanged(e);
return obj;
}
public int size() {
return mArray.size();
}
public Object[] toArray() {
return mArray.toArray();
}
public <Ta> Ta[] toArray(Ta[] array) {
return mArray.toArray(array);
}
public boolean add(T object) {
boolean result = mArray.add(object);
if (result){
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Add, Arrays.asList(new Object[]{object}), (int)mArray.size()-1);
this.notifyCollectionChanged(e);
}
return result;
}
public boolean contains(Object object) {
return mArray.contains(object);
}
public boolean remove(Object object) {
int index = mArray.indexOf(object);
boolean result = mArray.remove(object);
if (result){
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Remove, Arrays.asList(new Object[]{object}), index);
this.notifyCollectionChanged(e);
}
return result;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
try{
dest.writeArray(this.toArray());
}catch(Exception e){
// The array is not parcelable.. ok?
}
}
@SuppressWarnings("unchecked")
@Override
public void _setObject(Object newValue, Collection<Object> initiators) {
if (newValue instanceof ArrayListObservable && this != newValue) {
mArray=((ArrayListObservable<T>)newValue).mArray;
initiators.add(this);
this.notifyChanged(initiators);
}
}
public static final Parcelable.Creator<ArrayListObservable<?>> CREATOR =
new Parcelable.Creator<ArrayListObservable<?>>() {
@SuppressWarnings({ "rawtypes", "unchecked" })
public ArrayListObservable<?> createFromParcel(Parcel source) {
Object[] arr = source.readArray(this.getClass().getClassLoader());
return new ArrayListObservable(arr.getClass().getComponentType(), arr);
}
public ArrayListObservable<?>[] newArray(int size) {
return new ArrayListObservable[size];
}
};
public void add(int location, T object) {
if( location < 0 )
location = 0;
if( location>mArray.size())
location = mArray.size();
mArray.add(location, object);
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Add, Arrays.asList(new Object[]{object}), location);
this.notifyCollectionChanged(e);
}
public boolean addAll(int arg0, Collection<? extends T> arg1) {
return false;
}
public T get(int location) {
return mArray.get(location);
}
public int lastIndexOf(Object object) {
return mArray.lastIndexOf(object);
}
public ListIterator<T> listIterator() {
return mArray.listIterator();
}
public ListIterator<T> listIterator(int location) {
return mArray.listIterator(location);
}
public T set(int location, T object) {
CollectionChangedEventArg e = new CollectionChangedEventArg(Action.Replace, mArray.indexOf(object));
T temp = mArray.set(location, object);
notifyCollectionChanged(e);
return temp;
}
public List<T> subList(int start, int end) {
return mArray.subList(start, end);
}
public void setVisibleChildrenCount(Object setter, int total) {
}
@Override
public boolean isNull() {
return false;
}
}