# Copyright 2014 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.

"""Classes to do screen capture."""

import logging

from PIL import Image

from autotest_lib.client.cros.multimedia import image_generator


def _unlevel(p):
    """Unlevel a color value from TV level back to PC level

    @param p: The color value in one character byte

    @return: The color value in integer in PC level
    """
    # TV level: 16~236; PC level: 0~255
    p = (p - 126) * 128 // 110 + 128
    if p < 0:
        p = 0
    elif p > 255:
        p = 255
    return p


class CommonChameleonScreenCapturer(object):
    """A class to capture the screen on Chameleon.

    Calling its member method capture() captures the screen.

    """
    TAG = 'Chameleon'

    def __init__(self, chameleon_port):
        """Initializes the CommonChameleonScreenCapturer objects."""
        self._chameleon_port = chameleon_port


    def capture(self):
        """Captures the screen.

        @return An Image object.
        """
        logging.info('Capturing the screen on Chameleon...')
        image = self._chameleon_port.capture_screen()

        # unleveling from TV level [16, 235]
        pmin, pmax = image_generator.ImageGenerator.get_extrema(image)
        if pmin > 10 and pmax < 240:
            logging.info(' (TV level: %d %d)', pmin, pmax)
            image = Image.eval(image, _unlevel)
        return image


class VgaChameleonScreenCapturer(object):
    """A class to capture the screen on a VGA port of Chameleon.

    Calling its member method capture() captures the screen.

    """
    TAG = 'Chameleon'

    def __init__(self, chameleon_port):
        """Initializes the VgaChameleonScreenCapturer objects."""
        self._chameleon_port = chameleon_port


    def capture(self):
        """Captures the screen.

        @return An Image object.
        """
        logging.info('Capturing the screen on a VGA port of Chameleon...')
        image = self._chameleon_port.capture_screen()

        # Find the box containing white points on its boundary.
        boundary = image.convert('L').point(
                lambda x: 255 if x >= 220 else 0).getbbox()
        logging.info('Boundary: %r', boundary)
        image = image.crop(boundary)
        return image


class CrosExternalScreenCapturer(object):
    """A class to capture the external screen on Chrome OS.

    Calling its member method capture() captures the screen.

    """
    TAG = 'CrOS-Ext'

    def __init__(self, display_facade):
        """Initializes the CrosExternalScreenCapturer objects."""
        self._display_facade = display_facade


    def capture(self):
        """Captures the screen.

        @return An Image object.
        """
        logging.info('Capturing the external screen on CrOS...')
        return self._display_facade.capture_external_screen()


class CrosInternalScreenCapturer(object):
    """A class to capture the internal screen on Chrome OS.

    Calling its member method capture() captures the screen.

    """
    TAG = 'CrOS-Int'

    def __init__(self, display_facade):
        """Initializes the CrosInternalScreenCapturer objects."""
        self._display_facade = display_facade


    def capture(self):
        """Captures the screen.

        @return An Image object.
        """
        logging.info('Capturing the internal screen on CrOS...')
        return self._display_facade.capture_internal_screen()


class CrosCalibrationImageCapturer(object):
    """A class to capture the calibration image on Chrome OS.

    Calling its member method capture() captures the image.

    """
    TAG = 'Calibration'

    def __init__(self, display_facade):
        """Initializes the CrosCalibrationImageCapturer objects."""
        self._display_facade = display_facade


    def capture(self):
        """Captures the screen.

        @return An Image object.
        """
        logging.info('Capturing the calibration image on CrOS...')
        return self._display_facade.capture_calibration_image()
