package lt.inventi.wicket.component.breadcrumb.collapse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import lt.inventi.wicket.component.breadcrumb.BEquality;
abstract class CollapseUtils {
private CollapseUtils() {
// static utils
}
static <F, T> List<T> collapse(List<F> source, BEquality<F> sameEq, BEquality<F> collapseEq,
BFun<F, T> transformSingle, BFun<Iterable<F>, T> transformCollapsed, int times) {
List<T> acc = new ArrayList<T>();
Iterator<F> forward = source.iterator();
List<F> backwardsSource = reverse(source);
F collapseTo = null;
while (forward.hasNext()) {
F f = forward.next();
int timesFound = 0;
Iterator<F> backwards = backwardsSource.iterator();
while (backwards.hasNext()) {
F b = backwards.next();
if (sameEq.equal(f, b)) {
break;
} else if (collapseEq.equal(f, b)) {
if (collapseTo == null) {
collapseTo = b;
}
if (timesFound++ == times) {
break;
}
}
}
if (collapseTo == null || timesFound < times) {
collapseTo = null;
acc.add(transformSingle.apply(f));
} else {
List<F> collapsed = new ArrayList<F>();
collapsed.add(f);
while (forward.hasNext()) {
F nextCollapsed = forward.next();
if (nextCollapsed == collapseTo) {
break;
}
collapsed.add(nextCollapsed);
}
acc.add(transformCollapsed.apply(collapsed));
acc.add(transformSingle.apply(collapseTo));
while (forward.hasNext()) {
acc.add(transformSingle.apply(forward.next()));
}
}
}
return acc;
}
private static <F> List<F> reverse(List<F> source) {
ArrayList<F> backwardsSource = new ArrayList<F>(source);
Collections.reverse(backwardsSource);
return backwardsSource;
}
}