#!/usr/bin/env python2
# 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.

# Description:
#
# Class for injecting input events to linux 'evdev' input devices.
#
# Provides evemu-play-like functionality if run from the command line:
# $ input_event_player.py -d /dev/input/event6

""" Playback input events on a linux input device. """

import glob
import os.path
import re
import time

from input_device import InputDevice, InputEvent
from optparse import OptionParser


class InputEventPlayer:
    """ Linux evdev input event player.

    An "evdev" input event player injects a stream of "input events" to kernel
    evdev driver. With this player, we could easily playback an input event file
    which was recorded with the tool evemu-record previously.

    """

    def __init__(self):
        self.tv_sec = None
        self.tv_usec = None

    def playback(self, device, gesture_file):
        """ Play the events in gesture_file on device.

        Keyword arguments:
        device -- the InputDevice device object
        gesture_file -- the name of the event file recorded previously
        """
        if not device:
            raise
        event_str = 'E: (\d+)\.(\d+) ([0-9a-f]{4}) ([0-9a-f]{4}) ([-]?\d+)'
        event_pattern = re.compile(event_str)
        for line in open(gesture_file, 'rt'):
            m = event_pattern.match(line)
            if not m:
                raise
            event = InputEvent(int(m.group(1)),
                               int(m.group(2)),
                               int(m.group(3), 16),
                               int(m.group(4), 16),
                               int(m.group(5)))
            if not self.tv_sec:
                self.tv_sec = event.tv_sec
                self.tv_usec = event.tv_usec
            delta = event.tv_sec - self.tv_sec
            delta += ((event.tv_usec - self.tv_usec) / 1000000.0)
            # Sleep only if the event is 0.05 ms later than the previous one
            if delta > 0.0000500:
                time.sleep(delta)
            self.tv_sec = event.tv_sec
            self.tv_usec = event.tv_usec
            event.write(device.f)


if __name__ == '__main__':
    parser = OptionParser()

    parser.add_option('-d', '--devpath', dest='devpath', default='',
                      help='device path (/dev/input/event0)')
    parser.add_option('-t', '--touchpad', action='store_true', dest='touchpad',
                      default=False, help='Find and use first touchpad device')
    parser.add_option('-f', '--file', action='store', dest='gesture_file',
                      help='Event file to playback')
    (options, args) = parser.parse_args()

    if options.touchpad:
        for evdev in glob.glob('/dev/input/event*'):
            device = InputDevice(evdev)
            if device.is_touchpad():
                break
        else:
            print 'Can not find a touchpad device'
            exit()
    elif not os.path.exists(options.devpath):
        print 'Can not find the input device "%s".' % options.devpath
        exit()
    else:
        device = InputDevice(options.devpath)
    if not options.gesture_file:
        print 'Gesture file is not specified.'
        exit()
    if not os.path.exists(options.gesture_file):
        print 'Can not find the gesture file %s.' % options.gesture_file
        exit()

    InputEventPlayer().playback(device, options.gesture_file)
    print 'Gesture file %s has been played.' % options.gesture_file
