# A LIRC plugin for Exaile. Depends on pylirc from http://sourceforge.net/projects/pylirc/
# Copyright (C) 2009-2011 Wicher Minnaard, http://smorgasbord.gavagai.nl / wicher@gavagai.eu
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import pylirc, logging, threading, select

LIRCAILE = None

def enable(exaile):
  _enable(None, exaile, None)
 
def _enable(eventname, exaile, nothing):
  global LIRCAILE
  LIRCAILE = Lircaile(exaile)

def disable(exaile):
  pylirc.exit()


class Lircaile():

  def __init__(self, exaile):
    self.exaile = exaile
    self.logger = logging.getLogger(__name__)
    sock_fd = pylirc.init('lircaile')
    waitlirc = threading.Thread(target=self.wait_lircevent, args=(sock_fd,), name='Thread-lircaile-waitlirc')
    waitlirc.daemon = True
    waitlirc.start()


  def wait_lircevent(self,sock_fd):
    while True:
      """Pops all queued signals off of the LIRC queue and hands them to
      handleCode() for further processing."""
      select.select([sock_fd],[],[])
      try:
        [code] = pylirc.nextcode()
        self.handleCode(*code.split())
      except TypeError:
        pass #empty queue


  def handleCode(self, command, *arg):
    """Takes LIRC signals and uses introspection to try to find appropriate 
    exaile functions to call based on the name of the signal. """

    if (command == 'chvol'):
      self.exaile.player.set_volume(self.exaile.player.get_volume() + float(arg[0]))
    elif (command == 'seek'):
      self.exaile.player.seek((self.exaile.player.get_position()/1000000000) + float(arg[0]))
    else:
      func = None
      # Look for a matching playlist function
      try:
        func = getattr(self.exaile.queue, command)
      except AttributeError:
        # No? Then look for a matching player function
        try:
          func = getattr(self.exaile.player, command)
        except AttributeError:
          # No? Then we're out of options
          self.logger.warning('No function to handle the "%s" LIRC event' % command)
      if callable(func):
        func()
