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

import gtk, zipfile, re, ConfigParser, os, gobject
from distutils import version
from lib import about, scrollframe, appinfo_reader, descappbox, modifs, progress_dialog

class PackageInstaller(gtk.Window):
	"""Fenêtre principale"""
	def __init__(self, db, filename=None):
		"""Création de la fenêtre"""
		self.db = db
		self.actualfile = filename
		self.handler_id = None
		
		# Configure l'affichage des icônes dans les boutons
		gtksettings = gtk.settings_get_default()
		gtksettings.set_long_property('gtk-button-images', 1, '')
		
		# Création de la fenetre
		gtk.Window.__init__(self)
		self.set_default_size(450, -1)
		self.set_title("Installeur de paquets")
		self.set_icon_list(gtk.gdk.pixbuf_new_from_file("icons/SynApps16.png"), gtk.gdk.pixbuf_new_from_file("icons/SynApps24.png"), gtk.gdk.pixbuf_new_from_file("icons/SynApps32.png"), gtk.gdk.pixbuf_new_from_file("icons/SynApps64.png"), gtk.gdk.pixbuf_new_from_file("icons/SynApps128.png"))
		self.connect("destroy", self.close)
		
		self.vboxprinc = gtk.VBox()
		self.add(self.vboxprinc)
		
		# Barre de menus
		self.create_menubar()
		self.vboxprinc.pack_start(self.menubar, False, False)
		
		table = gtk.Table()
		table.set_border_width(5)
		table.set_row_spacings(5)
		table.set_col_spacings(5)
		self.vboxprinc.pack_start(table, False, True)
		
		self.icon = gtk.image_new_from_file("icons/install.png")
		table.attach(self.icon, 0, 1, 0, 2, gtk.FILL, gtk.FILL)
		
		label = gtk.Label()
		label.set_use_markup(True)
		label.set_markup("<b>Paquet :</b>")
		label.set_alignment(0.0, 0.5)
		table.attach(label, 1, 2, 0, 1, gtk.FILL, gtk.FILL|gtk.EXPAND)
		
		self.namelabel = gtk.Label()
		self.namelabel.set_alignment(0.0, 0.5)
		table.attach(self.namelabel, 2, 3, 0, 1, gtk.FILL, gtk.FILL|gtk.EXPAND)
		
		label = gtk.Label()
		label.set_use_markup(True)
		label.set_markup("<b>État :</b>")
		label.set_alignment(0.0, 0.5)
		table.attach(label, 1, 2, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND)
		
		self.statelabel = gtk.Label()
		self.statelabel.set_alignment(0.0, 0.5)
		table.attach(self.statelabel, 2, 3, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND)
		
		self.button = gtk.Button(stock=gtk.STOCK_APPLY)
		self.button.get_child().get_child().get_children()[1].set_label("Installer le paquet")
		self.button.set_sensitive(False)
		table.attach(self.button, 3, 4, 0, 2, gtk.FILL, 0)
		
		# Détails
		self.expander = gtk.Expander("Détails")
		self.vboxprinc.pack_start(self.expander, True, True)
		
		self.appdetails = descappbox.DescAppBox(self.db)
		scroll = scrollframe.scrollframe()
		scroll.add_with_viewport(self.appdetails)
		
		self.expander.add(scroll)
		
		# Barre d'état
		self.statusbar = gtk.Statusbar()
		self.statusbar.set_has_resize_grip(True)
		self.statusid = self.statusbar.get_context_id("default")
		
		self.vboxprinc.pack_start(self.statusbar, False, False)
		
		self.open_package(filename)
	
	def run(self):
		gtk.Window.show_all(self)
		
	def open_package(self, filename):
		self.appdetails.hide_all()
		if filename == None:
			return
		
		try:
			infos = appinfo_reader.get_package_infos(filename)
		except IOError as message:
			errordialog = gtk.MessageDialog(self, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, str(message))
			errordialog.run()
			errordialog.destroy()
			return
		
		self.actualfile = filename
		
		app = self.db.get_app(name=infos["name"])
		
		infos["state"] = 0
		
		if app != None:
			if app["state"] > 0:
				infos["state"] = 1
				infos["installedversion"] = app["installedversion"]
				if version.LooseVersion(infos["version"]) == version.LooseVersion(app["installedversion"]):
					infos["state"] = 2
				elif version.LooseVersion(infos["version"]) > version.LooseVersion(app["installedversion"]):
					infos["state"] = 3
		
		self.namelabel.set_text(infos["name"] + " (" + infos["version"] + ")")
		self.set_state(infos["state"])
		self.icon.set_from_file(infos["icon"])
		
		if self.handler_id != None:
			self.button.handler_disconnect(self.handler_id)
		
		self.handler_id = self.button.connect("clicked", self.apply, filename, infos)
		
		infos["icon"] = ""
		infos["appid"] = 0
		
		self.appdetails.display(infos)
	
	def set_state(self, state):
		self.statelabel.set_text(["Cette application n'est pas installée", "Une version plus récente est déjà installée", "La même version est déjà installée", "Cette version est plus récente"][state])
		
		self.button.get_child().get_child().get_children()[1].set_label(["Installer le paquet", "Installer le paquet", "Installer le paquet", "Mettre à jour le paquet"][state])
		self.button.set_sensitive([True, False, False, True][state])
	
	def apply(self, widget, filename, infos):
		if infos["state"] == 0:
			dialog = modifs.modifs(self, self.db)
			dialog.connect("destroy", self.refresh)
			dialog.install_package(filename, infos)
		if infos["state"] == 3:
			dialog = modifs.modifs(self, self.db)
			dialog.connect("destroy", self.refresh)
			dialog.update_package(filename, infos)
	
	def refresh(self, widget=None):
		"""Actualise les listes."""
		self.refresh_finished = False
		dialog = progress_dialog.progress_dialog()
		dialog.run()
		dialog.connect("destroy", self.refresh_end)
		
		gobject.idle_add(self.thread_refresh, dialog)

	def thread_refresh(self, dialog):
		try:
			self.db.update()
		except IOError as message:
			errordialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, str(message))
			errordialog.run()
			errordialog.destroy()
			
		self.refresh_finished = True
		dialog.destroy()
		
		return False

	def refresh_end(self, widget):
		if self.refresh_finished:
			self.open_package(self.actualfile)
	
	def create_menubar(self):
		"""Création de la barre de menus"""
		accelgrp = gtk.AccelGroup()
		self.add_accel_group(accelgrp)
		
		self.menubar = gtk.MenuBar()
		
		# Menu fichier
		menuitem = gtk.MenuItem(_("_Fichier"), True)
		menu = gtk.Menu()
		menuitem.set_submenu(menu)
		self.menubar.append(menuitem)
		
		item = gtk.ImageMenuItem("gtk-open", accelgrp)
		key, mod = gtk.accelerator_parse("<Ctrl>O")
		item.add_accelerator("activate", accelgrp, key, mod, gtk.ACCEL_VISIBLE)
		item.connect("activate", self.ouvrir)
		menu.append(item)
		
		item = gtk.ImageMenuItem("gtk-refresh", accelgrp)
		key, mod = gtk.accelerator_parse("<Ctrl>R")
		item.add_accelerator("activate", accelgrp, key, mod, gtk.ACCEL_VISIBLE)
		item.connect("activate", self.refresh)
		menu.append(item)
		
		menu.append(gtk.SeparatorMenuItem())
	
		item = gtk.ImageMenuItem("gtk-quit", accelgrp)
		key, mod = gtk.accelerator_parse("<Ctrl>Q")
		item.add_accelerator("activate", accelgrp, key, mod, gtk.ACCEL_VISIBLE)
		item.connect("activate", self.close)
		menu.append(item)
		
		# Menu aide
		menuitem = gtk.MenuItem("_Aide", True)
		menu = gtk.Menu()
		menuitem.set_submenu(menu)
		self.menubar.append(menuitem)
		
		item = gtk.ImageMenuItem("gtk-about")
		item.connect("activate", about.about, self.db)
		menu.append(item)
		
	def ouvrir(self, widget = None):
		dialog = gtk.FileChooserDialog("Ouvrir un paquet", self, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
		resp = dialog.run()
		
		if resp == gtk.RESPONSE_OK:
			self.open_package(dialog.get_filename())
			
		dialog.destroy()
		
	def close(self, widget = None):
		gtk.main_quit()

		
def _(str):
	return str
