#!/usr/bin/env python
# -*- coding: utf-8 -*-

#================================================
#
#    wallpapoz.py - Wallpapoz 
#    Copyright (C) 2005 Akbar <akbarhome@gmail.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#================================================

import pygtk
pygtk.require('2.0')
import gtk.glade
import gobject
import os
import sys
sys.path.insert(0, '/usr/share/wallpapoz')
from xml_processing import XMLProcessing

# appGui -- main class for the gui it self
class WallpapozGui:

    # class method -- handling delete event
    def delete_event(self, widget, data=None):
	return False
 
    # class method -- handling destroy event
    def destroy(self, widget):
	gtk.main_quit()

    def main(self):
	gtk.main()

    # the constructor
    def __init__(self):

	# the configuration file
	home = os.environ['HOME']
	self.file = home + "/.wallpapoz/wallpapoz.xml"

	# call the xmlprocessing class to read it
	self.wallpapozxml = XMLProcessing(self.file)

        # so we can call from anywhere
	pathname = os.path.dirname(sys.argv[0])
	os.chdir(os.path.abspath(pathname))

	# Open the glade file doors, Man!
	self.mainGlade = gtk.glade.XML("../share/wallpapoz/wallpapoz.glade")
	self.mainWindow = self.mainGlade.get_widget('mainwindow')
	self.treeView = self.mainGlade.get_widget('treeview')
	self.imageWidget = self.mainGlade.get_widget('picture')
	
	# Here's where we get our callbacks.
	self.mainWindow.connect("delete_event", self.delete_event)
	self.mainWindow.connect("destroy", self.destroy)
	
        # Display wallpaper list with treeview
	self.loadTreeView()

	# create the menu for right click the treeview
	self.menu = gtk.Menu()
	self.add_item = gtk.MenuItem("Add Wallpaper")
	self.change_item = gtk.MenuItem("Change Wallpaper")
	self.delete_item = gtk.MenuItem("Delete Wallpaper")
	self.move_up_item = gtk.MenuItem("Move Up")
	self.move_down_item = gtk.MenuItem("Move Down")
	self.rename_item = gtk.MenuItem("Rename")
	self.add_item.connect("activate", self.addWallpaper)
	self.change_item.connect("activate", self.changeWallpaper)
	self.delete_item.connect("activate", self.deleteWallpaper)
	self.move_up_item.connect("activate", self.moveUp)
	self.move_down_item.connect("activate", self.moveDown)
	self.rename_item.connect("activate", self.renameGroup)
	self.menu.append(self.add_item)
	self.menu.append(self.change_item)
	self.menu.append(self.delete_item)
	self.menu.append(self.move_up_item)
	self.menu.append(self.move_down_item)
	self.add_item.show()
	self.change_item.show()
	self.delete_item.show()
	self.move_up_item.show()
	self.move_down_item.show()
	self.rename_item.show()
	self.type_of_menu = "child" 

	# connect object
	self.treeView.connect_object("event", self.popUpMenu, self.menu)

	# We autoconnect the signals that does not need multiple args
	self.mainGlade.signal_autoconnect({'on_quitbutton_clicked': self.destroy})
	self.mainGlade.signal_autoconnect({'on_aboutbutton_clicked': self.displayAbout})
	self.mainGlade.signal_autoconnect({'on_killbutton_clicked': self.killDaemon})
	self.mainGlade.signal_autoconnect({'on_restartbutton_clicked': self.restartDaemon})
	self.mainGlade.signal_autoconnect({'on_savebutton_clicked': self.saveConfiguration})
	self.mainGlade.signal_autoconnect({'on_preferencesbutton_clicked': self.displayPreferences})
	self.mainGlade.signal_autoconnect({'on_treeview_cursor_changed': self.showImage})
	self.mainGlade.signal_autoconnect({'on_treeview_button_press_event': self.popUpMenu})

    # popup menu
    def popUpMenu(self, widget, event):
	row = self.treeView.get_selection()
	iter = row.get_selected()[1]
	if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3 and iter != None:
	    parent = self.treestore.iter_parent(iter)
	    if parent == None and self.type_of_menu == "child":
		self.menu.remove(self.change_item)
		self.menu.remove(self.delete_item)
		self.menu.insert(self.rename_item, 1)
		self.type_of_menu = "parent"
	    elif parent != None and self.type_of_menu == "parent":
		self.menu.remove(self.rename_item)
		self.menu.insert(self.change_item, 1)
		self.menu.insert(self.delete_item, 2)
		self.type_of_menu = "child"
	    widget.popup(None, None, None, event.button, event.time)
	    return True
	return False

    # rename group function
    def renameGroup(self, widget):
	row = self.treeView.get_selection()
	iter = row.get_selected()[1]
	value = self.treestore.get_value(iter, 1)
	rename_dialog = gtk.Dialog("Rename Group", self.mainWindow, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) )
	rename_dialog.set_default_response(gtk.RESPONSE_ACCEPT)
	vbox_area = rename_dialog.vbox
	label = gtk.Label(" ")
	label.show()
	entryview = gtk.Entry()
	entryview.set_text(value)
	entryview.set_activates_default(True)
	entryview.show()
	leftlabel = gtk.Label(" ")
	leftlabel.show()
	rightlabel = gtk.Label(" ")
	rightlabel.show()
	hbox = gtk.HBox()
	hbox.pack_start(leftlabel)
	hbox.pack_start(entryview)
	hbox.pack_start(rightlabel)
	hbox.show()
	vbox_area.pack_start(label)
	vbox_area.pack_start(hbox)
	vbox_area.set_spacing(4)
	if(rename_dialog.run()==gtk.RESPONSE_CANCEL):
	    rename_dialog.hide()
	else:
	    self.treestore.set_value(iter, 1, entryview.get_text())
	    rename_dialog.hide()

    # add wallpaper function
    def addWallpaper(self, widget):
	filew = gtk.FileChooserDialog("Choose Wallpaper", None)
	cancel_button = filew.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
	ok_button = filew.add_button(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
	cancel_button.connect("clicked", lambda w: filew.hide())
	if filew.run() == gtk.RESPONSE_ACCEPT:
	    row = self.treeView.get_selection()
	    iter = row.get_selected()[1]
	    parent = self.treestore.iter_parent(iter)
	    if parent != None:
		num_of_child = self.treestore.iter_n_children(parent)
		self.treestore.append(parent, [num_of_child+1, filew.get_filename()])
	    else:
		num_of_child = self.treestore.iter_n_children(iter)
		self.treestore.append(iter, [num_of_child+1, filew.get_filename()])
	    filew.hide()

    # change wallpaper function
    def changeWallpaper(self, widget):
	filew = gtk.FileChooserDialog("Choose Wallpaper", None)
	cancel_button = filew.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
	ok_button = filew.add_button(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
	cancel_button.connect("clicked", lambda w: filew.hide())
	if filew.run() == gtk.RESPONSE_ACCEPT:
	    row = self.treeView.get_selection()
	    iter = row.get_selected()[1]
	    self.treestore.set(iter, 1, filew.get_filename())
	    filew.hide()
	    self.showImage(None)

    # delete wallpaper function
    def deleteWallpaper(self, widget):
	row = self.treeView.get_selection()
	iter = row.get_selected()[1]
	parent = self.treestore.iter_parent(iter)
	num_of_child = self.treestore.iter_n_children(parent)
	if(num_of_child==1):
	    message_dialog = gtk.MessageDialog(None, type=gtk.MESSAGE_ERROR, message_format="Every workspace must have\n at least one wallpaper")
	    close_button = message_dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CANCEL)
	    if(message_dialog.run() == gtk.RESPONSE_CANCEL):
		message_dialog.hide()
	    return
	self.treestore.remove(iter)
	# reorder the node
	childiter = self.treestore.iter_children(parent)
	done = 0
	index = 1
	while not done:
	    self.treestore.set(childiter, 0, index)
	    childiter = self.treestore.iter_next(childiter)
	    index += 1
	    if childiter == None:
		done = 1

    # move up wallpaper node function
    def moveUp(self, widget):
	row = self.treeView.get_selection()
	iter = row.get_selected()[1]
	parent = self.treestore.iter_parent(iter)
	if parent != None:
	    parent_path = self.treestore.get_path(iter)[0]
	    path = self.treestore.get_path(iter)[1]
	    if(path!=0):
		before_iter = self.treestore.get_iter((parent_path, path-1))
		self.treestore.move_after(before_iter, iter)
		before_iter_number = self.treestore.get_value(before_iter, 0)
		iter_number = self.treestore.get_value(iter, 0)
		self.treestore.set(before_iter, 0, iter_number)
		self.treestore.set(iter, 0, before_iter_number)
	else:
	    path = self.treestore.get_path(iter)[0]
	    if(path!=0):
		before_iter = self.treestore.get_iter((path-1))
		self.treestore.move_after(before_iter, iter)
		before_iter_number = self.treestore.get_value(before_iter, 0)
		iter_number = self.treestore.get_value(iter, 0)
		self.treestore.set(before_iter, 0, iter_number)
		self.treestore.set(iter, 0, before_iter_number)

    # move down wallpaper node function
    def moveDown(self, widget):
	row = self.treeView.get_selection()
	iter = row.get_selected()[1]
	next_iter = self.treestore.iter_next(iter)
	if(next_iter!=None):
	    self.treestore.move_after(iter, next_iter)
	    next_iter_number = self.treestore.get_value(next_iter, 0)
	    iter_number = self.treestore.get_value(iter, 0)
	    self.treestore.set(next_iter, 0, iter_number)
	    self.treestore.set(iter, 0, next_iter_number)

    # function to kill the daemon
    def killDaemon(self, widget):
	wallpapoz_id_list = os.popen("pgrep -f /usr/bin/daemon_wallpapoz").read().splitlines()
	python_id_list =os.popen("pgrep -f python").read().splitlines()
	for iter in wallpapoz_id_list:
	    if iter in python_id_list:
		os.system("kill " + iter)

    # function to restart the daemon
    def restartDaemon(self, widget):
	self.killDaemon(None)
	os.system("/usr/bin/daemon_wallpapoz &")

    # function to display preferences widget
    def displayPreferences(self, widget):
	input_dialog = gtk.Dialog("Preferences Dialog", self.mainWindow, gtk.DIALOG_MODAL)
	input_dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
	input_dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
	vbox_area = input_dialog.vbox
	check_button = gtk.CheckButton("Show wallpapers in random order")
	if self.wallpapozxml.is_random() == "1":
	    check_button.set_active(True)
	else:
	    check_button.set_active(False)
        label = gtk.Label("Change wallpaper after: ")
	label2 = gtk.Label(" minutes")
	adjustment_time = gtk.Adjustment(1, 1, 9999, 1, 1, 0)
	spin_button = gtk.SpinButton(adjustment_time)
	spin_button.set_value(float(self.wallpapozxml.delay()))
	label.show()
	label2.show()
	spin_button.show()
	hbox = gtk.HBox( False, 0 )
	hbox.pack_start(label)
	hbox.pack_start(spin_button)
	hbox.pack_start(label2)
	hbox.show()
	check_button.show()
	vbox_area.pack_start(hbox)
	vbox_area.pack_start(check_button)
	if(input_dialog.run()==gtk.RESPONSE_CANCEL):
	    input_dialog.hide()
	else:
	    time_var = str(int(spin_button.get_value()))
	    random_var = "0"
	    if check_button.get_active():
		random_var = "1"
	    self.wallpapozxml.set_delay(time_var)
	    self.wallpapozxml.set_random(random_var)
	    self.saveConfiguration(None)
	    input_dialog.hide()

    # function to save treeview wallpaper list to xml file
    def saveConfiguration(self, widget):
	wallpaperlist = []
	parentrow = self.treestore.get_iter_first()
	updone = 0
	index = 0
	while not updone:
	    wallpaperlist.append([])
	    childiter = self.treestore.iter_children(parentrow)
	    wallpaperlist[index].append(self.treestore.get_value(parentrow, 1))
	    done = 0
	    while not done:
		wallvar = self.treestore.get(childiter, 1)[0]
		wallpaperlist[index].append(wallvar)
		childiter = self.treestore.iter_next(childiter)
		if childiter == None:
		    done = 1
	    parentrow = self.treestore.iter_next(parentrow)
	    if parentrow == None:
		updone = 1
	    index += 1

	self.wallpapozxml.create_configuration_file(self.file, wallpaperlist, self.wallpapozxml.delay(), self.wallpapozxml.is_random())

    # class method for showing image
    def showImage(self, widget):
	row = self.treeView.get_selection()
	iter = row.get_selected()[1]
	if self.treestore.iter_parent(iter)!=None:
	    refImage = gtk.gdk.pixbuf_new_from_file( self.treestore.get_value(iter, 1) )
	    refImage = refImage.scale_simple( 620, 605, gtk.gdk.INTERP_BILINEAR )
	    self.imageWidget.set_from_pixbuf(refImage)

    # class method for show about dialog
    def displayAbout(self, widget):
	self.aboutDialog = self.mainGlade.get_widget('aboutdialog')
	self.aboutDialog.show()

    def loadTreeView(self):

	# fill the workspace list
	worklist = self.wallpapozxml.fill_list()

	# how many workspace we use
	total_workspace = self.wallpapozxml.get_workspace_num()

        # the treestore
	self.treestore = gtk.TreeStore(gobject.TYPE_INT, gobject.TYPE_STRING)

	# make the wallpaper list
	for i in range(total_workspace):
	    parent = self.treestore.append(None, [i+1, worklist[i].pop(0)])
	    j = 1
	    for wallpaper in worklist[i]:
		self.treestore.append(parent, [j, wallpaper])
		j = j + 1

	# set the model
	self.treeView.set_model(self.treestore)

	# column of treeview
	self.cell = gtk.CellRendererText()

	self.tvcolumn = gtk.TreeViewColumn('Workspace')
	self.treeView.append_column( self.tvcolumn )
	self.tvcolumn.pack_start(self.cell, True)
	self.tvcolumn.add_attribute(self.cell, 'text', 0)

	self.tvcolumn = gtk.TreeViewColumn('Wallpapers')
	self.treeView.append_column( self.tvcolumn )
	self.tvcolumn.pack_start(self.cell, True)
	self.tvcolumn.add_attribute(self.cell, 'text', 1)

	# show the treeview
	self.treeView.show()

if __name__ == "__main__":
    wallpapoz = WallpapozGui()
    wallpapoz.main()
