#! /usr/bin/python
#
#         Xfce4-backdrop-manager V 10.09.11
#
#         Copyright (C) 2010, Lachlan Turner (Padfoot) <lochjt@hotmail.com>
#
#         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 2 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, write to the Free Software
#         Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
#         02110-1301 USA

import sys
import os
import subprocess
import ConfigParser

try:
	import gobject
except:
	sys.exit('xfce4-backdrop-manager: Required python module gobject is not installed.')

try:
	import wnck
except:
	sys.exit('xfce4-backdrop-manager: Required python module wnck is not installed.')

# CLASS

class Xfce4backdropmanager:

	path = {'user': os.path.expanduser('~'), 'conf': '.xfce4-backdrop-manager/backdrop.conf'}
	path['xml'] = '.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml'
	path['list'] = os.path.join(path['user'], path['conf'])
	path['dir'] = os.path.dirname(path['list'])
	path['xfconf'] = os.path.join(path['user'], path['xml'])
	desktop = {'screen': wnck.screen_get_default()}
	command = {'xprop': ['xprop', '-root', '_DT_SAVE_MODE']}
	command['mkdir'] = ['mkdir', path['dir']]
	command['xfconf'] = 'xfconf-query,-c,xfce4-desktop'
	command['property'] = ',-p,/backdrop/screen0/monitor0/%s'
	command['single'] = ',-s,%s'
	command['array'] = ',-t,uint,-s,%s,-t,uint,-s,%s,-t,uint,-s,%s,-t,uint,-s,%s'
	keys = {'image-path': False, 'image-style': False, 'image-show': False, 'color-style': False, 'color1': True, 'color2': True}
	enum = {'pipe': subprocess.PIPE, 'session': 'xfce4', 'manager': 'Xfwm4', 'keyerror': 'does not exist'}
	signal = {'changed': 'active-workspace-changed', 'created': 'workspace-created'}
	signal['destroyed'] = 'workspace-destroyed'
	signal['background'] = 'background-changed'
	signal['manager'] = 'window-manager-changed'
	signal['ignore'] = False
	state = True
	error = {'header': 'xfce4-backdrop-manager:', 'manager': ' Xfwm4 window manager is not in use.', 'session': ' Desktop session is not Xfce', 'version': ' Required version of Xfce (4.6+) is not installed.', 'list': ''}
	mainloop = gobject.MainLoop()

	def __init__(self):

		self.desktop['screen'].force_update()
		session = subprocess.Popen(self.command['xprop'], stdout=self.enum['pipe']).communicate()[0]
		if self.enum['session'] not in session:
			self.state = False
			self.error['list'] = self.error['session']
		if self.desktop['screen'].get_window_manager_name() not in self.enum['manager']:
			self.state = False
			self.error['list'] = self.error['list'] + self.error['manager']
		if not os.path.isfile(self.path['xfconf']):
			self.state = False
			self.error['list'] = self.error['list'] + self.error['version']
		if self.state:
			self.get_workspaces(self.desktop['screen'])
			self.get_current_backdrop()
			self.get_backdrop_list()
			self.changed_workspace(self.desktop['screen'], self.desktop['workspace_active'])
			self.connect_signals()

	def main(self):
		if self.state:
			self.mainloop.run()
		else:
			error = self.error['header'] + self.error['list']
			sys.exit(error)
		sys.exit(0)

	def connect_signals(self):
		self.desktop['screen'].connect(self.signal['changed'], self.changed_workspace)
		self.desktop['screen'].connect(self.signal['created'], self.created_workspace)
		self.desktop['screen'].connect(self.signal['destroyed'], self.destroyed_workspace)
		self.desktop['screen'].connect(self.signal['background'], self.changed_backdrop)
		self.desktop['screen'].connect(self.signal['manager'], self.manager_changed)

	def get_backdrop_list(self):
		self.desktop['backdrop_list'] = {}
		if os.path.isfile(self.path['list']):
			self.conf = ConfigParser.ConfigParser()
			self.conf.read(self.path['list'])
			for section in self.conf.sections():
				self.desktop['backdrop_list'][section] = {}
				for item in self.conf.items(section):
					if self.keys[item[0]]:
						self.desktop['backdrop_list'][section][item[0]] = item[1].split(',')
					else:
						self.desktop['backdrop_list'][section][item[0]] = item[1]
		else:
			if not os.path.exists(self.path['dir']):
				command = self.command['mkdir']
				result = subprocess.Popen(command, stdout=self.enum['pipe']).communicate()[0]
			self.conf = ConfigParser.ConfigParser()
			for item in range(len(self.desktop['workspace_list'])):
				self.create_section(item)
		workspaces = len(self.desktop['workspace_list'])
		backdrops = len(self.desktop['backdrop_list'].keys())
		if backdrops < workspaces:
			for item in range(workspaces - backdrops):
				self.create_section(item + backdrops)
		if workspaces < backdrops:
			for item in range(backdrops - workspaces):
				section = 'workspace' + str(item + workspaces)
				self.conf.remove_section(section)
				del self.desktop['backdrop_list'][section]
		self.save_backdrop_list()

	def create_section(self, workspace):
		section = 'workspace' + str(workspace)
		self.conf.add_section(section)
		self.desktop['backdrop_list'][section] = {}
		self.set_options(section)

	def set_options(self, section):
		for item in self.keys:
			if self.keys[item]:
				data = '%s,%s,%s,%s' % tuple(self.desktop[item])
			else:
				data = self.desktop[item]
			self.desktop['backdrop_list'][section][item] = self.desktop[item]
			self.conf.set(section, item, data)

	def save_backdrop_list(self):
		with open(self.path['list'], 'wb') as conf:
			self.conf.write(conf)

	def get_current_backdrop(self):
		for item in self.keys:
			command = self.command['xfconf'] + self.command['property'] % (item)
			result = subprocess.Popen(command.split(','), stdout=self.enum['pipe']).communicate()[0]
			if self.enum['keyerror'] in result:
				if self.keys[item]:
					result = '\n\ndefault\ndefault\ndefault\ndefault'
				else:
					result = 'default'
			else:
				if self.keys[item]:
					data = result.rstrip('\n').split('\n')
					data.pop(0)
					data.pop(0)
					self.desktop[item] = data
				else:
					self.desktop[item] = result.rstrip('\n')

	def get_workspaces(self, screen):
		self.desktop['workspace_list'] = screen.get_workspaces()
		self.desktop['workspace_active'] = screen.get_active_workspace()
		if not self.desktop['workspace_active']:
			self.desktop['workspace_active'] = self.desktop['workspace_list'][0]
		self.desktop['workspace_current'] = self.desktop['workspace_active'].get_number()

	def changed_backdrop(self, screen):
		self.get_current_backdrop()
		if self.signal['ignore']:
			self.signal['ignore'] = False
		else:
			section = 'workspace' + str(self.desktop['workspace_current'])
			self.set_options(section)
			self.save_backdrop_list()

	def changed_workspace(self, screen, workspace):
		self.get_workspaces(self.desktop['screen'])
		section = 'workspace' + str(self.desktop['workspace_current'])
		for item in self.keys:
			action = True
			command = self.command['xfconf'] + self.command['property'] % (item)
			if self.keys[item]:
				if self.desktop['backdrop_list'][section][item][0] == 'default':
					action = False
				else:
					command = command + self.command['array'] % tuple(self.desktop['backdrop_list'][section][item])
			else:
				if self.desktop['backdrop_list'][section][item] == 'default':
					action = False
				else:
					command = command + self.command['single'] % (self.desktop['backdrop_list'][section][item])
			if action:
				self.signal['ignore'] = True
				result = subprocess.Popen(command.split(','), stdout=self.enum['pipe']).communicate()[0]

	def created_workspace(self, screen, workspace):
		self.create_section(workspace.get_number())
		self.save_backdrop_list()

	def destroyed_workspace(self, screen, workspace):
		section = 'workspace' + str(workspace.get_number())
		self.conf.remove_section(section)
		del self.desktop['backdrop_list'][section]
		self.save_backdrop_list()
		self.get_workspaces(screen)

	def manager_changed(self, screen):
		self.mainloop.quit()
		error = self.error['header'] + self.error['manager']
		sys.exit(error)

if __name__ == '__main__':
	applet = Xfce4backdropmanager()
	applet.main()
