#!/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 pygtk
pygtk.require("2.0")
import gtk

from winswitch.consts import APPLICATION_NAME
from winswitch.ui import icons
from winswitch.ui.tray_util import BaseTray
from winswitch.util.main_loop import callLater
from winswitch.ui.ui_util import get_ui_util


class WindowFakeTray(BaseTray):

	def __init__(self, popup_menu, activate_menu, exit_cb, ask_quit, default_icon_name):
		self.layout = None
		self.ui_util = get_ui_util()
		BaseTray.__init__(self, popup_menu, activate_menu, exit_cb, ask_quit, default_icon_name)

	def setup_widget(self):
		self.slog()
		w = gtk.Window()
		w.set_title("%s Menu" % APPLICATION_NAME)
		def ask(*args):
			self.ask_quit()
			return	True
		w.connect('delete_event', ask)
		self.scroll = gtk.ScrolledWindow()
		self.scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
		self.scroll.set_shadow_type(gtk.SHADOW_NONE)
		w.add(self.scroll)
		w.set_default_size(192, 168)
		self.viewport = gtk.Viewport()
		self.scroll.add(self.viewport)
		self.vbox = None
		self.ui_util.add_close_accel(w, self.ask_quit)
		self.tray_widget = w
		self.set_icon(self.default_icon_name)
		self.menu_shown = None
		self.pending_menu = None

	def close(self):
		if self.tray_widget:
			self.pending_menu = None
			self.tray_widget.hide()
			self.tray_widget.destroy()
			self.tray_widget = None

	def ready(self):
		self.tray_widget.show_all()

	def set_icon(self, icon_name):
		icon = icons.get(icon_name)
		self.tray_widget.set_icon(icon)

	def request_attention(self, message, delay):
		self.tray_widget.set_urgency_hint(True)
		callLater(delay, self.tray_widget.set_urgency_hint, False)

	def set_menu(self, menu):
		""" if the menu is not in use, replace it
			otherwise, wait for menu_deactivated() to do it
		"""
		if not self.menu_shown:
			self.do_set_menu(menu)
		else:
			self.pending_menu = menu

	def do_set_menu(self, menu):
		sh = self.tray_widget.get_screen().get_height()
		abs_max_h = 2000
		abs_min_h = 100
		max_h = min(max(abs_min_h, sh*0.90), abs_max_h)
		try:
			va = self.scroll.get_vadjustment().value
			oldbox = self.vbox
			self.vbox = gtk.VBox()
			for x in menu.get_children():
				b = self.menuitem_to_widget(x)
				if b:
					self.vbox.add(b)
				menu.remove(x)
			self.vbox.show_all()
			if oldbox:
				self.viewport.remove(oldbox)
			self.viewport.add(self.vbox)
			w,h = self.vbox.size_request()
			h = min(max(h, abs_min_h), max_h)
			self.scroll.set_size_request(w, h)
			vadj = self.scroll.get_vadjustment()
			vadj.set_value(max(min(va, vadj.upper), vadj.lower))
			self.tray_widget.set_size_request(w+2, h+8)
		except Exception, e:
			self.serr(None, e, menu)

	def menu_deactivated(self, *args):
		self.sdebug("pending_menu=%s" % self.pending_menu, *args)
		self.menu_shown = None
		if self.pending_menu:
			self.do_set_menu(self.pending_menu)
			self.pending_menu = None

	def menuitem_to_widget(self, item):
		if type(item)==gtk.SeparatorMenuItem:
			h = gtk.HBox(False, 0)
			h.set_size_request(-1, 12)
			return	h
		if not isinstance(item, gtk.MenuItem) or type(item) in [gtk.CheckMenuItem]:
			self.sdebug("skipping %s" % type(item), item)
			return	None
		image = None
		if isinstance(item, gtk.ImageMenuItem):
			image = item.get_image()
		label = item.get_label()
		tooltip = item.get_tooltip_text()
		submenu = item.get_submenu()
		item.show_all()
		def button_action(button, mouse_button, event_time):
			self.slog("item=%s" % item, button, mouse_button, event_time)
			if submenu:
				self.menu_shown = submenu
				submenu.connect("deactivate", self.menu_deactivated)
				submenu.popup(None, None, None, mouse_button, event_time)
			else:
				button._source_menu_item_.activate()
		def button_clicked(button):
			self.slog("item=%s" % item, button)
			button_action(button, 1, 0)
		def button_release(button, event):
			self.slog("item=%s" % item, button, event)
			button_action(button, event.button, event.time)
			return	True	#prevents button_clicked from firing!
		b = self.ui_util.imagebutton(label, None, tooltip)
		b.connect('button-release-event', button_release)
		b.connect("clicked", button_clicked)
		b._source_menu_item_ = item
		b.set_sensitive(item.get_sensitive())
		if image:
			b.set_image(image)
		return b
