# -*- coding: utf-8 -*-
# Elisa - Home multimedia server
# Copyright (C) 2006-2008 Fluendo Embedded S.L. (www.fluendo.com).
# All rights reserved.
#
# This file is available under one of two license agreements.
#
# This file is licensed under the GPL version 3.
# See "LICENSE.GPL" in the root of this distribution including a special
# exception to use Elisa with Fluendo's plugins.
#
# The GPL part of Elisa is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Elisa" in the root directory of this distribution package
# for details on that license.


__maintainer__ = 'Lionel Martin <lionel@fluendo.com>'

import string
from elisa.base_components.input_provider import PushInputProvider
from elisa.core.input_event import *
import pgm

class PigmentInput(PushInputProvider):
    """
    This class implements Pigment events support.
    """

    def __init__(self):
        PushInputProvider.__init__(self)
        self._handler_ids = []
        self._simple_keys = {}
        
        letters = string.ascii_letters
        for key in letters:
            key_value = getattr(EventValue, 'KEY_%s' % key)
            pgm_key = getattr(pgm.keysyms, key)
            self._simple_keys[pgm_key] = key_value

        for key in '1234567890':
            key_value = getattr(EventValue, 'KEY_%s' % key)
            pgm_key = getattr(pgm.keysyms, '_%s' % key)
            self._simple_keys[pgm_key] = key_value


    def bind(self):
        signal_id = self.viewport.connect('delete-event',
                                          self._process_delete_event)
        self._handler_ids.append(signal_id)
        signal_id = self.viewport.connect('key-press-event',
                                          self._process_press_event)
        self._handler_ids.append(signal_id)
        signal_id = self.viewport.connect('key-release-event',
                                          self._process_release_event)
        self._handler_ids.append(signal_id)

    def unbind(self):
        for signal_id in self._handler_ids:
            self.viewport.disconnect(signal_id)

        # releasing our reference to the viewport
        del self.viewport

    def _process_delete_event(self, viewport, event):
        elisa_event = InputEvent(EventSource.OTHER, EventType.OTHER,
                                 EventAction.EXIT)
        elisa_event.origin = self.origin
        self.input_manager.process_event(elisa_event, self.path)

    def _process_press_event(self, viewport, event):
        elisa_event = self._create_event_with_type(event, EventType.KEY_DOWN)
        self.input_manager.process_event(elisa_event, self.path)

    def _process_release_event(self, viewport, event):
        elisa_event = self._create_event_with_type(event, EventType.KEY_UP)
        self.input_manager.process_event(elisa_event, self.path)

    def _process_scroll_event(self, viewport, event):
        if event.direction == pgm.SCROLL_DOWN:
            elisa_event = InputEvent(EventSource.MOUSE, EventType.OTHER,
                                     EventAction.GO_LEFT)
        elif event.direction == pgm.SCROLL_UP:
            elisa_event = InputEvent(EventSource.MOUSE, EventType.OTHER,
                                     EventAction.GO_RIGHT)
        
        elisa_event.origin = self.origin
        self.input_manager.process_event(elisa_event, self.path)

    def _process_button_press_event(self, viewport, event):
        if event.button == pgm.BUTTON_LEFT:
            elisa_event = InputEvent(EventSource.MOUSE, EventType.OTHER,
                                     EventAction.GO_DOWN)
        elif event.button == pgm.BUTTON_RIGHT:
            elisa_event = InputEvent(EventSource.MOUSE, EventType.OTHER,
                                     EventAction.GO_UP)
        elif event.button == pgm.BUTTON_MIDDLE:
            elisa_event = InputEvent(EventSource.MOUSE, EventType.OTHER,
                                     EventAction.OK)
        
        elisa_event.origin = self.origin
        self.input_manager.process_event(elisa_event, self.path)

    def _create_event_with_type(self, event, event_type):
        elisa_event = None

        if event_type == EventType.KEY_DOWN:
            # TODO: support more keys
            keyval = event.keyval
            if keyval == pgm.keysyms.Up:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.GO_UP)
            elif keyval == pgm.keysyms.Down:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.GO_DOWN)
            elif keyval == pgm.keysyms.Right:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.GO_RIGHT)
            elif keyval == pgm.keysyms.Left:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.GO_LEFT)
            elif keyval == pgm.keysyms.Return:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.OK)
            elif keyval == pgm.keysyms.BackSpace or \
                 keyval == pgm.keysyms.space:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.MENU)
            elif keyval == pgm.keysyms.f:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.TOGGLE_FULLSCREEN,
                                         EventValue.KEY_f)
            elif keyval == pgm.keysyms.q:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.EXIT,
                                         EventValue.KEY_q)
            elif keyval == pgm.keysyms.Escape:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.EXIT)
            elif keyval == pgm.keysyms.s:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.STOP,
                                         EventValue.KEY_s)
            elif keyval == pgm.keysyms.x:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.PREVIOUS,
                                         EventValue.KEY_x)
            elif keyval == pgm.keysyms.c:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.NEXT,
                                         EventValue.KEY_c)
            elif keyval == pgm.keysyms.v:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.SEEK_BACKWARD,
                                         EventValue.KEY_v)
            elif keyval == pgm.keysyms.b:
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.SEEK_FORWARD,
                                         EventValue.KEY_b)
            # All the other events
            elif keyval in self._simple_keys:
                event_value = self._simple_keys[keyval]
                elisa_event = InputEvent(EventSource.KEYBOARD,
                                         EventType.KEY_DOWN,
                                         EventAction.NONE,
                                         event_value)
            else:
                self.info('Unrecognized key received: %s', event)
        else:
            self.info('Unrecognized key received: %s', event)

        if elisa_event:
            elisa_event.origin = self.origin
            
        return elisa_event
