import math

from .. import checker


class SearchDirection:
    def __init__(self, level, fixed_rgb):
        self.level = level
        self.target_ratio = checker.level_to_ratio(level)
        self.fixed_luminance = checker.relative_luminance(fixed_rgb)

    def round(self, ratio):
        return self._math_round(ratio * 10) / 10.0

    def has_sufficient_contrast(self, rgb):
        return self.contrast_ratio(rgb) >= self.target_ratio

    def contrast_ratio(self, rgb):
        luminance = checker.relative_luminance(rgb)
        return checker.luminance_to_contrast_ratio(self.fixed_luminance,
                                                   luminance)


class ToDarkerSide(SearchDirection):
    def __init__(self, level, fixed_rgb):
        super().__init__(level, fixed_rgb)
        self._math_round = math.floor

    def increment_condition(self, contrast_ratio):
        return contrast_ratio > self.target_ratio


class ToBrighterSide(SearchDirection):
    def __init__(self, level, fixed_rgb):
        super().__init__(level, fixed_rgb)
        self._math_round = math.ceil

    def increment_condition(self, contrast_ratio):
        return self.target_ratio > contrast_ratio


def threshold_criteria(level, fixed_rgb, other_rgb):
    if should_scan_darker_side(fixed_rgb, other_rgb):
        return ToDarkerSide(level, fixed_rgb)

    return ToBrighterSide(level, fixed_rgb)


def should_scan_darker_side(fixed_rgb, other_rgb):
    fixed_luminance = checker.relative_luminance(fixed_rgb)
    other_luminance = checker.relative_luminance(other_rgb)
    higher_luminance = fixed_luminance > other_luminance
    same_luminance = fixed_luminance == other_luminance
    is_light_color = checker.is_light_color(fixed_rgb)

    return higher_luminance or (is_light_color and same_luminance)

@@ -85,32 +85,44 @@
 level, fixed_rgb
+, math_round
 ):%0A        self.
@@ -257,24 +257,62 @@
 e(fixed_rgb)
+%0A        self._math_round = math_round
 %0A%0A    def ro
@@ -752,132 +752,8 @@
 n):%0A
-    def __init__(self, level, fixed_rgb):%0A        super().__init__(level, fixed_rgb)%0A        self._math_round = math.floor%0A%0A
     
@@ -894,131 +894,8 @@
 n):%0A
-    def __init__(self, level, fixed_rgb):%0A        super().__init__(level, fixed_rgb)%0A        self._math_round = math.ceil%0A%0A
     
@@ -1136,32 +1136,44 @@
 level, fixed_rgb
+, math.floor
 )%0A%0A    return To
@@ -1201,16 +1201,27 @@
 ixed_rgb
+, math.ceil
 )%0A%0A%0Adef 

simplify the implementation of threshold_finder.criteria.SearchDirection and its subclasses