package io.fotoapparat.parameter.selector;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;

import io.fotoapparat.parameter.range.Range;
import io.fotoapparat.util.CompareFpsRangeByBounds;
import io.fotoapparat.util.ExactFpsRangePredicate;
import io.fotoapparat.util.InBoundsFpsRangePredicate;

import static io.fotoapparat.parameter.selector.Selectors.filtered;
import static io.fotoapparat.parameter.selector.Selectors.firstAvailable;

/**
 * Selector functions for preview FPS ranges.
 */
public class PreviewFpsRangeSelectors {

    private static final Comparator<Range<Integer>> COMPARATOR_BY_BOUNDS = new CompareFpsRangeByBounds();

    /**
     * For conversion fps to FPS range bound
     */
    private static final int FPS_RANGE_BOUNDS_SCALE = 1000;

    /**
     * @param fps the specified FPS
     * @return {@link SelectorFunction} which selects FPS range that contains only the specified FPS.
     */
    public static SelectorFunction<Range<Integer>> fromExactFps(Integer fps) {
        return filtered(biggestFpsRange(),
                new ExactFpsRangePredicate(fps * FPS_RANGE_BOUNDS_SCALE));
    }

    /**
     * @param fps the specified FPS
     * @return {@link SelectorFunction} which selects FPS range that contains the specified FPS.
     */
    public static SelectorFunction<Range<Integer>> nearestToExactFps(Integer fps) {
        return firstAvailable(fromExactFps(fps),
                filtered(biggestFpsRange(), new InBoundsFpsRangePredicate(fps * FPS_RANGE_BOUNDS_SCALE)));
    }

    /**
     * @return {@link SelectorFunction} which selects FPS range with max FPS.
     */
    public static SelectorFunction<Range<Integer>> biggestFpsRange() {
        return new SelectorFunction<Range<Integer>>() {
            @Override
            public Range<Integer> select(Collection<Range<Integer>> items) {
                if (items.isEmpty()) {
                    return null;
                }

                return Collections.max(items, COMPARATOR_BY_BOUNDS);
            }
        };
    }

    /**
     * @return {@link SelectorFunction} which selects FPS range with min FPS.
     */
    public static SelectorFunction<Range<Integer>> lowestFpsRange() {
        return new SelectorFunction<Range<Integer>>() {
            @Override
            public Range<Integer> select(Collection<Range<Integer>> items) {
                if (items.isEmpty()) {
                    return null;
                }

                return Collections.min(items, COMPARATOR_BY_BOUNDS);
            }
        };
    }

}

@@ -1006,39 +1006,35 @@
 %3E%3E fromExactFps(
-I
+i
 nt
-eger
  fps) %7B%0A        
@@ -1368,23 +1368,19 @@
 xactFps(
-I
+i
 nt
-eger
  fps) %7B%0A

Use primitive type for null-safety