#!/usr/bin/env python

#    This program is a combination of a GPS-data-logger and voicerecorder to do audiomapping (e.g. with josm).
#    Copyright (C) 2011  Stephan Spielmann
#
#    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
#    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/>.

# TODO: are all these imports needed
import dbus
import gobject
import pygtk
pygtk.require('2.0')
import gtk
import os
import subprocess
from dbus.mainloop.glib import DBusGMainLoop
from datetime import datetime

# TODO: comment
class AudioMapper:

    # TODO: comment

    # the subprocess for recording should be saved in here to
    # stop it when pressing the stop-button
    __subprocess = None
    gps_course_iface = None
    gps_position_iface = None

    # the data of the config-file will be saved in the config-dictionary
    # after parsing the config file
    config = {
        "gpxlogfile" : "/home/root/",
        "wptlogfile" : "/home/root/",
        "audiodir"   : "/home/root/",
	"gpxdir"     : "/home/root/",
        "wptdir"     : "/home/root/"}

    # TODO: comment
    def timestampToDateTime(self, timestamp):
        time = datetime.fromtimestamp(timestamp)
        return "{0}T{1}".format(time.date(),time.time())

    # TODO: comment
    def destroy(self, widget, data = None):
	gpxfoot = "</gpx>"
        self._gpxlogfile.write("</trkseg></trk>")
        self._gpxlogfile.write(gpxfoot)
        self._wptlogfile.write(gpxfoot)
        self._gpxlogfile.close()
        self._wptlogfile.close()
        gtk.main_quit()

    # TODO: comment
    def toggled(self, toggleButton):
        __isActive = toggleButton.get_active()
        # TODO: funktionen finden, die den externen aufruf ersetzen
        # TODO: dateinamen auf gps-zeit setzen
        if __isActive:
	    time = datetime.now().isoformat()
            self.__subprocess = subprocess.Popen(["sh","/usr/bin/capturesound.sh", "{0}{1}.wav".format(self.config["audiodir"],time)])
            toggleButton.set_label("stop")
            (validity,timestamp,lat,lon,alt) = self.gps_position_iface.GetPosition()
            self.printPosition(lat,lon,"./{0}.wav".format(time))
        else:
            if self.__subprocess != None:
                self.__subprocess.kill()
                os.system("killall arecord")
            toggleButton.set_label("record")

    # print out the fix status
    def printStatus(self, gps_device_iface):
        fixStatus = gps_device_iface.GetFixStatus()
        print("fix status:"),
        if fixStatus == 0:
            print("Invalid")
        elif fixStatus == 1:
            print("None")
        elif fixStatus == 2:
            print("2 dimensional")
        elif fixStatus == 3:
            print("3 dimensional")

    # TODO: comment
    def printPosition(self, lat, lon, audioFilename):
	self._wptlogfile.write("<wpt lat=\"{0}\" lon=\"{1}\">".format(lat,lon))
        self._wptlogfile.write("<desc>audiomapping waypoint</desc>")
	self._wptlogfile.write("<link href=\"{0}\"><text>{0}</text></link>".format(audioFilename))
        self._wptlogfile.write("</wpt>")

    # print out the connection status
    def printConnectionStatus(self, gps_device_iface):
        connectionStatus = gps_device_iface.GetConnectionStatus()
        if connectionStatus:
            print("gps-device is connected")
        else:
            print("gps-device seems to be disconnected")

    # print out the current accuracy
    def printAccuracy(self, gps_accuracy_iface):
        (validity, pdop, hdop, vdop) = gps_accuracy_iface.GetAccuracy()
        print("Accuracy:")
        print("validity: {0}".format(validity))
        print("pdop: {0}".format(pdop))
        print("hdop: {0}".format(hdop))
        print("vdop: {0}".format(vdop))
        print("")

    # TODO: comment
    def printPositionChanged(self, validity, timestamp, lat, lon, alt):
	(field, timestamp, speed, heading, climb) = self.gps_course_iface.GetCourse()
        self._gpxlogfile.write("<trkpt lat=\"{0}\" lon=\"{1}\">".format(lat, lon))
        self._gpxlogfile.write("<time>" + self.timestampToDateTime(timestamp) + "</time>")
	self._gpxlogfile.write("<speed>{0}</speed>".format(speed))
        self._gpxlogfile.write("<course>{0}</course>".format(heading))
        self._gpxlogfile.write("</trkpt>")
    
    # TODO: comment
    def __init__(self):
        self._gpxlogfile = open("{0}{1}.gpx".format(self.config["gpxlogfile"],datetime.now().isoformat()),"w")
        self._wptlogfile = open("{0}{1}wpt.gpx".format(self.config["wptlogfile"],datetime.now().isoformat()),"w")
	gpxhead = """\
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.0"
    creator="audiomapper.py http://www.bazzinga.eu"
    xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance"
    xmlns="http://www.topografix.com/GPX/1/0">"""

        self._gpxlogfile.write(gpxhead)
	self._gpxlogfile.write("<trk><trkseg>")
        self._wptlogfile.write(gpxhead)

        # den DBUS anfahren
        DBusGMainLoop(set_as_default=True)

        self.loop = gobject.MainLoop()

        self.bus = dbus.SystemBus()

        self.usage_obj = self.bus.get_object('org.freesmartphone.ousaged', '/org/freesmartphone/Usage')
        self.usage_iface = dbus.Interface(self.usage_obj, 'org.freesmartphone.Usage')

        # interfaces besorgen
        self.usage_iface.RequestResource("GPS")

        self.gps_daemon = self.bus.get_object("org.freesmartphone.ogpsd",
                "/org/freedesktop/Gypsy")

        self.gps_position_iface = dbus.Interface(self.gps_daemon,
                "org.freedesktop.Gypsy.Position")

        self.gps_device_iface = dbus.Interface(self.gps_daemon,
                "org.freedesktop.Gypsy.Device")

        self.gps_accuracy_iface = dbus.Interface(self.gps_daemon,
                "org.freedesktop.Gypsy.Accuracy")

        self.gps_course_iface = dbus.Interface(self.gps_daemon,
                "org.freedesktop.Gypsy.Course")

        # zum PositionChanged-event verbinden
        self.gps_position_iface.connect_to_signal("PositionChanged",self.printPositionChanged)
        #self.loop.run()

        # GUI bauen
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("destroy",self.destroy)
        self.window.show()

        # Aufnahmeknopf
        self.button = gtk.ToggleButton("Record")
        self.button.connect("toggled",self.toggled)

        # Knopf dem Fenster zufuegen
        self.window.add(self.button)

        # Knopf sichtbar machen
        self.button.show()

    
    # TODO: comment
    def main(self):
        gtk.main()

if __name__ == "__main__":
    audioMapper = AudioMapper()
    audioMapper.main()








