#!/usr/bin/env python3

# Copyright (C) 2014-2015 Inuvika Inc.
# http://www.inuvika.com
# Author Julien Langlois <j.langlois@inuvika.com> 2014
# Author David Pham-Van <d.phamvan@inuvika.com> 2014, 2015
#
# Copyright (C) 2013 Ulteo SAS
# http://www.ulteo.com
# Author David PHAM-VAN <d.pham-van@ulteo.com> 2013
#
# 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; version 2
# of the License
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


import os
import sys
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
gi.require_version("Gdk", "3.0")
from gi.repository import Gdk
import gettext
import time
import subprocess
import tempfile
import fcntl


try:
	_ = gettext.translation("ovd-client", localedir=os.environ.get("LOCALEDIR"), codeset="utf-8").gettext
except:
	print("Unable to load translation", file=sys.stderr)
	_ = lambda string: string


class LogoutDialog:
	FULLSCREEN_MASK = True
	KILLALL = False

	def createButton(self, label=None, image=None):
		_button = Gtk.Button()
		_box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
		_box.set_border_width(2)
		_image = Gtk.Image()
		_image.set_from_icon_name(image, Gtk.IconSize.DIALOG)
		_label = Gtk.Label.new(label)
		_box.pack_start(_image, False, False, 3)
		_box.pack_start(_label, False, False, 3)
		_button.add(_box)
		return _button


	def draw_on_top(self, widget, cr):
		pict = self.screenshot[widget]
		Gdk.cairo_set_source_pixbuf(cr, pict, 0, 0)
		cr.rectangle(0, 0, pict.get_width(), pict.get_height())
		cr.fill()
		return True


	def __init__(self):
		self.lock()
		self.screenshot = {}
		self.top = []

		display = Gdk.Display.get_default()
		root_window = Gdk.get_default_root_window()
		if self.FULLSCREEN_MASK:
			for i in range(display.get_n_monitors()):
				monitor = display.get_monitor(i)
				g = monitor.get_geometry()

				screenshot = Gdk.pixbuf_get_from_window(root_window, g.x, g.y, g.width, g.height)
				screenshot.saturate_and_pixelate(screenshot, 0, True)

				top = Gtk.Window.new(Gtk.WindowType.TOPLEVEL)

				hbbox = Gtk.HButtonBox()
				top.add(hbbox)
				hbbox.connect('draw', self.draw_on_top)
				hbbox.show()
				self.screenshot[hbbox] = screenshot
				top.move(g.x, g.y)
				top.fullscreen()
				top.show()
				self.top.append(top)

		self.window = Gtk.Window.new(Gtk.WindowType.TOPLEVEL | Gtk.WindowType.POPUP)
		self.window.set_resizable(False)
		self.window.set_modal(True)
		if hasattr(self.window, "set_can_focus"):
			self.window.set_can_focus(True)

		if self.FULLSCREEN_MASK:
			self.window.set_decorated(False)
			self.window.set_transient_for(self.top[0])

		self.window.connect("destroy", self.destroy)
		self.window.set_title(_("Logout"))
		self.window.set_border_width(10)

		vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5)
		vbox.set_border_width(10)
		self.window.add(vbox)

		self.label = Gtk.Label.new("<b>{msg}</b>".format(msg=_("Are you sure you want to logout?")))
		self.label.set_use_markup(True)
		self.label.set_margin_bottom(15)
		vbox.pack_start(self.label, False, False, 5)

		btn_vbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 15)
		btn_vbox.set_homogeneous(True)

		button_disconnect = self.createButton(label=_("Disconnect"), image="media-playback-pause-symbolic")
		button_logout = self.createButton(label=_("Logout"), image="media-playback-stop-symbolic")
		button_cancel = self.createButton(label=_("Cancel"), image="window-close-symbolic")

		button_disconnect.connect("clicked", self.disconnect)
		button_logout.connect("clicked", self.logout)
		button_cancel.connect("clicked", self.destroy)

		vbox.add(btn_vbox)
		btn_vbox.pack_start(button_disconnect, True, True, 0)
		btn_vbox.pack_start(button_logout, True, True, 0)
		btn_vbox.pack_start(button_cancel, True, True, 0)

		self.window.set_focus(button_cancel)
		self.window.set_icon_name("system-log-out")
		self.window.set_position(Gtk.WindowPosition.CENTER)
		self.window.show_all()


	def destroy(self, widget, data=None):
		self.unlock()
		Gtk.main_quit()


	def logout(self, widget):
		self.unlock()
		proc = subprocess.Popen(["xfce4-session-logout", ], shell=True)
		if self.KILLALL:
			start = time.time()
			while proc.poll() == None:
				time.sleep(0.5)
				if time.time() - start > 10:
					subprocess.call("kill -9 -1", shell=True)

		Gtk.main_quit()


	def disconnect(self, widget):
		self.unlock()
		subprocess.call("xrdp-disconnect", shell=True)
		Gtk.main_quit()


	def lock(self):
		self.lockfile = os.path.join(tempfile.gettempdir(), "%s.%d.lock" % (os.path.basename(sys.argv[0]), os.getuid()))
		self.fp = open(self.lockfile, 'w')
		try:
				fcntl.lockf(self.fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
		except IOError:
				print("Another instance is already running, quitting.")
				sys.exit(-1)
		self.locked = True


	def unlock(self):
		if not self.locked:
				return

		try:
			fcntl.lockf(self.fp, fcntl.LOCK_UN)
			if os.path.isfile(self.lockfile):
				os.unlink(self.lockfile)
			self.locked = False
		except Exception as e:
			print("Error: %s" % e)


if __name__ == "__main__":
	LogoutDialog()
	Gtk.main()
