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

"""
LircInputProvider component class
"""


__maintainer__ = 'Florian Boucault <florian@fluendo.com>'

from elisa.base_components.input_provider import PollInputProvider
from elisa.core.input_event import *
from elisa.core.component import InitializeFailure
from elisa.core import application

import os
import pkg_resources
from twisted.internet import reactor
from tempfile import mkstemp
import pylirc

class LircInput(PollInputProvider):
    """
    This class implements LIRC remote control support
    """

    config_doc = {'lirc_rc': 'filename of the LIRC config map to use',
                  'delay' : 'how many keys to wait until triggering a repeat',
                  'repeat' : 'every which repeat should be used, zero means'
                             ' no repeating'
                  }
    default_config = {'lirc_rc': 'streamzap.lirc',
                      'delay' : '4',
                      'repeat' : '1'
                      }


    convert_table = {
        'move_up_key' :                 EventAction.GO_UP,
        'move_down_key' :               EventAction.GO_DOWN,
        'move_left_key' :               EventAction.GO_LEFT,
        'move_right_key':               EventAction.GO_RIGHT,
        'toggle_menu_key':              EventAction.MENU,
        'activate_key' :                EventAction.OK,
        'close_key' :                   EventAction.EXIT,
        'toggle_play_pause_key':        EventAction.PLAY,
        'pause_key':                    EventAction.PAUSE,
        'stop_key':                     EventAction.STOP,
        'increment_playback_speed' :    EventAction.INC_PLAYBACK_SPEED,
        'decrement_playback_speed' :    EventAction.DEC_PLAYBACK_SPEED,
        'seek_forward_key' :            EventAction.SEEK_FORWARD,
        'seek_backward_key':            EventAction.SEEK_BACKWARD,
        'next_key':                     EventAction.NEXT,
        'previous_key':                 EventAction.PREVIOUS,
        'toggle_fullscreen_key' :       EventAction.TOGGLE_FULLSCREEN,
        'toggle_mute_key' :             EventAction.MUTE,
        'increment_volume_key' :        EventAction.VOL_UP,
        'decrement_volume_key' :        EventAction.VOL_DOWN
        }


    def __init__(self):
        PollInputProvider.__init__(self)
        self.sock = None
        self._temp_path = None

    def initialize(self):
        rc_file = self.get_lirc_config()
        try:
            self.sock = pylirc.init('elisa', rc_file)
        except Exception, error:
            self.clean()
            raise InitializeFailure(self.name, str(error))
        else:
            self.info("Using LIRC config file: %s" % rc_file)
            pylirc.blocking(False)

    def clean(self):
        if self._temp_path:
            if os.path.exists(self._temp_path):
                os.remove(self._temp_path)

        PollInputProvider.clean(self)

    def get_lirc_config(self):
        delay = int(self.config.get('delay', '0'))
        repeat = int(self.config.get('repeat', '0'))
        lirc_config = self.config.get('lirc_rc','')

        if not os.path.isabs(lirc_config):
            lirc_config = os.path.join(application.CONFIG_DIR, lirc_config)

        if not os.path.exists(lirc_config):
            path = 'data/lirc/%s' % self.config.get('lirc_rc', '')
            lirc_config = pkg_resources.resource_filename(self.__module__,
                                                          path)

        reader = open(lirc_config, 'r')
        write_id, path = mkstemp('.lirc', 'elisa_tmp_lirc_')
        writer = os.fdopen(write_id, 'w')
           
        # replace all delays and repeats
        rep_count = 0
        del_count = 0
        for line in reader:
            if line.find('delay') != -1:
                del_count += 1
                writer.write("delay = %s\n" % delay)
            elif line.find('repeat') != -1:
                rep_count += 1
                writer.write("repeat = %s\n" % repeat)
            else:
                writer.write("%s" % line)

        self.debug("Written %s delays and %s repeats to %s" % (del_count,
                                                                rep_count, 
                                                                path))
        reader.close()
        writer.close()
        self._temp_path = path
        return path

    def get_input_events(self):
        ret = []

        ev = pylirc.nextcode()
        if not ev:
            return []

        if len(ev):
            self.debug("Received: %r", ev)

        for i in ev:
            e = self.create_input_event(i)
            if e:
                ret.append(e)
        return ret

    def create_input_event(self, data):
        evt = None
        if data and data in self.convert_table:
            evt = InputEvent(EventSource.REMOTE, EventType.OTHER,
                             self.convert_table[data])
            evt.origin = self.origin
        else:
            self.info('Unrecognized key received: %s', data)
        return evt


if __name__ == "__main__":

    import time
    from elisa.core import config

    _config = config.Config('elisa.conf')

    _section = {'lirc_rc': 'streamzap.lirc'}
    _config.set_section('lirc_input', _section)

    l = LircInput()
    l.load_config(_config)
    l.initialize()

    while True:
        events = l.get_input_events()
        for event in events:
            print event
        time.sleep(0.01)
