package com.baselet.control.basics; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * Maintains a sorted list of none overlapping Line1D elements. * On insertion the existing elements are searched if the new element * would overlap with some of them then all the overlapping elements * including the new one are merged into one element. */ public class SortedMergedLine1DList implements List<Line1D> { private final List<Line1D> list = new ArrayList<Line1D>(); @Override public int size() { return list.size(); } @Override public boolean isEmpty() { return list.isEmpty(); } @Override public boolean contains(Object o) { return list.contains(o); } @Override public Iterator<Line1D> iterator() { return list.iterator(); } @Override public Object[] toArray() { return list.toArray(); } @Override public <T> T[] toArray(T[] a) { return list.toArray(a); } /** * The element is NOT inserted at the END. * It will be inserted according to the sorting * and maybe a merge of two or more elements will happen. * * @param e the element which will be inserted at the correct position to maintain a sorted list. Maybe a merge of elements happens. Low and High must be != null. */ @Override public boolean add(Line1D e) { if (contains(e)) { return false; } else { ListIterator<Line1D> listIter = list.listIterator(); // while high < e.low no overlap while (listIter.hasNext()) { if (listIter.next().getHigh() >= e.getLow()) { listIter.previous(); break; } } if (!listIter.hasNext()) { list.add(e); return true; } else { int insertIndex = listIter.nextIndex(); Line1D tmpLine = listIter.next(); if (tmpLine.getLow() <= e.getHigh()) { double low = Math.min(tmpLine.getLow(), e.getLow()); double high = tmpLine.getHigh(); while (listIter.hasNext()) { tmpLine = listIter.next(); if (e.isIntersecting(tmpLine)) { listIter.remove(); high = tmpLine.getHigh(); } else { break; } } list.set(insertIndex, new Line1D(low, Math.max(e.getHigh(), high))); } else { list.add(insertIndex, e); } return true; } } } @Override public boolean remove(Object o) { return list.remove(o); } @Override public boolean containsAll(Collection<?> c) { return list.containsAll(c); } /** * The element is NOT inserted at the END. * @see #add(Line1D) */ @Override public boolean addAll(Collection<? extends Line1D> c) { boolean changed = false; for (Line1D l : c) { changed = add(l) || changed; } return changed; } /** * The element is NOT inserted at the END. * @see #add(Line1D) */ public boolean addAll(Line1D[] c) { boolean changed = false; for (Line1D l : c) { changed = add(l) || changed; } return changed; } /** * NOT supported. */ @Override public boolean addAll(int index, Collection<? extends Line1D> c) { throw new UnsupportedOperationException(); } @Override public boolean removeAll(Collection<?> c) { return list.removeAll(c); } @Override public boolean retainAll(Collection<?> c) { return list.retainAll(c); } @Override public void clear() { list.clear(); } @Override public Line1D get(int index) { return list.get(index); } /** * NOT supported. */ @Override public Line1D set(int index, Line1D element) { throw new UnsupportedOperationException(); } /** * NOT supported. */ @Override public void add(int index, Line1D element) { throw new UnsupportedOperationException(); } @Override public Line1D remove(int index) { return list.remove(index); } @Override public int indexOf(Object o) { return list.indexOf(o); } @Override public int lastIndexOf(Object o) { return list.lastIndexOf(o); } @Override public ListIterator<Line1D> listIterator() { return list.listIterator(); } @Override public ListIterator<Line1D> listIterator(int index) { return list.listIterator(index); } @Override public List<Line1D> subList(int fromIndex, int toIndex) { return list.subList(fromIndex, toIndex); } }