# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Import guard for OpenCV.
try:
    import cv
    import cv2
except ImportError:
    pass

import colorsys
import math
import numpy as np

# Color constants.
_COLORS = {
    'important': (0, 0, 255),
    'corner': (0, 255, 255),
    'success': (0, 255, 0),
    'deviation': (255, 0, 255),
    }

_UPSAMPLING_SCALE = 8
_UPSAMPLING_BITS = 3

def _DrawLineByAngle(img, origin, length, angle, color,
                     thickness):
    '''Draw a line by specifying the origin, length and angle.'''
    dx1 = length * math.cos(angle)
    dy1 = length * math.sin(angle)
    cv2.line(img, origin, (origin[0] + dx1, origin[1] + dy1), color,
             thickness, lineType=cv2.CV_AA)


def _DrawArrowTip(img, tip, direction, tip_length, tip_angle, color,
                  thickness):
    '''Draw an arrow tip.'''
    theta1 = math.radians(direction + 180 + tip_angle)
    _DrawLineByAngle(img, tip, tip_length, theta1, color, thickness)
    theta2 = math.radians(direction + 180 - tip_angle)
    _DrawLineByAngle(img, tip, tip_length, theta2, color, thickness)


def _DrawArcWithArrow(img, center, radius, start_angle, delta_angle,
                        tip_length, tip_angle, color, thickness):
    '''Draw an arc with an arrow tip on one end.'''
    # Draw arc.
    cv2.ellipse(img, center, (radius, radius), start_angle,
                (0 if delta_angle > 0 else -delta_angle),
                (-delta_angle if delta_angle > 0 else 0), color, thickness,
                lineType=cv2.CV_AA)

    # Draw arrow tip.
    # The minus sign is because the y axis is reversed for the actual image.
    tip_point_angle = -(start_angle + delta_angle)
    tip = (center[0] + radius * math.cos(math.radians(tip_point_angle)),
           center[1] + radius * math.sin(math.radians(tip_point_angle)))
    _DrawArrowTip(img, tip,
                  tip_point_angle - (90 if delta_angle > 0 else -90),
                  tip_length, tip_angle, color, thickness)


def DrawVC(img, success, result):
    '''Draw the result of the visual correctness test on the test image.'''
    if hasattr(result, 'sample_corners'):
        # Draw all corners.
        for point in result.sample_corners:
            cv2.circle(img, (point[0], point[1]), 2, _COLORS['corner'],
                       thickness=-1)

        if hasattr(result, 'shift'):
            # Draw the four corners of the corner grid.
            for point in result.four_corners:
                cv2.circle(img, (point[0], point[1]), 4,
                           _COLORS[('success' if success else 'important')],
                           thickness = -1, lineType=cv2.CV_AA)

            # Draw the center and the shift vector.
            center = ((img.shape[1] - 1) / 2.0, (img.shape[0] - 1) / 2.0)
            tip = np.array(center) + result.v_shift
            cv2.line(img, center, (tip[0], tip[1]),
                     _COLORS['deviation'], thickness=2, lineType=cv2.CV_AA)
            diag_len = math.sqrt(img.shape[0] ** 2 + img.shape[1] ** 2)
            angle = math.atan2(result.v_shift[1], result.v_shift[0])
            _DrawArrowTip(img, (tip[0], tip[1]), math.degrees(angle),
                          result.shift * diag_len * 0.3, 60,
                          _COLORS['deviation'], thickness=2)
            cv2.circle(img, center, 4,
                       _COLORS[('success' if success else 'important')],
                       thickness=-1, lineType=cv2.CV_AA)

            # Draw the rotation indicator.
            radius = max(img.shape) / 4
            # Boost the amount so it is more easily visible.
            angle = max(-90, min(90, result.tilt * 10))
            tip_length = abs(math.radians(angle)) * radius * 0.3
            tip_angle = 60
            _DrawArcWithArrow(img, center, radius, 0, angle,
                              tip_length, tip_angle,
                              _COLORS['deviation'], thickness=2)
            _DrawArcWithArrow(img, center, radius, 180, angle,
                              tip_length, tip_angle,
                              _COLORS['deviation'], thickness=2)


def _HSVToBGR(h, s, v, scale=255):
    '''Convert from the HSV color space to BGR.'''
    fc = colorsys.hsv_to_rgb(h, s, v)
    return tuple([int(round(x * scale)) for x in fc[::-1]])


def _Up(x):
    '''Encode floating point values in integers.'''
    return np.floor(x * _UPSAMPLING_SCALE + 0.5)


def DrawMTF(img, edges, perm, mtfs, crop_ratio, color_map_range):
    '''Draw the result of the image sharpness test on the test image.'''
    # Map MTF values to hue values.
    hues = ((mtfs - color_map_range[0]) /
            (color_map_range[1] - color_map_range[0])) / 3.0
    np.clip(hues, 0.0, 1.0/3, out=hues)

    # Draw the edges.
    for idx, edge_id in enumerate(perm):
        edge = edges[edge_id]
        start = (1 - crop_ratio) * edge[0:2] + crop_ratio * edge[2:4]
        end = crop_ratio * edge[0:2] + (1 - crop_ratio) * edge[2:4]
        cv2.line(img, tuple(_Up(start)), tuple(_Up(end)),
                 _HSVToBGR(hues[idx], 1.0, 1.0), thickness=2,
                 shift=_UPSAMPLING_BITS, lineType=cv2.CV_AA)
