#!/usr/bin/env python

# This file is part of Window-Switch.
# Copyright (c) 2009-2013 Antoine Martin <antoine@nagafix.co.uk>
# Window-Switch is released under the terms of the GNU GPL v3


import pygst
pygst.require("0.10")
import gst

import gobject
import signal
import sys
import os.path

main_loop = None
from winswitch.util.simple_logger import Logger, set_log_to_tty, set_log_filename, set_log_to_file, get_log_file
logger = Logger("gst_launch_wrapper")
from winswitch.util.daemonize import daemonize
OSX = sys.platform.startswith("darwin")

DEBUG = False

args = sys.argv
def arg_test(name):
	if OSX:
		env_name = "__"+name.replace("-", "_")
		return	env_name in os.environ
	arg_name = "--%s" % name
	global args
	if arg_name not in args:
		return False
	args.remove(arg_name)
	return	True
def get_arg(name):
	if OSX:
		env_name = "__"+name.replace("-", "_")
		return	os.environ.get(env_name)
	arg_name = "--%s="  % name
	for x in args[:]:
		if x.startswith(arg_name):
			args.remove(x)
			return x[len(arg_name):]

QUIET = arg_test("quiet")
if QUIET:
	set_log_to_tty(False)
else:
	set_log_to_tty(True)
DEBUG=arg_test("debug-gst")
logger._debug = DEBUG
LOGFILE = get_arg("log-file")
if LOGFILE:
	set_log_filename(LOGFILE)
	set_log_to_file(True)
	#ensure the log file is created:
	get_log_file()
DAEMON = arg_test("daemon")
PRINT_PID = DAEMON and arg_test("print-pid")
PIPELINE = get_arg("pipeline")
SESSION_NAME = get_arg("session-name")
DOCK_ICON = None
if OSX:
	DOCK_ICON = get_arg("dock-icon")


def start():
	logger.sdebug("initializing name and icon")
	if SESSION_NAME:
		set_application_name()
	if OSX:
		mac_init()
	else:
		set_default_icon()
	logger.slog("creating pipeline")
	player = gst.parse_launch(PIPELINE)
	bus = player.get_bus()
	bus.add_signal_watch()
	def bus_message(bus, message):
		t = message.type
		if t == gst.MESSAGE_EOS:
			player.set_state(gst.STATE_NULL)
			exit()
		elif t == gst.MESSAGE_ERROR:
			player.set_state(gst.STATE_NULL)
			err, debug = message.parse_error()
			logger.slog("err=%s, debug=%s" % (err, debug), bus, message)
			exit()
		else:
			logger.sdebug(None, bus, message)

	bus.connect("message", bus_message)
	logger.slog("starting")
	player.set_state(gst.STATE_PLAYING)
	signal.signal(signal.SIGTERM, sigtermhandler)
	signal.signal(signal.SIGINT, siginthandler)

	global main_loop
	main_loop = gobject.MainLoop()
	try:
		logger.slog("started")
		main_loop.run()
	except KeyboardInterrupt, e:
		logger.slog("exiting on: %s" % e)
	return	0


def terminate(*args):
	logger.slog()
	global main_loop
	if main_loop:
		main_loop.quit()
	else:
		sys.exit(0)


def mac_init():
	if DOCK_ICON and os.path.exists(DOCK_ICON):
		try:
			import gtk.gdk
			import gtkosx_application		#@UnresolvedImport
			macapp = gtkosx_application.Application()
			macapp.connect("NSApplicationBlockTermination", gtk.main_quit)
			try:
				print "mac_init() loading icon from %s" % DOCK_ICON
				pixbuf = gtk.gdk.pixbuf_new_from_file(DOCK_ICON)
				macapp.set_dock_icon_pixbuf(pixbuf)
			except Exception, e:
				logger.serr("error loading %s" % DOCK_ICON, e)
			#try to define a menu:
			menu = gtk.MenuBar()
			# Quit (will be hidden - see below)
			quit_item = gtk.MenuItem("Quit")
			quit_item.connect("activate", terminate)
			menu.add(quit_item)
			#now set the dock/main menu
			menu.show_all()
			quit_item.hide()
			menu.hide()
			# We need to add it to a widget (otherwise it just does not work)
			macapp.hidden_window = gtk.Window()
			macapp.hidden_window.add(menu)
			macapp.set_menu_bar(menu)
			macapp.ready()
		except Exception, e:
			logger.serr("error initializing mac specific components...", e)

def sigtermhandler(self, *args):
	logger.sdebug(None, *args)
	terminate()

def siginthandler(self, *args):
	logger.sdebug(None, *args)
	terminate()


def set_default_icon():
	if OSX:
		return		#dont bother
	try:
		import gtk
		from winswitch.util.paths import WINSWITCH_SHARE_DIR
		icon_file = os.path.join(WINSWITCH_SHARE_DIR, "icons", "winswitch.png")
		if os.path.exists(icon_file):
			gtk.window_set_default_icon_from_file(icon_file)
		else:
			logger.serror("%s not found!" % icon_file)
	except Exception, e:
		#not fatal, just log it
		logger.serr(None, e)

def set_application_name():
	logger.sdebug()
	try:
		sys.argv[0] = SESSION_NAME
		import glib
		glib.set_application_name(SESSION_NAME)
	except Exception, e:
		#not fatal, just log it
		logger.serr(None, e)


def main():
	global args
	#we remove all the arguments we recognized, so there should only be one left (the program name)
	#also the PIPELINE is required:
	if len(args)!=1 or not PIPELINE:
		print("This program is not meant to be used directly")
		print("It is used by WindowSwitch to provide GStreamer sound and video support")
		print("")
		print("")
		EXAMPLE_DEVICE = 'alsa_input.pci-0000_00_14.2.analog-stereo'
		EXAMPLE_DEVICE_MONITOR = 'alsa_output.pci-0000_00_14.2.analog-stereo.monitor'
		EXAMPLE_REC_PIPELINE = "pulsesrc device=%s ! vorbisenc ! gdppay ! queue ! tcpserversink port=5000 host=192.168.42.100" % EXAMPLE_DEVICE_MONITOR
		EXAMPLE_PLAY_PIPELINE = "tcpclientsrc port=5000 host=192.168.42.100 ! gdpdepay ! vorbisdec ! queue ! pulsesink device=%s" % EXAMPLE_DEVICE
		print("illegal number of arguments: %s: %s" % (len(args), args))
		print("usage: %s session-name gstpipeline" % sys.argv[0])
		print(" ie: %s '--session-name=TestRec' '--pipeline=%s'" % (args[0], EXAMPLE_REC_PIPELINE))
		print(" ie: %s '--pipeline=%s'" % (args[0], EXAMPLE_PLAY_PIPELINE))
		if sys.platform.startswith("win"):
			input("Press Enter to continue...")
		return	1
	if DAEMON:
		daemonize(PRINT_PID)
	return	start()


if __name__ == "__main__":
	sys.exit(main())
