# Copyright (c) 2011 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.

''' A module for parsing X events and manipulating X Button labels '''

import logging
import math
import os
import re

import constants
import trackpad_util

from common_util import simple_system, simple_system_output


# Declare X property names
X_PROP_SCROLL_BUTTONS = 'Scroll Buttons'
X_PROP_TAP_ENABLE = 'Tap Enable'

# Declare NOP as a instance containing NOP related constants
NOP = constants.NOP()


class Xinput(object):
    ''' Manipulation of xinput properties

    An example usage for instantiating a trackpad xinput device:
    xi = Xinput('t(?:ouch|rack)pad')
    '''

    def __init__(self, device_re_str):
        self.device_re_str = device_re_str
        self.xinput_str = 'DISPLAY=:0 xinput %s'

        # list command looks like
        #   DISPLAY=:0 xinput list
        self.xinput_list_cmd = self.xinput_str % 'list'
        self.dev_id = self.lookup_device_id()

        # list-props command looks like
        #   DISPLAY=:0 xinput list-props 11
        list_props_str = 'list-props %s' % self.dev_id
        self.xinput_list_props_cmd = self.xinput_str % list_props_str

    def device_exists(self):
        ''' Indicating whether the device exists or not. '''
        return self.dev_id is not None

    def lookup_device_id(self):
        ''' Look up device id with the specified device string

        For example, a trackpad device looks like
        SynPS/2 Synaptics TouchPad         id=11   [slave  pointer  (2)]
        '''
        dev_patt_str = '%s\s*id=(\d+)\s*\[' % self.device_re_str
        dev_patt = re.compile(dev_patt_str, re.I)
        dev_list = simple_system_output(self.xinput_list_cmd)
        if dev_list:
            for line in dev_list.splitlines():
                result = dev_patt.search(line)
                if result is not None:
                    return result.group(1)
        return None

    def lookup_int_prop_id_and_value(self, prop_name):
        ''' Look up integer property id based on property name

        For example, a property looks like
        Scroll Buttons (271):   0
        '''
        prop_re_str = '\s*%s\s*\((\d+)\):\s*(\d+)' % prop_name
        prop_patt = re.compile(prop_re_str, re.I)
        prop_list = simple_system_output(self.xinput_list_props_cmd)
        if prop_list:
            for line in prop_list.splitlines():
                result = prop_patt.search(line)
                if result:
                    return (result.group(1), int(result.group(2)))
        return (None, None)

    def set_int_prop_value(self, prop_id, prop_val):
        ''' Set integer property value

        For example, to enable Scroll Buttons (id=271) at device 11
        DISPLAY=:0 xinput set-prop 11 271 1
        '''
        # set-prop command looks like
        #   DISPLAY=:0 xinput set-prop 11 271 1
        set_int_prop_str = 'set-prop %s %s %d' % (self.dev_id, prop_id,
                                                  prop_val)
        self.xinput_set_int_prop_cmd = self.xinput_str % set_int_prop_str
        simple_system(self.xinput_set_int_prop_cmd)


class XIntProp(Xinput):
    ''' A special class to manipulate xinput Int Property. '''

    def __init__(self, prop_name):
        ''' Look up the id and value of the X int property '''
        self.name = prop_name
        super(XIntProp, self).__init__(self._get_trackpad_re_str())
        # Look up the property only when the device exists
        if self.device_exists():
            prop_result = self.lookup_int_prop_id_and_value(prop_name)
            self.prop_id, self.orig_prop_val = prop_result
        else:
            self.prop_id = self.orig_prop_val = None

    def _get_trackpad_re_str(self):
        xinput_trackpad_string = trackpad_util.read_trackpad_test_conf(
            'xinput_trackpad_string', '.')
        return '(?:%s)' % '|'.join(xinput_trackpad_string)

    def exists(self):
        ''' Indicating whether the property exists or not. '''
        return self.prop_id is not None

    def set_prop(self):
        ''' Enable the int property if it is not enabled yet. '''
        if self.orig_prop_val == 0:
            self.set_int_prop_value(self.prop_id, 1)

    def reset_prop(self):
        ''' Disable the int property if it was originally disabled. '''
        if self.orig_prop_val == 0:
            self.set_int_prop_value(self.prop_id, 0)


