/*
* Copyright (c) 2012 Hai Bison
*
* See the file LICENSE at the root directory of this project for copying
* permission.
*/
package group.pals.android.lib.ui.filechooser.utils.history;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
/**
* A history store of any object extending {@link Parcelable}.<br>
* <b>Note:</b> This class does not support storing its {@link HistoryListener}
* 's into {@link Parcelable}. You must re-build all listeners after getting
* your {@link HistoryStore} from a {@link Bundle} for example.
*
* @author Hai Bison
* @since v2.0 alpha
*/
public class HistoryStore<A extends Parcelable> implements History<A> {
private final ArrayList<A> mHistoryList = new ArrayList<A>();
private final int mMaxSize;
private final List<HistoryListener<A>> mListeners = new ArrayList<HistoryListener<A>>();
/**
* Creates new {@link HistoryStore}
*
* @param maxSize
* the maximum size that allowed, if it is <= {@code 0},
* {@code 100} will be used
*/
public HistoryStore(int maxSize) {
this.mMaxSize = maxSize > 0 ? maxSize : 100;
}
@Override
public void push(A newItem) {
if (newItem == null)
return;
if (!mHistoryList.isEmpty() && mHistoryList.indexOf(newItem) == mHistoryList.size() - 1)
return;
mHistoryList.add(newItem);
notifyHistoryChanged();
}// push()
@Override
public void truncateAfter(A item) {
if (item == null)
return;
int idx = mHistoryList.indexOf(item);
if (idx >= 0 && idx < mHistoryList.size() - 1) {
mHistoryList.subList(idx + 1, mHistoryList.size()).clear();
notifyHistoryChanged();
}
}// truncateAfter()
@Override
public void remove(A item) {
if (mHistoryList.remove(item))
notifyHistoryChanged();
}
@Override
public void removeAll(HistoryFilter<A> filter) {
boolean changed = false;
for (int i = mHistoryList.size() - 1; i >= 0; i--) {
if (filter.accept(mHistoryList.get(i))) {
mHistoryList.remove(i);
if (!changed)
changed = true;
}
}// for
if (changed)
notifyHistoryChanged();
}// removeAll()
@Override
public void notifyHistoryChanged() {
for (HistoryListener<A> listener : mListeners)
listener.onChanged(this);
}
@Override
public int size() {
return mHistoryList.size();
}
@Override
public int indexOf(A a) {
return mHistoryList.indexOf(a);
}
@Override
public A prevOf(A a) {
int idx = mHistoryList.indexOf(a);
if (idx > 0)
return mHistoryList.get(idx - 1);
return null;
}
@Override
public A nextOf(A a) {
int idx = mHistoryList.indexOf(a);
if (idx >= 0 && idx < mHistoryList.size() - 1)
return mHistoryList.get(idx + 1);
return null;
}
@SuppressWarnings("unchecked")
@Override
public ArrayList<A> items() {
return (ArrayList<A>) mHistoryList.clone();
}// items()
@Override
public boolean isEmpty() {
return mHistoryList.isEmpty();
}
@Override
public void clear() {
mHistoryList.clear();
notifyHistoryChanged();
}
@Override
public void addListener(HistoryListener<A> listener) {
mListeners.add(listener);
}
@Override
public void removeListener(HistoryListener<A> listener) {
mListeners.remove(listener);
}
/*-----------------------------------------------------
* Parcelable
*/
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mMaxSize);
dest.writeInt(size());
for (int i = 0; i < size(); i++)
dest.writeParcelable(mHistoryList.get(i), flags);
}
@SuppressWarnings("rawtypes")
public static final Parcelable.Creator<HistoryStore> CREATOR = new Parcelable.Creator<HistoryStore>() {
public HistoryStore createFromParcel(Parcel in) {
return new HistoryStore(in);
}
public HistoryStore[] newArray(int size) {
return new HistoryStore[size];
}
};
@SuppressWarnings("unchecked")
private HistoryStore(Parcel in) {
mMaxSize = in.readInt();
int count = in.readInt();
for (int i = 0; i < count; i++)
mHistoryList.add((A) in.readParcelable(null));
}
}