#!/usr/bin/python

from __future__ import print_function
import os
import sys
import dbus
import dbus.service
import dbus.mainloop.glib
import gobject
import bluezutils

class Player(dbus.service.Object):
	properties = None
	metadata = None

	def set_object(self, obj = None):
		if obj != None:
			bus = dbus.SystemBus()
			mp = dbus.Interface(bus.get_object("org.bluez", obj),
						"org.bluez.MediaPlayer1")
			prop = dbus.Interface(bus.get_object("org.bluez", obj),
						"org.freedesktop.DBus.Properties")

			self.properties = prop.GetAll("org.bluez.MediaPlayer1")
			self.metadata = mp.GetTrack()

			bus.add_signal_receiver(self.properties_changed,
				path = obj,
				dbus_interface = "org.freedesktop.DBus.Properties",
				signal_name = "PropertiesChanged")

			bus.add_signal_receiver(self.track_changed,
				path = obj,
				dbus_interface ="org.bluez.MediaPlayer",
				signal_name = "TrackChanged")
		else:
			self.properties = dbus.Dictionary({
					"Equalizer" : "off",
					"Repeat" : "off",
					"Shuffle" : "off",
					"Scan" : "off",
					"Status" : "playing",
					"Position" : dbus.UInt32(0) },
					signature="sv")

			self.metadata = dbus.Dictionary({
					"Title" : "Title",
					"Artist" : "Artist",
					"Album" : "Album",
					"Genre" : "Genre",
					"NumberOfTracks" : dbus.UInt32(10),
					"Track" : dbus.UInt32(1),
					"Duration" : dbus.UInt32(10000) },
					signature="sv")
			handler = InputHandler(self)
			gobject.io_add_watch(sys.stdin, gobject.IO_IN,
							handler.handle)

	@dbus.service.method("org.bluez.MediaPlayer1",
					in_signature="", out_signature="")
	def Release(self):
		print("Release")
		mainloop.quit()

	@dbus.service.method("org.freedesktop.DBus.Properties",
					in_signature="ssv", out_signature="")
	def Set(self, interface, key, value):
		print("Set (%s, %s)" % (key, value), file=sys.stderr)
		return

	@dbus.service.signal("org.freedesktop.DBus.Properties",
							signature="sa{sv}as")
	def PropertiesChanged(self, interface, properties,
						invalidated = dbus.Array()):
		"""PropertiesChanged(interface, properties, invalidated)

		Send a PropertiesChanged signal. 'properties' is a dictionary
		containing string parameters as specified in doc/media-api.txt.
		"""
		pass

	@dbus.service.signal("org.bluez.MediaPlayer1", signature="a{sv}")
	def TrackChanged(self, metadata):
		"""TrackChanged(metadata)

		Send a TrackChanged signal. 'metadata' parameter is a dictionary,
		with values as defined in doc/media-api.txt.
		"""
		pass

	def help(self, func):
		help(self.__class__.__dict__[func])

	def properties_changed(self, interface, properties, invalidated):
		print("properties_changed(%s, %s)" % (properties, invalidated))

		self.PropertiesChanged(interface, properties, invalidated)

	def track_changed(self, metadata):
		print("track_changed(%s)" % (metadata))

		self.TrackChanged(metadata)

class InputHandler:
	commands = { 'TrackChanged': '(metadata)',
			'PropertiesChanged': '(interface, properties)',
			'help': '(cmd)' }
	def __init__(self, player):
		self.player = player
		print('\n\nAvailable commands:')
		for cmd in self.commands:
			print('\t', cmd, self.commands[cmd], sep='')

		print("\nUse python syntax to pass arguments to available methods.\n" \
                "E.g.: TrackChanged({'Title': 'My title', 'Album': 'my album' })")
		self.prompt()

	def prompt(self):
		print('\n>>> ', end='')
		sys.stdout.flush()

	def handle(self, fd, condition):
		s = os.read(fd.fileno(), 1024).strip()
		try:
			cmd = s[:s.find('(')]
			if not cmd in self.commands:
				print("Unknown command ", cmd)
		except ValueError:
			print("Malformed command")
			return True

		try:
			exec "self.player.%s" % s
		except Exception as e:
			print(e)
			pass
		self.prompt()
		return True


if __name__ == '__main__':
	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

	bus = dbus.SystemBus()

	if len(sys.argv) > 1:
		path = bluezutils.find_adapter(sys.argv[1]).object_path
	else:
		path = bluezutils.find_adapter().object_path

	media = dbus.Interface(bus.get_object("org.bluez", path),
						"org.bluez.Media1")

	path = "/test/player"
	player = Player(bus, path)
	mainloop = gobject.MainLoop()

	if len(sys.argv) > 2:
		player.set_object(sys.argv[2])
	else:
		player.set_object()

	print('Register media player with:\n\tProperties: %s\n\tMetadata: %s' \
					% (player.properties, player.metadata))


	media.RegisterPlayer(dbus.ObjectPath(path), player.properties,
							player.metadata)

	mainloop.run()