def set_x_input_prop(prop_name):
    ''' Enable the specified property if it is not enabled yet. '''
    prop = XIntProp(prop_name)
    if prop.exists():
        prop.set_prop()
        logging.info('  The property %s has been set.' % prop_name)
    else:
        logging.info('  The property %s does not exist.' % prop_name)
    return prop


def reset_x_input_prop(prop):
    ''' Disable the specified property if it was originally disabled. '''
    if prop.exists():
        prop.reset_prop()
        logging.info('  The property %s has been reset.' % prop.name)


class XButton:
    ''' Manipulation of X Button labels and values '''

    # Define some common X button values
    Left = 1
    Middle = 2
    Right = 3
    Wheel_Up = 4
    Wheel_Down = 5
    Wheel_Left = 6
    Wheel_Right = 7
    Mouse_Wheel_Up = 8
    Mouse_Wheel_Down = 9
    DEFAULT_BUTTON_LABELS = ('Button Left', 'Button Middle', 'Button Right',
                             'Button Back', 'Button Forward')

    def __init__(self):
        self.display_environ = trackpad_util.Display().get_environ()
        self.xinput_list_cmd = ' '.join([self.display_environ, 'xinput list'])
        self.xinput_dev_cmd = ' '.join([self.display_environ,
                                        'xinput list --long %s'])
        self.trackpad_dev_id = self._get_trackpad_dev_id()
        self.button_labels = None
        self.get_supported_buttons()

    def _get_trackpad_dev_id(self):
        trackpad_dev_id = None
        if os.system('which xinput') == 0:
            input_dev_str = simple_system_output(self.xinput_list_cmd)
            for dev_str in input_dev_str.splitlines():
                res = re.search(r'(t(ouch|rack)pad\s+id=)(\d+)', dev_str, re.I)
                if res is not None:
                    trackpad_dev_id = res.group(3)
                    break
        return trackpad_dev_id

    def get_supported_buttons(self):
        ''' Get supported button labels from xinput

        a device returned from 'xinput list' looks like:
        |   SynPS/2 Synaptics TouchPad       id=11   [slave  pointer (2)]

        Button labels returned from 'xinput list <device_id>' looks like:
        Button labels: Button Left Button Middle Button Right Button Wheel Up
        Button Wheel Down Button Horiz Wheel Left Button Horiz Wheel Right
        Button 0 Button 1 Button 2 Button 3 Button 4 Button 5 Button 6
        Button 7
        '''

        if self.button_labels is not None:
            return self.button_labels

        if self.trackpad_dev_id is not None:
            xinput_dev_cmd = self.xinput_dev_cmd % self.trackpad_dev_id
            features = simple_system_output(xinput_dev_cmd)
            if features is not None:
                button_labels_list = [line.lstrip().lstrip('Button labels:')
                    for line in features.splitlines()
                    if line.lstrip().startswith('Button labels:')]
                button_labels = button_labels_list[0]
                self.button_labels = tuple(['Button ' + b.strip() for b in
                                            button_labels.split('Button') if b])

        if self.button_labels is None:
            logging.warn('Cannot find trackpad device in xinput. '
                         'Using default Button Labels instead.')
            self.button_labels = self.DEFAULT_BUTTON_LABELS

        logging.info('Button Labels (%d) in the trackpad: %s' %
                     (len(self.button_labels), self.button_labels))

        return self.button_labels

    def get_value(self, button_label):
        ''' Mapping an X button label to an X button value

        For example, 'Button Left' returns 1
                     'Button Wheel Up' returns 4
                     'Button Wheel Down' returns 5
        '''
        return self.button_labels.index(button_label) + 1

    def get_label(self, button_value):
        ''' Mapping an X button value to an X button label

        For example, 1 returns 'Button Left'
                     4 returns 'Button Wheel Up'
                     5 returns 'Button Wheel Down'
        '''
        return self.button_labels[button_value - 1]

    def get_index(self, button_label):
        ''' Mapping an X button label to its index in a button tuple

        Generally, a button index is equal to its button value decreased by 1.
        For example, 'Button Left' returns 0
                     'Button Wheel Up' returns 3
                     'Button Wheel Down' returns 4
        '''
        return self.button_labels.index(button_label)

    def init_button_struct(self, value):
        ''' Initialize a button dictionary to the given values. '''
        return dict(map(lambda b: (self.get_value(b), value),
                                  self.button_labels))

    def init_button_struct_with_time(self, value, time):
        ''' Initialize a button dictionary with time to the given values. '''
        return dict(map(lambda b: (self.get_value(b), [value, list(time)]),
                        self.button_labels))

    def is_button_wheel(self, button_label):
        '''  Is this button a wheel button? '''
        return button_label in ['Button Wheel Up',
                                'Button Wheel Down',
                                'Button Horiz Wheel Left',
                                'Button Horiz Wheel Right']


