# -*- coding: utf-8 -*-
#
# Copyright (c) 2010 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.


# DESCRIPTION :
#
# This test searches for a v4l2 video capture device, and starts streaming
# captured frames on the monitor.
# The observer then decides if the captured image looks good or defective,
# pressing enter key to let it pass or tab key to fail.
#
# Then the test will start to test the LED indicator located near the webcam.
# The LED test will be repeated for a fixed number (=5 at time of writing)
# of rounds, each round it will randomly decide whether to capture from the
# cam (the LED turns on when capturing). The captured image will NOT be
# shown on the monitor, so the observer must answer what he really sees.
# The test passes only if the answer for all rounds are correct.


# The current configuration of buildbot will try to compile Python
# files for the remote test purpose. Since this is done on the host,
# it can't use any library that is not installed there even if the
# library might be available on the target. We currently do not have
# OpenCV on the host so we have to try-catch the import in order to
# avoid the compilation error.
#
# TODO: Fix it either when we have OpenCV on the host or the build
#       configuration for Python files in the autotest changes.

try:
    import cv
    import cv2
except ImportError:
    # We can't raise error because it will fail the interpreter.
    pass

import gtk
import glib
import pango
import numpy
import time

from gtk import gdk
from random import randrange

from autotest_lib.client.cros import factory
from autotest_lib.client.cros.factory import ui as ful
from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error

# OpenCV will automatically search for a working camera device if we use the
# index -1.
DEVICE_INDEX = -1

PREFERRED_FPS = 30
PREFERRED_INTERVAL = int(round(1000.0 / PREFERRED_FPS))
FPS_UPDATE_FACTOR = 0.1

GDK_PIXBUF_BIT_PER_SAMPLE = 8

KEY_GOOD = gdk.keyval_from_name('Return')
KEY_BAD = gdk.keyval_from_name('Tab')

LABEL_FONT = pango.FontDescription('courier new condensed 16')

MESSAGE_STR = ('hit TAB to fail and ENTER to pass\n' +
               '錯誤請按 TAB，成功請按 ENTER\n')
MESSAGE_STR2 = ('hit TAB if the LED is off and ENTER if the LED is on\n' +
                '請檢查攝像頭 LED 指示燈, 沒亮請按 TAB, 燈亮請按 ENTER\n')


