#!/usr/bin/env python
#
#    Cardapio is an alternative menu applet, launcher, and much more!
#
#    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
#    (at your option) 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/>.
#

# these imports are outside of the "try" block because it defines
# the function fatal_error(), which is used in the "except"
from Misc import fatal_error
import sys

try:
	import Constants
	import dbus
	from dbus.mainloop.glib import DBusGMainLoop

except Exception, exception:
	fatal_error('Loading libraries in Cardapio main', exception)
	sys.exit(1)

# main
DBusGMainLoop(set_as_default = True)
bus = dbus.SessionBus()
bus_request_name = bus.request_name(Constants.BUS_NAME_STR)

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


def start_cardapio(show):

	from Cardapio import Cardapio
	import gtk
	Cardapio(show = show)
	gtk.gdk.threads_enter()
	gtk.main()
	gtk.gdk.threads_leave()


def cardapio_run_in_window():

	import os
	import gnomeapplet
	import gtk
	from gnomepanel.CardapioGnomeAppletFactory import CardapioGnomeAppletFactory

	# make sure Cardapio shows even if using Ubuntu's AppMenu
	os.environ['UBUNTU_MENUPROXY'] = ''

	# open new Cardapio instance
	main_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
	main_window.set_title('Cardapio')
	main_window.connect('destroy', gtk.main_quit)
	app = gnomeapplet.Applet()
	CardapioGnomeAppletFactory(app, None)
	app.reparent(main_window)
	main_window.show_all()
	gtk.gdk.threads_enter()
	gtk.main()
	gtk.gdk.threads_leave()

def cardapio_run_in_mate_window():

	import os
	import mateapplet
	import gtk
	from matepanel.CardapioMateAppletFactory import CardapioMateAppletFactory

	# make sure Cardapio shows even if using Ubuntu's AppMenu
	os.environ['UBUNTU_MENUPROXY'] = ''

	# open new Cardapio instance
	main_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
	main_window.set_title('Cardapio')
	main_window.connect('destroy', gtk.main_quit)
	app = mateapplet.Applet()
	CardapioMateAppletFactory(app, None)
	app.reparent(main_window)
	main_window.show_all()
	gtk.gdk.threads_enter()
	gtk.main()
	gtk.gdk.threads_leave()

def cardapio_run_standalone_but_hidden():

	# if there's no other instance, start hidden Cardapio
	if bus_request_name == dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER:
		start_cardapio(show = Constants.DONT_SHOW)


def cardapio_show(centered = False):

	if centered:
		position = Constants.SHOW_CENTERED
		dbus_method_name = 'show_hide'
	else:
		position = Constants.SHOW_NEAR_MOUSE
		dbus_method_name = 'show_hide_near_mouse'

	# if there's no other instance - start Cardapio
	if bus_request_name == dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER:
		start_cardapio(show = position)

	# if there is - "show / hide" it
	else:
		dbus_method = bus.get_object(Constants.BUS_NAME_STR, Constants.BUS_OBJ_STR).get_dbus_method(dbus_method_name)
		dbus_method()


def cardapio_open_options_dialog():

	# if there's no other instance, quit
	if bus_request_name == dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER:
		print('Cardapio is not running. Aborting...')
		sys.exit(2)

	# if there is, show its options dialog
	dbus_method_name = 'open_options_dialog'
	dbus_method = bus.get_object(Constants.BUS_NAME_STR, Constants.BUS_OBJ_STR).get_dbus_method(dbus_method_name)
	dbus_method()


def cardapio_show_near_docky():

	# if there's no other instance - start hidden Cardapio
	if bus_request_name == dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER:
		start_cardapio(show = Constants.DONT_SHOW)

	else:
		from docky.DockySettingsHelper import DockySettingsHelper, MainDockError

		try:
			settings_helper = DockySettingsHelper()
			dock_num = settings_helper.get_main_dock()

			x, y, force_anchor_right, force_anchor_bottom = settings_helper.get_best_position(dock_num)

			dbus_method_name = 'show_hide_near_point'
			dbus_method = bus.get_object(Constants.BUS_NAME_STR, Constants.BUS_OBJ_STR).get_dbus_method(dbus_method_name)
			dbus_method(x, y, force_anchor_right, force_anchor_bottom)

		except MainDockError, exception:
			fatal_error("Couldn't find the main dock of Docky! " + str(exception))

		except Exception, exception:
			fatal_error('Unknown error with Cardapio in Docky!', exception)


# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


if len(sys.argv) == 2:

	if sys.argv[1] == 'run-in-window':
		cardapio_run_in_window()

	if sys.argv[1] == 'run-in-mate-window':
		cardapio_run_in_mate_window()

	elif sys.argv[1] == 'hidden':
		cardapio_run_standalone_but_hidden()

	elif sys.argv[1] == 'show':
		cardapio_show(centered = True)

	elif sys.argv[1] == 'show-near-mouse':
		cardapio_show(centered = False)

	elif sys.argv[1] == 'docky-open':
		cardapio_show_near_docky()

	elif sys.argv[1] == 'options':
		cardapio_open_options_dialog()

	elif sys.argv[1] == '--help':
		print('Usage: cardapio [option]')
		print('Options:')
		print('  show                - Show Cardapio centered. This is the default behavior.')
		print('  show-near-mouse     - Show Cardapio close to the mouse pointer.')
		print('  hidden              - Load Cardapio but do not show it yet.')
		print('  options             - Show Cardapio\'s preferences window')
		print('  run-in-window       - Used for debugging the Gnome Panel applet.')
		print('  run-in-mate-window  - Used for debugging the Mate Panel applet.')
		print('If Cardapio is already loaded, both "show" and "show-near-mouse" simply show the existing instance. That is, they do not load a new Cardapio instance.')

else:
	cardapio_show(centered = True)
