#!/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 time
import ctypes

from winswitch.util.simple_logger import Logger
from winswitch.globals import WIN32

class XScreenSaverInfo( ctypes.Structure):
	""" typedef struct { ... } XScreenSaverInfo; """
	_fields_ = [('window',      ctypes.c_ulong), # screen saver window
				('state',       ctypes.c_int),   # off,on,disabled
				('kind',        ctypes.c_int),   # blanked,internal,external
				('since',       ctypes.c_ulong), # milliseconds
				('idle',        ctypes.c_ulong), # milliseconds
				('event_mask',  ctypes.c_ulong)] # events

class	WM_Util:
	def	__init__(self):
		Logger(self, log_colour=Logger.HIGHLIGHTED_CRIMSON)

		self.all_failed = False
		self.valid_impl = None
		self.log_flood = 0

	def	try_wnck(self):
		try:
			from winswitch.ui.window_wnck import wnck_wm
			return	wnck_wm()
		except Exception, e:
			self.sdebug("failed to load winswitch.ui.window_wnck: "+ str(e))
		return	None

	def try_xlib(self):
		try:
			from winswitch.ui.window_xlib import xlib_wm
			return	xlib_wm()
		except Exception, e:
			self.sdebug("failed to load winswitch.ui.window_xlib: "+ str(e))
		return	None

	def try_win32(self):
		try:
			from winswitch.ui.window_win32 import win32_wm
			return	win32_wm()
		except Exception, e:
			self.serr("failed to load winswitch.ui.window_win32", e)
		return	None


	def get_impl(self):
		if self.valid_impl:
			return	self.valid_impl
		if not self.all_failed:
			if WIN32:
				try_list = [self.try_win32, self.try_wnck]
			else:
				try_list = [self.try_xlib, self.try_wnck]
				#try_list = [try_wnck, try_xlib]
			for trial in try_list:
				v = trial()
				self.sdebug("%s=%s" % (trial, v))
				if v:
					self.valid_impl = v
					return	self.valid_impl
			self.all_failed = True
		return	None

	def impl(self):
		i = self.get_impl()
		if not i:
			raise Exception("All window manager utility classes failed to load!")
		return	i


	def close_windows(self, pids):
		self.impl().close_windows(pids)

	def minimize_windows(self, pids):
		try:
			self.impl().minimize_windows(pids)
		except Exception, e:
			self.serror("cannot minimize! non fatal: %s" % e, pids)

	def can_check_for_idle(self):
		return self.impl().is_screensaver_running is not None

	def is_idle(self, timeout):
		self.sdebug("impl.is_screensaver_running=%s" % self.impl().is_screensaver_running)
		if self.impl().is_screensaver_running is not None:
			return	self.impl().is_screensaver_running()
		return	False

	def get_our_windows(self):
		return	self.impl().get_our_windows()

	def get_shell_tray_window(self):
		if self.impl().get_shell_tray_window is None:
			return	None
		return	self.impl().get_shell_tray_window()

	def raise_windows(self, pids):
		if self.impl().raise_windows:
			self.impl().raise_windows(pids)

	def get_modifiers_set(self):
		i = self.get_impl()
		if i and i.get_modifiers_set:
			return	i.get_modifiers_set()
		""" fallback gtk.gdk implementation """
		modifiers = []
		try:
			from winswitch.consts import MODIFIER_KEY_SHIFT, MODIFIER_KEY_CONTROL, MODIFIER_KEY_ALT
			import gtk.gdk
			(_,_, mods) = gtk.gdk.get_default_root_window().get_pointer()
			if mods & gtk.gdk.SHIFT_MASK:
				modifiers.add(MODIFIER_KEY_SHIFT)
			if mods & gtk.gdk.CONTROL_MASK:
				modifiers.add(MODIFIER_KEY_CONTROL)
			if mods & gtk.gdk.MOD1_MASK:
				modifiers.add(MODIFIER_KEY_ALT)
		except:
			pass
		return	modifiers



wm_util = None
def get_wm_util():
	global wm_util
	if not wm_util:
		wm_util = WM_Util()
	return	wm_util
get_wm_util()



if __name__ == "__main__":
	wm_util = get_wm_util()
	while True:
		print("is_idle=%s" % wm_util.is_idle())
		time.sleep(1)
