package com.github.davidmoten.rtree;

import java.util.ArrayList;
import java.util.List;

import com.github.davidmoten.rtree.geometry.Geometry;
import com.github.davidmoten.rtree.geometry.Rectangle;
import com.google.common.base.Optional;

public class SelectorMinimalOverlap implements Selector {

	@Override
	public <T> Node<T> select(Geometry g, List<? extends Node<T>> nodes) {
		return findMinimalOverlap(g.mbr(), nodes);
	}

	private static <T> Node<T> findMinimalOverlap(Rectangle r,
			List<? extends Node<T>> list) {
		List<Node<T>> best = new ArrayList<Node<T>>();
		Optional<Double> bestMetric = Optional.absent();
		for (Node<T> node : list) {
			double m = 0;
			for (Node<T> node2 : list) {
				Rectangle nodePlusR = node.geometry().mbr().add(r);
				if (node2 != node) {
					m += nodePlusR.intersectionArea(node2.geometry().mbr());
				}
			}
			if (!bestMetric.isPresent() || m < bestMetric.get()) {
				best = new ArrayList<Node<T>>();
				best.add(node);
				bestMetric = Optional.of(m);
			} else if (bestMetric.isPresent() && m == bestMetric.get()) {
				best.add(node);
			}
		}
		return SelectorMinimalAreaIncrease.findMinimalAreaIncrease(r, best);
	}
}

@@ -48,25 +48,56 @@
 va.util.
-ArrayList
+Collections;%0Aimport java.util.Comparator
 ;%0Aimport
@@ -114,16 +114,44 @@
 .List;%0A%0A
+import rx.functions.Func1;%0A%0A
 import c
@@ -196,16 +196,73 @@
 ometry;%0A
+import com.github.davidmoten.rtree.geometry.HasGeometry;%0A
 import c
@@ -311,48 +311,8 @@
 gle;
-%0Aimport com.google.common.base.Optional;
 %0A%0Apu
@@ -591,191 +591,291 @@
 T%3E%3E 
-list
+nodes
 ) %7B%0A%09%09
-List%3CNode%3CT%3E%3E best = new ArrayList%3CNode%3CT%3E%3E();%0A%09%09Optional%3CDouble%3E bestMetric = Optional.absent();%0A%09%09for (Node%3CT%3E node : list) %7B%0A%09%09%09double m = 0;%0A%09%09%09for (Node%3CT%3E node2 : list
+return Collections.min(nodes, overlapComparator(r, nodes));%0A%09%7D%0A%0A%09private static Func1%3CHasGeometry, Double%3E overlap(final Rectangle r,%0A%09%09%09final List%3C? extends HasGeometry%3E list) %7B%0A%09%09return new Func1%3CHasGeometry, Double%3E() %7B%0A%0A%09%09%09@Override%0A%09%09%09public Double call(HasGeometry g
 ) %7B%0A
@@ -892,20 +892,17 @@
 gle 
-node
+g
 PlusR = 
 node
@@ -897,20 +897,17 @@
 PlusR = 
-node
+g
 .geometr
@@ -932,29 +932,83 @@
 %09%09%09%09
-if (node2 != node
+double m = 0;%0A%09%09%09%09for (HasGeometry other : list) %7B%0A%09%09%09%09%09if (other != g
 ) %7B%0A
+%09
 %09%09%09%09
@@ -1013,20 +1013,17 @@
 %09%09%09m += 
-node
+g
 PlusR.in
@@ -1041,13 +1041,13 @@
 rea(
-node2
+other
 .geo
@@ -1070,18 +1070,20 @@
 %09%09%09%09
+%09
 %7D%0A
+%09
 %09%09%09%7D%0A%09%09%09
 if (
@@ -1082,316 +1082,361 @@
 %0A%09%09%09
-if (!bestMetric.isPresent() %7C%7C m %3C bestMetric.get()) %7B%0A%09%09%09%09best = new ArrayList%3CNode%3CT%3E%3E();%0A%09%09%09%09best.add(node);%0A%09%09%09%09bestMetric = Optional.of(m);%0A%09%09%09%7D else if (bestMetric.isPresent() && m == bestMetric.get()) %7B%0A%09%09%09%09best.add(node);%0A%09%09%09%7D%0A%09%09%7D%0A%09%09return SelectorMinimalAreaIncrease.findMinimalAreaIncrease
+%09return m;%0A%09%09%09%7D%0A%09%09%7D;%0A%09%7D%0A%0A%09private static %3CT extends HasGeometry%3E Comparator%3CHasGeometry%3E overlapComparator(%0A%09%09%09final Rectangle r, final List%3CT%3E list) %7B%0A%09%09return new Comparator%3CHasGeometry%3E() %7B%0A%0A%09%09%09@Override%0A%09%09%09public int compare(HasGeometry g1, HasGeometry g2) %7B%0A%09%09%09%09return overlap(r, list).call(g1).compareTo(%0A%09%09%09%09%09%09overlap
 (r, 
-be
+li
 st)
+.call(g2));%0A%09%09%09%7D%0A%09%09%7D
 ;%0A%09%7D

refactor overlap