class XEvent:
    ''' A class for X event parsing '''

    def __init__(self, xbutton):
        self.xbutton = xbutton
        # Declare the format to extract information from X event structures
        self.raw_format_dict = {
            'Motion_coord'  : '{6}',
            'Motion_time'   : '{5}',
            'Motion_tv'     : '{7}',
            'Button_coord'  : '{6}',
            'Button_button' : '{3}',
            'Button_time'   : '{5}',
            'Button_tv'     : '{7}',
        }
        self.motion_trace_before = trackpad_util.read_trackpad_test_conf(
            'motion_trace_before', '.')
        self.motion_trace_after = trackpad_util.read_trackpad_test_conf(
            'motion_trace_after', '.')
        self.LONG_MOTIOIN_TRACE = trackpad_util.read_trackpad_test_conf(
            'LONG_MOTION_TRACE', '.')

    def _extract_prop(self, event_name, line, prop_key):
        ''' Extract property from X events '''
        if line is None:
            logging.warn('      X event format may not be correct.')
            return None

        event_format_str = self.raw_format_dict[event_name]
        try:
            prop_val = event_format_str.format(*line.strip().split()).strip(',')
        except IndexError, err:
            logging.warn('      %s in X event data.' % str(err))
            return None
        return (prop_key, prop_val)

    def _calc_distance(self, x0, y0, x1, y1):
        ''' A simple Manhattan distance '''
        delta_x = abs(x1 - x0)
        delta_y = abs(y1 - y0)
        dist = round(math.sqrt(delta_x * delta_x + delta_y * delta_y))
        return [dist, [delta_x, delta_y]]

    def parse_raw_string(self, xevent_str):
        ''' Parse X raw event string

        The event information of a single X event may span across multiple
        lines. This function extracts the important event information of
        an event into a dictionary so that it is easier to process in
        subsequent stages.

        For example:
        A MotionNotify event looks like:
            MotionNotify event, serial 25, synthetic NO, window 0xa00001,
                root 0xab, subw 0x0, time 925196, (750,395), root:(750,395),
                state 0x0, is_hint 0, same_screen YES

        A ButtonPress event looks like:
            ButtonPress event, serial 25, synthetic NO, window 0xa00001,
                root 0xab, subw 0x0, time 1098904, (770,422), root:(770,422),
                state 0x0, button 1, same_screen YES

        The property extracted for the MotionNotify event looks like:
            ['MotionNotify', {'coord': (150,200), 'time': ...]

        The property extracted for the ButtonPress event looks like:
            ['ButtonPress', {'coord': (150,200), 'button': 5}, 'time': ...]
        '''

        if not xevent_str:
            logging.warn('    No X events were captured.')
            return False

        xevent_iter = iter(xevent_str)
        self.xevent_data = []
        while True:
            line = next(xevent_iter, None)
            if line is None:
                break
            line_words = line.split()
            if not line_words:
                continue
            event_name = line_words[0]

            # Extract event information for important event types
            if event_name == 'MotionNotify' or event_name == 'EnterNotify':
                line1 = next(xevent_iter, None)
                line2 = next(xevent_iter, None)
                prop_coord = self._extract_prop('Motion_coord', line1, 'coord')
                prop_time = self._extract_prop('Motion_time', line1, 'time')
                if prop_coord is not None and prop_time is not None:
                    event_dict = dict([prop_coord, prop_time])
                    self.xevent_data.append([event_name, event_dict])
            elif line.startswith('Button'):
                line1 = next(xevent_iter, None)
                line2 = next(xevent_iter, None)
                prop_coord = self._extract_prop('Button_coord', line1, 'coord')
                prop_time = self._extract_prop('Button_time', line1, 'time')
                prop_button = self._extract_prop('Button_button', line2,
                                                 'button')
                if (prop_coord is not None and prop_button is not None
                    and prop_time is not None):
                    event_dict = dict([prop_coord, prop_button, prop_time])
                    self.xevent_data.append([event_name, event_dict])
        return True

    def parse_button_and_motion(self):
        ''' Parse X button events and motion events

        This method parses original X button events and motion events from
        self.xevent_data, and saves the aggregated results in self.xevent_seq

        The variable seg_move accumulates the motions of the contiguous events
        segmented by some boundary events such as Button events and other
        NOP events.

        A NOP (no operation) event is a fake X event which is used to indicate
        the occurrence of some important trackpad device events. It can be
        use to compute the latency between a device event and a resultant X
        event. It can also be used to partition X events into groups.
        '''

        # Define some functions for seg_move
        def _reset_seg_move():
            ''' Reset seg_move in x+y, x, and y to 0 '''
            return [0, [0, 0]]

        def _reset_time_interval(begin_time=None):
            ''' Reset time interval '''
            return [begin_time, None]

        def _reset_coord():
            return [None, None]

        def _add_seg_move(seg_move, move):
            ''' Accumulate seg_move in x+y, x, and y respectively '''
            list_add = lambda list1, list2: map(sum, zip(list1, list2))
            return [seg_move[0] + move[0], list_add(seg_move[1], move[1])]

        def _is_finger_off(line):
            ''' Is finger off the trackpad? '''
            ev_name, ev_dict = line
            if isinstance(ev_dict, dict) and ev_dict.has_key('event'):
                return ev_dict['event'] == 'Finger Off'

        def _reset_motion_trace(self):
            ''' Reset motion_trace and its state '''
            self.motion_trace_state = None
            self.motion_trace = []
            self.motion_trace_len = self.LONG_MOTIOIN_TRACE

        def _extract_motion_trace_state(self, line):
            ''' Extract motion_trace_state which determines motion trace
            length and buffer strategy.

            For typical physical clicks:
            ----------------------------
              Finger On

                  optional Motion events        Use trace: motion_trace_before
                Device Mouse Click Press
                  optional Motion events
                ButtonPress
                  optional Motion events
                Device Mouse Click Release
                  optional Motion events
                ButtonRelease
                  optional Motion events        Use trace: motion_trace_after

                  optional Motion events        Use trace: motion_trace_before
                Device Mouse Click Press
                  optional Motion events
                ButtonPress
                  optional Motion events
                Device Mouse Click Release
                  optional Motion events
                ButtonRelease
                  optional Motion events        Use trace: motion_trace_after

                  ...

              Finger Off

            (1) state == 'Finger On':
                Set trace length: LONG_MOTIOIN_TRACE
                Note: its next state could be either 'Device Mouse Click Press'
                      or 'ButtonPress'.
                motion_trace_state = state

            (2) state == 'Device Mouse Click Press':
                Set trace length: motion_trace_before
                Motion report: Use only the motion_trace_before portion in
                               motion_trace.
                Reason: Users may move cursor around and, without finger
                        leaving trackpad, make a physical click. We do not want
                        to take into account the cursor movement during
                        finger tracking.
                Set trace length: LONG_MOTIOIN_TRACE
                motion_trace_state = state

            (3) state == 'ButtonPress':
                Motion report: Use all motion events in motion_trace
                               since it is in the middle of a physical click.
                Note: its previoius state could be either 'Device Mouse Click
                      Press' or 'Finger On'
                Set trace length: LONG_MOTIOIN_TRACE
                motion_trace_state = state

            (4) state == 'Device Mouse Click Release':
                (No need to handle 'Device Mouse Click Release' explicitly)

            (5) state == 'ButtonRelease':
                Motion report: Use all motion events in motion_trace
                               since it is in the middle of a physical click.
                Set trace length: motion_trace_after
                Reason: After releasing the physical click, without finger
                        leaving trackpad, users may move cursor around. So we
                        only want to collect the motion events afterwards in
                        limited time.
                Note: After motion_trace_after has been collected.
                      Append a motion report. And then turn to using
                      "Set trace length: LONG_MOTIOIN_TRACE"
                                          for next possible clicks or
                                          tap-to-clicks.
                motion_trace_state = state

            (6) state == 'Finger Off':
                if self.motion_trace_state == 'ButtonRelease':
                    Motion report: Use motion events in the motion_trace
                                   for up to motion_trace_after elements.
                Set trace length: LONG_MOTIOIN_TRACE
                motion_trace_state = state

            (7) event_name == 'Motion':
                if (self.motion_trace_state == 'ButtonRelease' and
                    len(self.motion_trace) >= self.motion_trace_len - 1):
                    _append_motion(self)
                    self.motion_trace_len = self.LONG_MOTIOIN_TRACE
                    self.motion_trace_state = 'ButtonRelease.TraceAfterDone'
                    Note: Next state could be either 'Device Mouse Click Press'
                          or 'Finger Off'
            '''
            ev_name, ev_dict = line
            state = None
            if ev_name in ['ButtonPress', 'ButtonRelease', 'MotionNotify']:
                state = ev_name
            elif (ev_name == 'NOP' and
                  ev_dict['event'] in ['Finger On', 'Finger Off',
                                       'Device Mouse Click Press']):
                state = ev_dict['event']
            return state

        def _insert_motion_trace_entry(self, event_coord, event_time):
            # Insert an entry into motion_trace
            mtrace_dict = {'coord': event_coord, 'time': event_time}
            self.motion_trace.append(mtrace_dict)

            if len(self.motion_trace) > self.motion_trace_len:
                self.motion_trace.pop(0)

        def _reduce_motion_trace(self, target_trace_len):
            # Reduce motion_trace according to target_trace_len
            trace_len = len(self.motion_trace)
            if trace_len > target_trace_len:
                begin_index = trace_len - target_trace_len
                self.motion_trace = self.motion_trace[begin_index:]

        def _add_motion_trace(self, event_coord, event_time, line):
            ''' Add the new coordinate into motion_trace.

            If the trace lenght exceeds a predefined length, pop off the
            oldest entry from the trace buffer.

            Refer to _extract_motion_trace_state() for details about
            the operations of motion_trace.
            '''
            state = _extract_motion_trace_state(self, line)

            # Determine motion trace length based on motion trace state
            if state == 'Finger On':
                self.motion_trace_len = self.LONG_MOTIOIN_TRACE
                self.motion_trace_state = state

            elif state == 'Device Mouse Click Press':
                _reduce_motion_trace(self, self.motion_trace_before)
                _append_motion(self)
                self.motion_trace_len = self.LONG_MOTIOIN_TRACE
                self.motion_trace_state = state

            elif state == 'ButtonPress':
                _insert_motion_trace_entry(self, event_coord, event_time)
                _append_motion(self)
                self.motion_trace_len = self.LONG_MOTIOIN_TRACE
                self.motion_trace_state = state

            elif state == 'ButtonRelease':
                _insert_motion_trace_entry(self, event_coord, event_time)
                _append_motion(self)
                self.motion_trace_len = self.motion_trace_after
                self.motion_trace_state = state

            elif state == 'Finger Off':
                # if the state is not 'ButtonRelease.TraceAfterDone' yet
                if self.motion_trace_state == 'ButtonRelease':
                    _append_motion(self)
                self.motion_trace_len = self.LONG_MOTIOIN_TRACE
                self.motion_trace_state = state

            elif state == 'MotionNotify':
                _insert_motion_trace_entry(self, event_coord, event_time)
                if (self.motion_trace_state == 'ButtonRelease' and
                    len(self.motion_trace) >= self.motion_trace_len - 1):
                    _append_motion(self)
                    self.motion_trace_len = self.LONG_MOTIOIN_TRACE
                    self.motion_trace_state = 'ButtonRelease.TraceAfterDone'

            elif line[0] == 'NOP':
                _append_motion(self)

        def _append_event(event):
            ''' Append the event into xevent_seq '''
            self.xevent_seq.append(event)
            indent = ' ' * 14
            logging.info(indent + str(event))

        def _append_motion(self):
            ''' Append Motion events to xevent_seq '''
            if not self.motion_trace:
                return

            # Compute the accumulated movement and the time span
            # in motion_trace buffer.
            pre_xy = _reset_coord()
            seg_move = _reset_seg_move()
            seg_time_span = [None, None]
            for m in self.motion_trace:
                cur_xy = m['coord']
                cur_time = m['time']
                if pre_xy == [None, None]:
                    pre_xy = cur_xy
                    seg_time_span = [cur_time, cur_time]
                else:
                    move = self._calc_distance(*(pre_xy + cur_xy))
                    seg_move = _add_seg_move(seg_move, move)
                    pre_xy = cur_xy
                    seg_time_span[1] = cur_time

            # Append the motion report data to xevent_seq
            # The format of reported motion data looks like:
            #   ('Motion', motion_data, time_span)
            #
            #   E.g.,
            #   ('Motion', (2.0, ('Motion_x', 2), ('Motion_y', 0)),
            #              [351613962, 351614138])
            (move_xy, (move_x, move_y)) = seg_move
            if move_x > 0 or move_y > 0:
                move_val = (move_xy, ('Motion_x', move_x), ('Motion_y', move_y))
                event = ('Motion', move_val, seg_time_span)
                _append_event(event)

            # Clear the motion_trace buffer and keep the last entry
            last_entry = self.motion_trace.pop()
            _reset_motion_trace(self)
            self.motion_trace.append(last_entry)

        def _append_button(event_name, button_label, event_time):
            ''' Append non-wheel Buttons

            Typically, they include Button Left, Button Middle, Button Right,
            and other non-wheel buttons etc.

            TODO(josephsih): creating a event class, with more formalized,
            named members (name, details, time). Or, using a dict, ('name': ,
            'details':, 'time':).
            '''
            if not self.xbutton.is_button_wheel(button_label):
                event = (event_name, button_label, event_time)
                _append_event(event)

        def _append_button_wheel(button_label, event_button, button_time):
            ''' Append Button Wheel count '''
            if self.xbutton.is_button_wheel(button_label):
                count = self.seg_count_buttons[event_button]
                count = int(count) if count == int(count) else count
                if count > 0:
                    event = (button_label, count, button_time)
                    _append_event(event)

        def _append_NOP(event_name, event_description, event_time):
            ''' Append NOP event '''
            if event_name == NOP.NOP:
                event = (event_name, event_description, event_time)
                _append_event(event)

        self.count_buttons = self.xbutton.init_button_struct(0)
        self.seg_count_buttons = self.xbutton.init_button_struct(0)
        self.count_buttons_press = self.xbutton.init_button_struct(0)
        self.count_buttons_release = self.xbutton.init_button_struct(0)
        self.button_states = self.xbutton.init_button_struct('ButtonRelease')

        pre_xy = _reset_coord()
        button_label = pre_button_label = None
        event_name = None
        event_button = pre_event_button = None
        self.xevent_seq = []
        seg_move_time = _reset_time_interval()
        button_time = _reset_time_interval()
        self.sum_move = 0
        _reset_motion_trace(self)

        indent = ' ' * 8
        logging.info(indent + 'X events detected:')

        for line in self.xevent_data:
            flag_finger_off = _is_finger_off(line)
            event_name = line[0]
            event_coord = _reset_coord()
            event_time = None
            if event_name != NOP.NOP:
                event_dict = line[1]
                if event_dict.has_key('coord'):
                    event_coord = list(eval(event_dict['coord']))
                if event_dict.has_key('button'):
                    event_button = eval(event_dict['button'])
                if event_dict.has_key('time'):
                    event_time = eval(event_dict['time'])

            # _extract_motion_trace_state(self, line)
            _add_motion_trace(self, event_coord, event_time, line)

            if event_name == 'EnterNotify':
                if pre_xy == [None, None]:
                    pre_xy = event_coord
                    seg_move_time[0] = event_time
                self.seg_count_buttons = self.xbutton.init_button_struct(0)

                if seg_move_time[0] is None:
                    seg_move_time = [event_time, event_time]
                else:
                    seg_move_time[1] = event_time

            elif event_name == 'MotionNotify':
                if pre_xy == [None, None]:
                    pre_xy = event_coord
                else:
                    cur_xy = event_coord
                    move = self._calc_distance(*(pre_xy + cur_xy))
                    pre_xy = cur_xy
                    self.sum_move += move[0]

                if seg_move_time[0] is None:
                    seg_move_time = [event_time, event_time]
                else:
                    seg_move_time[1] = event_time

            elif event_name.startswith('Button'):
                seg_move_time = _reset_time_interval()
                button_label = self.xbutton.get_label(event_button)
                self.button_states[event_button] = event_name

                if button_label == pre_button_label:
                    button_time[1] = event_time
                else:
                    # Append Button Wheel count when event button is changed
                    _append_button_wheel(pre_button_label, pre_event_button,
                                         button_time)
                    self.seg_count_buttons = self.xbutton.init_button_struct(0)
                    button_time = _reset_time_interval(begin_time=event_time)

                # Append button events except button wheel events
                _append_button(event_name, button_label, event_time)

                # A ButtonRelease should precede ButtonPress
                # A ButtonPress should precede ButtonRelease
                if event_name == 'ButtonPress':
                    self.count_buttons_press[event_button] += 1
                elif event_name == 'ButtonRelease':
                    self.count_buttons_release[event_button] += 1
                self.count_buttons[event_button] += 0.5
                self.seg_count_buttons[event_button] += 0.5
                pre_button_label = button_label
                pre_event_button = event_button

            elif event_name == NOP.NOP:
                _append_button_wheel(pre_button_label, pre_event_button,
                                     button_time)
                pre_button_label = None
                self.seg_count_buttons = self.xbutton.init_button_struct(0)
                button_time = _reset_time_interval()
                seg_move_time = _reset_time_interval()
                _append_NOP(NOP.NOP, line[1]['event'], line[1]['time'])
                if flag_finger_off:
                    pre_xy = _reset_coord()
                    _reset_motion_trace(self)

        # Append aggregated button wheel events and motion events
        _append_button_wheel(button_label, event_button, button_time)
        _append_motion(self)

        # Convert dictionary to tuple
        self.button_states = tuple(self.button_states.values())
        self.count_buttons = tuple(self.count_buttons.values())
