# -*- coding: utf-8 -*-
# 
# The LIRC Plugin for elisa
# 
# Copyright (C) 2008 by Benjamin Kampmann <big.master.ben@web.de>
# 
# 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/>.
# 
# Author: Benjamin Kampmann <big.master.ben@web.de>


from twisted.internet import glib2reactor
glib2reactor.install()

from twisted.internet import reactor

from twisted.internet.unix import Client

import pgm, string

from pgm.graph.text import Text
from pgm.graph.group import Group

from elisa.plugins.lirc.lirc_input import CallbackConnector


ordered_keys = [('KEY_OK', 'OK'), ('KEY_GO_DOWN', 'Down'),
                ('KEY_GO_UP', 'Up'),  ('KEY_GO_LEFT', 'Left'),
                ('KEY_GO_RIGHT','Right'), ('KEY_MENU', 'Menu'),
                ('KEY_EXIT', 'Exit') , ('KEY_PLAY', 'Play'),
                ('KEY_PAUSE', 'Pause'), ('KEY_STOP', 'Stop'),
                ('KEY_SEEK_FORWARD', 'Seek Forward'),
                ('KEY_SEEK_BACKWARD', 'Seek Backward'),
                ('KEY_MUTE', 'Mute'), ('KEY_VOL_UP', 'Volume +'),
                ('KEY_VOL_DOWN', 'Volume -'),
                ('KEY_NEXT', 'Next'), ('KEY_PREVIOUS', 'Previous'),
                ('KEY_PAGE_UP','Page Up'), ('KEY_PAGE_DOWN', 'Page Down'),
                ('KEY_INC_PLAYBACK_SPEED', 'Increase Playback Speed'),
                ('KEY_DEC_PLAYBACK_SPEED', 'Decrease Playback Speed'),]
#               ('KEY_DVD_MENU', 'DVD Menu')

letter_keys = [ ('KEY_%s' % k, k) for k in string.ascii_letters]
num_keys = [ ('KEY_%s' % k, k) for k in string.digits]

all_keys = ordered_keys + num_keys + letter_keys

class SimpleUI(object):

    def __init__(self):
        self.gl = pgm.viewport_factory_make('opengl')
        self.gl.title = 'Remote Setup'

        self.name = None
        self.filename = None
        self.mappings = {}

        self.next_key = None
        self.ok_key = None
        self.prev_key = None

        self.save = False

        self.cvs = pgm.Canvas()
        self.txt = Text()
        self.txt.label = 'Please press a button on your remote'

        self.help_txt = Text()
        self.help_txt.label = """\
Help:
- save & exit: press OK twice
- skip this key configuration: press Up
- reconfigure previous key: press Down
"""

        self.gl.set_canvas(self.cvs)

        white = (255, 255, 255, 255)
        text_bg_color = (0, 0, 0, 255)
        self.txt.size = (4, 1.3)
        self.txt.position = (0., 0.25, 0.0)
        self.txt.fg_color = white
        self.txt.bg_color = text_bg_color
        self.txt.font_height = 1/5.
        self.txt.show()
        self.cvs.add(pgm.DRAWABLE_MIDDLE, self.txt)


        self.help_txt.size = (4, 1.25)
        self.help_txt.position = (0., 1.7, 0.0)
        self.help_txt.fg_color = white
        self.help_txt.bg_color = text_bg_color
        self.help_txt.font_height = 1/6.


        self._client = Client('/dev/lircd', 
                CallbackConnector(self.key_pressed),
                reactor=reactor)

        self.gl.show()

    def key_pressed(self, hex, repeat, name, remote):
        if int(repeat):
            return

        if not self.name:
            self.name = remote
            self.idx = 0
            self.refresh()
            return
        elif self.name != remote:
            print "unknown remote", remote
            return
        
        if hex == self.ok_key:
            if self.save:
                self._save()
            else:
                self.save = True
                self.txt.label = "Press 'OK' to save"
            return
        elif hex == self.prev_key:
            self.idx -= 1
            self.refresh()
        elif hex == self.next_key:
            self.idx += 1
            self.refresh()
        elif self.idx == len(all_keys):
            self.save = True
            self.txt.label = "Press 'OK' to save"
        else:
            key, name = all_keys[self.idx] 
            self.mappings[key] = hex
            if self.idx == 0 :
                self.ok_key = hex
            elif self.idx == 1:
                self.prev_key = hex
            elif self.idx == 2:
                self.next_key = hex
            self.idx += 1
            self.refresh()
    
    def _save(self):
        data = ""
        for key, value in self.mappings.iteritems():
            data += "%s %s %s\n" % (self.name, value, key)

        writer = open(self.filename, 'w')
        writer.write(data)
        writer.close()
        print "Remote control mappings written to file %s" % self.filename
        reactor.stop()

    def refresh(self):
        try:
            current_key = all_keys[self.idx]
        except IndexError:
            # most likely last key was reached, let's save & exit
            self._save()
        else:
            self.save = False

            key, name = current_key
            self.txt.label = "Please press '%s' now" % name


        # show the help text only if all the keys referenced in there
        # have already been configured
        if None not in (self.next_key, self.ok_key, self.prev_key) and \
               not self.help_txt.visible:
            self.help_txt.show()
            self.cvs.add(pgm.DRAWABLE_MIDDLE, self.help_txt)


if __name__ == '__main__':
    import sys
    if len(sys.argv) != 2:
        print "Usage: %s path_to_file_to_create" % sys.argv[0]
        sys.exit(1)

    ui = SimpleUI()
    ui.filename = sys.argv[1]
    ui.gl.connect('delete-event', lambda x, y: reactor.stop())
    reactor.run()

