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

"""This module provides GUI for touch device firmware test using GTK."""

import re

import gobject
import gtk
import gtk.gdk
import pango

import firmware_utils
import test_conf as conf

from firmware_constants import TFK


TITLE = "Touch Firmware Test"


class BaseFrame(object):
    """A simple base frame class."""
    def __init__(self, label=None, size=None, aspect=False):
        # Create a regular/aspect frame
        self.frame = gtk.AspectFrame() if aspect else gtk.Frame()
        self.frame.set_shadow_type(gtk.SHADOW_ETCHED_OUT)
        self.size = size
        if label:
            self.frame.set_label(label)
            self.frame.set_label_align(0.0, 0.0)
            frame_label = self.frame.get_label_widget()
            markup_str = '<span foreground="%s" size="x-large">%s</span>'
            frame_label.set_markup(markup_str % ('black', label))
        if size:
            width, height = size
            self.frame.set_size_request(width, height)
            if aspect:
                self.frame.set(ratio=(float(width) / height))


class PromptFrame(BaseFrame):
    """A simple frame widget to display the prompt.

    It consists of:
      - A frame
      - a label showing the gesture name
      - a label showing the prompt
      - a label showing the keyboard interactions
    """

    def __init__(self, label=None, size=None):
        super(PromptFrame, self).__init__(label, size)

        # Create a vertical packing box.
        self.vbox = gtk.VBox(False, 0)
        self.frame.add(self.vbox)

        # Create a label to show the gesture name
        self.label_gesture = gtk.Label('Gesture Name')
        self.label_gesture.set_justify(gtk.JUSTIFY_LEFT)
        self.vbox.pack_start(self.label_gesture, True, True, 0)
        # Expand the lable to be wider and wrap the line if necessary.
        if self.size:
            _, label_height = self.label_gesture.get_size_request()
            width, _ = self.size
            label_width = int(width * 0.9)
            self.label_gesture.set_size_request(label_width, label_height)
        self.label_gesture.set_line_wrap(True)

        # Pack a horizontal separator
        self.vbox.pack_start(gtk.HSeparator(), True, True, 0)

        # Create a label to show the prompt
        self.label_prompt = gtk.Label('Prompt')
        self.label_prompt.set_justify(gtk.JUSTIFY_CENTER)
        self.vbox.pack_start(self.label_prompt, True, True, 0)

        # Create a label to show the choice
        self.label_choice = gtk.Label('')
        self.label_choice.set_justify(gtk.JUSTIFY_LEFT)
        self.vbox.pack_start(self.label_choice, True, True, 0)

        # Show all widgets added to this frame
        self.frame.show_all()

    def set_gesture_name(self, string, color='blue'):
        """Set the gesture name in label_gesture."""
        markup_str = '<b><span foreground="%s" size="xx-large"> %s </span></b>'
        self.label_gesture.set_markup(markup_str % (color, string))

    def set_prompt(self, string, color='black'):
        """Set the prompt in label_prompt."""
        markup_str = '<span foreground="%s" size="x-large"> %s </span>'
        self.label_prompt.set_markup(markup_str % (color, string))

    def set_choice(self, string):
        """Set the choice in label_choice."""
        self.label_choice.set_text(string)


class ResultFrame(BaseFrame):
    """A simple frame widget to display the test result.

    It consists of:
      - A frame
      - a scrolled window
      - a label showing the test result
    """
    SCROLL_STEP = 100.0

    def __init__(self, label=None, size=None):
        super(ResultFrame, self).__init__(label, size)

        # Create a scrolled window widget
        self.scrolled_window = gtk.ScrolledWindow()
        self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
                                        gtk.POLICY_AUTOMATIC)
        self.frame.add(self.scrolled_window)

        # Create a vertical packing box.
        self.vbox = gtk.VBox(False, 0)
        self.scrolled_window.add_with_viewport(self.vbox)

        # Create a label to show the gesture name
        self.result = gtk.Label()
        self.vbox.pack_start(self.result , False, False, 0)

        # Show all widgets added to this frame
        self.frame.show_all()

        # Get the vertical and horizontal adjustments
        self.vadj = self.scrolled_window.get_vadjustment()
        self.hadj = self.scrolled_window.get_hadjustment()

        self._scroll_func_dict = {TFK.UP: self._scroll_up,
                                  TFK.DOWN: self._scroll_down,
                                  TFK.LEFT: self._scroll_left,
                                  TFK.RIGHT: self._scroll_right}

    def _calc_result_font_size(self):
        """Calculate the font size so that it does not overflow."""
        label_width_in_px, _ = self.size
        font_size = int(float(label_width_in_px) / conf.num_chars_per_row *
                        pango.SCALE)
        return font_size

    def set_result(self, text, color='black'):
        """Set the text in the result label."""
        mod_text = re.sub('<', '&lt;', text)
        mod_text = re.sub('>', '&gt;', mod_text)
        markup_str = '<b><span foreground="%s" size="%d"> %s </span></b>'
        font_size = self._calc_result_font_size()
        self.result.set_markup(markup_str % (color, font_size, mod_text))

    def _calc_inc_value(self, adj):
        """Calculate new increased value of the specified adjustement object."""
        value = adj.get_value()
        new_value = min(value + self.SCROLL_STEP, adj.upper - adj.page_size)
        return new_value

    def _calc_dec_value(self, adj):
        """Calculate new decreased value of the specified adjustement object."""
        value = adj.get_value()
        new_value = max(value - self.SCROLL_STEP, adj.lower)
        return new_value

    def _scroll_down(self):
        """Scroll the scrolled_window down."""
        self.vadj.set_value(self._calc_inc_value(self.vadj))

    def _scroll_up(self):
        """Scroll the scrolled_window up."""
        self.vadj.set_value(self._calc_dec_value(self.vadj))

    def _scroll_right(self):
        """Scroll the scrolled_window to the right."""
        self.hadj.set_value(self._calc_inc_value(self.hadj))

    def _scroll_left(self):
        """Scroll the scrolled_window to the left."""
        self.hadj.set_value(self._calc_dec_value(self.hadj))

    def scroll(self, choice):
        """Scroll the result frame using the choice key."""
        scroll_method = self._scroll_func_dict.get(choice)
        if scroll_method:
            scroll_method()
        else:
            print 'Warning: the key choice "%s" is not legal!' % choice


