import math
import bob.io.base
import bob.ip.color
import bob.ip.facedetect
from . import Base, bounding_box_to_annotations


class BobIpFacedetect(Base):
    """Annotator using bob.ip.facedetect
    Provides topleft and bottomright annoations.

    Parameters
    ----------
    cascade : :any:`bob.ip.facedetect.Cascade`
        The file name, where a face detector cascade can be found. If ``None``,
        the default cascade for frontal faces
        :any:`bob.ip.facedetect.default_cascade` is used.

    detection_overlap : float
        See :any:`bob.ip.facedetect.detect_single_face`.

    distance : int
        See the Sampling section in the
        :ref:`Users Guide of bob.ip.facedetect <bob.ip.facedetect>`.

    scale_base : float
        See the Sampling section in the
        :ref:`Users Guide of bob.ip.facedetect <bob.ip.facedetect>`.

    lowest_scale : float
        See the Sampling section in the
        :ref:`Users Guide of bob.ip.facedetect <bob.ip.facedetect>`.

    eye_estimate : bool
        If ``True``, expected eye locations are added to the annotations.
    """

    def __init__(self, cascade=None,
                 detection_overlap=0.2, distance=2,
                 scale_base=math.pow(2., -1. / 16.), lowest_scale=0.125,
                 eye_estimate=False,
                 **kwargs):
        super(BobIpFacedetect, self).__init__(**kwargs)
        self.sampler = bob.ip.facedetect.Sampler(
            scale_factor=scale_base, lowest_scale=lowest_scale,
            distance=distance)
        if cascade is None:
            self.cascade = bob.ip.facedetect.default_cascade()
        else:
            self.cascade = bob.ip.facedetect.Cascade(
                bob.io.base.HDF5File(cascade))
        self.detection_overlap = detection_overlap
        self.eye_estimate = eye_estimate

    def annotate(self, image, **kwargs):
        """Return topleft and bottomright and expected eye positions

        Parameters
        ----------
        image : array
            Image in Bob format RGB image.
        **kwargs
            Ignored.

        Returns
        -------
        dict
            The annotations in a dictionary. The keys are topleft, bottomright,
            quality, leye, reye.
        """
        if image.ndim == 3:
            image = bob.ip.color.rgb_to_gray(image)
        bbx, quality = bob.ip.facedetect.detect_single_face(
            image, self.cascade, self.sampler, self.detection_overlap)

        landmarks = bounding_box_to_annotations(bbx)
        landmarks['quality'] = quality
        if self.eye_estimate:
            landmarks.update(bob.ip.facedetect.expected_eye_positions(bbx))

        return landmarks
