#!/usr/bin/python

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

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

	@dbus.service.method("org.bluez.MediaPlayer",
					in_signature="sv", out_signature="")
	def SetProperty(self, key, value):
		print("SetProperty (%s, %s)" % (key, value), file=sys.stderr)
		return

	@dbus.service.signal("org.bluez.MediaPlayer", signature="sv")
	def PropertyChanged(self, setting, value):
		"""PropertyChanged(setting, value)

		Send a PropertyChanged signal. 'setting' and 'value' are
		string parameters as specified in doc/media-api.txt.
		"""
		pass

	@dbus.service.signal("org.bluez.MediaPlayer", 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])

class InputHandler:
	commands = { 'TrackChanged': '(metadata)',
					'PropertyChanged': '(key, value)',
					'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()
	manager = dbus.Interface(bus.get_object("org.bluez", "/"),
						"org.bluez.Manager")

	if len(sys.argv) > 1:
		path = manager.FindAdapter(sys.argv[1])
	else:
		path = manager.DefaultAdapter()

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

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

	properties = dbus.Dictionary({ "Equalizer" : "off",
					"Repeat" : "off",
					"Shuffle" : "off",
					"Scan" : "off",
					"Status" : "playing",
					"Position" : dbus.UInt32(0) }, signature="sv")

	metadata = dbus.Dictionary({ "Title" : "Title",
					"Artist" : "Artist",
					"Album" : "Album",
					"Genre" : "Genre",
					"NumberOfTracks" : dbus.UInt32(10),
					"Number" : dbus.UInt32(1),
					"Duration" : dbus.UInt32(10000) }, signature="sv")

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

	handler = InputHandler(player)
	gobject.io_add_watch(sys.stdin, gobject.IO_IN, handler.handle)

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

	mainloop.run()