class factory_Camera(test.test):
    version = 1

    def key_release_callback(self, widget, event):
        factory.log('key_release_callback %s(%s)' %
                    (event.keyval, gdk.keyval_name(event.keyval)))
        if event.keyval == KEY_GOOD or event.keyval == KEY_BAD:
            if self.stage == 0:
                self.capture_stop()
                if event.keyval == KEY_BAD:
                    gtk.main_quit()
                self.img.hide()
                self.label.set_text(MESSAGE_STR2)
            else:
                if self.ledstats & 1:
                    self.capture_stop()
                if bool(self.ledstats & 1) != (event.keyval == KEY_GOOD):
                    self.ledfail = True
                self.ledstats >>= 1
            if self.stage == self.led_rounds:
                self.fail = False
                gtk.main_quit()
            self.stage += 1
            if self.ledstats & 1:
                self.capture_start()
            self.label.hide()
            glib.timeout_add(1000, lambda *x: self.label.show())
        return True

    def capture_core(self):
        '''Captures an image and displays it

        The FPS is determined by the camera hardware limit, the gtk display
        overhead and the amount of memory copy operations. This subroutine
        involves 3 copy operations of image data which usually takes less than
        10 ms on an average machine.
        '''
        # Read image from camera.
        ret, cvImg = self.dev.read()
        if not ret:
            raise IOError("Error while capturing. Camera disconnected?")

        # Convert from BGR to RGB in-place.
        cv2.cvtColor(cvImg, cv.CV_BGR2RGB, cvImg)

        # Convert to gdk pixbuf format.
        pbuf = gdk.pixbuf_new_from_data(cvImg.data,
            gdk.COLORSPACE_RGB, False, GDK_PIXBUF_BIT_PER_SAMPLE,
            cvImg.shape[1], cvImg.shape[0], cvImg.strides[0])

        # Copy to the display buffer.
        pbuf.copy_area(0, 0, pbuf.get_width(), pbuf.get_height(), self.pixbuf,
                       0, 0)

        # Queue for refreshing.
        self.img.queue_draw()

        # Update FPS if required.
        if self.show_fps:
            current_time = time.clock()
            self.current_fps = (self.current_fps * (1 - FPS_UPDATE_FACTOR) +
                                1.0 / (current_time - self.last_capture_time) *
                                FPS_UPDATE_FACTOR)
            self.last_capture_time = current_time

            self.label.set_text(MESSAGE_STR2 +
                                'FPS = ' + '%.2f\n' % self.current_fps)

        return True

    def register_callbacks(self, w):
        w.connect('key-release-event', self.key_release_callback)
        w.add_events(gdk.KEY_RELEASE_MASK)

    def capture_start(self):
        # Register the image capturing subroutine using glib.
        # It will be called every PREFERRED_INTERVAL time.
        self.gio_tag = glib.timeout_add( PREFERRED_INTERVAL,
            lambda *x:self.capture_core(),
            priority=glib.PRIORITY_LOW)

    def capture_stop(self):
        # Unregister the image capturing subroutine.
        glib.source_remove(self.gio_tag)

    def run_once(self,
                 led_rounds=1, show_fps=False):
        '''Run the camera test

        Parameter
          led_rounds: 0 to disable the LED test,
                      1 to check if the LED turns on,
                      2 or higher to have multiple random turn on/off
                      (at least one on round and one off round is guranteed)
        '''
        factory.log('%s run_once' % self.__class__)

        self.fail = True
        self.ledfail = False
        self.led_rounds = led_rounds
        self.ledstats = 0
        if led_rounds == 1:
            # Always on if only one round.
            self.ledstats = 1
        elif led_rounds > 1:
            # Ensure one on round and one off round.
            self.ledstats = randrange(2 ** led_rounds - 2) + 1
        self.show_fps = show_fps
        self.stage = 0

        self.label = label = gtk.Label(MESSAGE_STR)
        label.modify_font(LABEL_FONT)
        label.modify_fg(gtk.STATE_NORMAL, gdk.color_parse('light green'))

        test_widget = gtk.VBox()
        test_widget.modify_bg(gtk.STATE_NORMAL, gdk.color_parse('black'))
        test_widget.add(label)
        self.test_widget = test_widget

        self.img = None

        # Initialize the camera with OpenCV.
        self.dev = dev = cv2.VideoCapture(DEVICE_INDEX)
        if not dev.isOpened():
            raise IOError('Device #%s ' % DEVICE_INDEX +
                             'does not support video capture interface')

        width, height = (dev.get(cv.CV_CAP_PROP_FRAME_WIDTH),
                dev.get(cv.CV_CAP_PROP_FRAME_HEIGHT))

        # Initialize the canvas.
        self.pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, False, 8,
            width, height)
        self.img = gtk.image_new_from_pixbuf(self.pixbuf)
        self.test_widget.add(self.img)
        self.img.show()

        if self.show_fps:
            self.last_capture_time = time.clock()
            self.current_fps = PREFERRED_FPS

        self.capture_start()

        ful.run_test_widget(self.job, test_widget,
            window_registration_callback=self.register_callbacks)

        if self.fail:
            raise error.TestFail('Camera test failed by user indication\n' \
                                 '品管人員懷疑攝影鏡頭故障，請檢修')
        if self.ledfail:
            raise error.TestFail('Camera LED test failed\n' \
                                 '攝影鏡頭 LED 測試不通過，請檢修')

        factory.log('%s run_once finished' % self.__class__)