class ImageFrame(BaseFrame):
    """A simple frame widget to display the mtplot window.

    It consists of:
      - An aspect frame
      - an image widget showing mtplot
    """

    def __init__(self, label=None, size=None):
        super(ImageFrame, self).__init__(label, size, aspect=True)

        # Use a fixed widget to display the image.
        self.fixed = gtk.Fixed()
        self.frame.add(self.fixed)

        # Create an image widget.
        self.image = gtk.Image()
        self.fixed.put(self.image, 0, 0)

        # Show all widgets added to this frame
        self.frame.show_all()

    def set_from_file(self, filename):
        """Set the image file."""
        self.image.set_from_file(filename)
        self.frame.show_all()


class FirmwareWindow(object):
    """A simple window class to display the touch firmware test window."""

    def __init__(self, size=None, prompt_size=None, result_size=None,
                 image_size=None):

        # Create a new window
        self.win = gtk.Window(gtk.WINDOW_TOPLEVEL)
        if size:
            self.win_size = size
            self.win.resize(*size)
        self.win.set_title(TITLE)
        self.win.set_border_width(0)

        # Create the prompt frame
        self.prompt_frame = PromptFrame(TITLE, prompt_size)

        # Create the result frame
        self.result_frame = ResultFrame("Test results:", size=result_size)

        # Create the image frame for mtplot
        self.image_frame = ImageFrame(size=image_size)

        # Handle layout below
        self.box0 = gtk.VBox(False, 0)
        self.box1 = gtk.HBox(False, 0)
        # Arrange the layout about box0
        self.win.add(self.box0)
        self.box0.pack_start(self.prompt_frame.frame, True, True, 0)
        self.box0.pack_start(self.box1, True, True, 0)
        # Arrange the layout about box1
        self.box1.pack_start(self.image_frame.frame, True, True, 0)
        self.box1.pack_start(self.result_frame.frame, True, True, 0)

        # Capture keyboard events.
        self.win.add_events(gtk.gdk.KEY_PRESS_MASK | gtk.gdk.KEY_RELEASE_MASK)

        # Set a handler for delete_event that immediately exits GTK.
        self.win.connect("delete_event", self.delete_event)

        # Show all widgets.
        self.win.show_all()

    def register_callback(self, event, callback):
        """Register a callback function for an event."""
        self.win.connect(event, callback)

    def register_timeout_add(self, callback, timeout):
        """Register a callback function for gobject.timeout_add."""
        return gobject.timeout_add(timeout, callback)

    def register_io_add_watch(self, callback, fd, data=None,
                              condition=gobject.IO_IN):
        """Register a callback function for gobject.io_add_watch."""
        if data:
            return gobject.io_add_watch(fd, condition, callback, data)
        else:
            return gobject.io_add_watch(fd, condition, callback)

    def create_key_press_event(self, keyval):
        """Create a key_press_event."""
        event = gtk.gdk.Event(gtk.gdk.KEY_PRESS)
        # Assign current time to the event
        event.time = 0
        event.keyval = keyval
        self.win.emit('key_press_event', event)

    def remove_event_source(self, tag):
        """Remove the registered callback."""
        gobject.source_remove(tag)

    def delete_event(self, widget, event, data=None):
        """A handler to exit the window."""
        self.stop()
        return False

    def set_input_focus(self):
        """Set input focus to this window."""
        x = firmware_utils.SimpleX(TITLE)
        x.set_input_focus()

    def set_gesture_name(self, string, color='blue'):
        """A helper method to set gesture name."""
        self.prompt_frame.set_gesture_name(string, color)

    def set_prompt(self, string, color='black'):
        """A helper method to set the prompt."""
        self.prompt_frame.set_prompt(string, color)

    def set_choice(self, string):
        """A helper method to set the choice."""
        self.prompt_frame.set_choice(string)

    def set_result(self, text):
        """A helper method to set the text in the result."""
        self.result_frame.set_result(text)

    def set_image(self, filename):
        """Set an image in the image frame."""
        self.image_frame.set_from_file(filename)

    def scroll(self, choice):
        """Scroll the result frame using the choice key."""
        self.result_frame.scroll(choice)

    def stop(self):
        """Quit the window."""
        gtk.main_quit()

    def main(self):
        """Main function of the window."""
        gtk.main()
