#!/usr/bin/python
import gps
import fcntl
import gobject
import time
import os
import sys
import pygtk
import gtk
import pango
import struct
input_event_struct = "@LLHHi"
input_event_size = struct.calcsize(input_event_struct)

def dbg(s):
    print("%s %s" % (time.strftime("%H:%M:%S"), s))

class UI:
    def __init__(self, loop):
        self.loop = loop

        self.daemon = gps.gps(host = "localhost",
                              port = "2947",
                              mode = gps.WATCH_ENABLE | gps.WATCH_JSON | gps.WATCH_SCALED,
                              verbose = 0)
        gobject.io_add_watch(self.daemon.sock, gobject.IO_IN, self.handle_response)
        gobject.io_add_watch(self.daemon.sock, gobject.IO_ERR, self.handle_hangup)
        gobject.io_add_watch(self.daemon.sock, gobject.IO_HUP, self.handle_hangup)

        w = gtk.Window(gtk.WINDOW_TOPLEVEL)
        w.set_default_size(480, 600)
        w.connect("delete_event", (lambda w,e: False))
        w.connect("destroy", (lambda w: self.loop.quit()))
        w.set_border_width(0)
        w.show()

        vbox = gtk.VBox(False, 0)
        w.add(vbox)
        vbox.show()

        b = gtk.Button("Record")
        self.button = b
        b.connect("pressed", self.cbRecordStart)
        b.connect("released", self.cbRecordStop)
        b.set_focus_on_click(False)
        b.set_size_request(480, 400)
        self.record_button = b
        self.record_button.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.color_parse('red'))
        vbox.pack_start(b)
        b.show()

        b = gtk.Button("Play")
        b.set_size_request(480, 200)
        b.connect("pressed", self.cbPlay)
        b.set_focus_on_click(False)
        vbox.pack_start(b)
        b.show()

        fd = os.open("/dev/input/event4", os.O_NONBLOCK | os.O_RDONLY)
        try:
            fcntl.ioctl(fd, 0x40044590, 1) # EVIOCGRAB
        except:
            print("failed to get exclusive access to AUX button")
        gobject.io_add_watch(fd, gobject.IO_IN, self.cbEventActivity)

        os.system("alsactl -f /etc/alsa-scenarios/voip-handset.state restore")

    def handle_response(self, source, condition):
        if self.daemon.poll() == -1:
            self.handle_hangup(source, condition)
        if not (self.daemon.valid & gps.PACKET_SET):
            return True
        if self.daemon.data["class"] != "TPV":
            return True
        self.time = ""
        self.lat = ""
        self.lon = ""
        if "lat" in self.daemon.data:
            self.lat = self.daemon.data["lat"]
            self.lon = self.daemon.data["lon"]
        else:
            print(self.daemon.data)
            
        if "time" in self.daemon.data:
            self.time = self.daemon.data["time"]
        s = "%s %s %s" % (self.time, self.lat, self.lon)
        if "time" not in self.daemon.data or self.time % 10 == 0:
            self.button.set_label(s)
        return True

    def handle_hangup(self, source, condition):
        print("hangup")
        self.loop.quit()
        return True

    def cbRecordStart(self, w):
        dbg("cbRecordStart")
        if self.lat != "":
            os.system("start-arecord %s %s %s" % (self.time, self.lat, self.lon))
        
    def cbRecordStop(self, w):
        dbg("cbRecordStop")
        os.system("stop-arecord")
    def cbPlay(self, w):
        dbg("cbPlay")
        os.system("set-alsa-profile stereoout")
        os.system("play-latest")
        os.system("alsactl -f /etc/alsa-scenarios/voip-handset.state restore")

    def cbEventActivity(self, source, condition):
        dbg("cbEventActivity")
        data = os.read(source, 512)
        events = [ data[i:i+input_event_size] for i in range(0, len(data), input_event_size) ]
        for e in events:
            timestamp, microseconds, typ, code, value = struct.unpack( input_event_struct, e )
            # We need more then just second accuracy
            timestamp = timestamp + microseconds/1000000.0
            if typ != 0x00: # ignore EV_SYN (synchronization event)
                dbg("event %s %s %s %s" % (timestamp, typ, code, value))
                if code == 169 and value == 1:
                    self.cbRecordStart(0)
                if code == 169 and value == 0:
                    self.cbRecordStop(0)
                if code == 116 and value == 1:
                    self.cbPlay(0)
        return True

if __name__ == "__main__":
    loop = gobject.MainLoop()
    UI(loop)
    loop.run()
