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

import gtk, gobject, framakiosk, io

class CatList(gtk.TreeView):
	"""Liste des catégories"""
	def __init__(self, config):
		"""Création de l'arbre"""
		self.config = config
		self.store = store(config)
		gtk.TreeView.__init__(self, self.store)
		self.set_headers_visible(False)
		
		targets = [("FKTUNE_LINK", gtk.TARGET_SAME_WIDGET, 0)]
		
		# Glisser-déposer
		self.enable_model_drag_source(gtk.gdk.BUTTON1_MASK|gtk.gdk.CONTROL_MASK, targets, gtk.gdk.ACTION_MOVE|gtk.gdk.ACTION_COPY)
		self.enable_model_drag_dest(targets, gtk.gdk.ACTION_MOVE|gtk.gdk.ACTION_COPY)
		self.connect("drag_data_received", self.drop)
		
		# Création des colonnes
		self.colonnetext = gtk.TreeViewColumn()
		self.colonnepixbuf = gtk.TreeViewColumn()
		
		self.append_column(self.colonnepixbuf)
		self.append_column(self.colonnetext)
		
		self.cellpixbuf = gtk.CellRendererPixbuf()
		self.celltext = gtk.CellRendererText()
		
		self.colonnepixbuf.pack_start(self.cellpixbuf, True)
		self.colonnetext.pack_start(self.celltext, True)
		self.colonnepixbuf.add_attribute(self.cellpixbuf, 'pixbuf', 0)
		self.colonnetext.add_attribute(self.celltext, 'markup', 1)
		
	def drop(self, widget, context, x, y, selection, info, time):
		path, pos = widget.get_dest_row_at_pos(x, y)
		store, iter = widget.get_selection().get_selected()
		target = store.get_iter(path)
		if self.check_drop(store, iter, target, pos) and context.action == gtk.gdk.ACTION_MOVE:
			self.move_iter(widget, store, iter, target, pos)
			context.finish(True, True, time)
		elif self.check_drop(store, iter, target, pos) and context.action == gtk.gdk.ACTION_COPY:
			self.move_iter(widget, store, iter, target, pos)
			context.finish(True, False, time)
		else:
			context.finish(False, False, time)
	
	def delete(self, widget=None):
		(store, iter) = self.get_selection().get_selected()
		src = store.iter_parent(iter)
		src_link = store.get_value(src, 2)
				
		next = store.iter_next(iter)
		if next is None:
			next = store.iter_parent(iter)
		
		if store.get_value(iter, 2).get("type") not in ["index", "panel_part", "categories"]:
			store.remove(iter)
			if src_link.get("type") in ["cat-apps", "cat-subpages"] and not store.iter_has_child(src):
				src_link.set("type", "cat")
		
		self.get_selection().select_iter(next)
		self.emit("cursor-changed")
		
	def key_event(self, widget, event):
		if gtk.gdk.keyval_name(event.keyval) == "Delete":
			self.delete()
	
	def check_drop(self, store, iter, target, pos):
		path = store.get_path(iter)
		target_path = store.get_path(target)
		type = store.get_value(iter, 2).get("type")
		target_type = store.get_value(target, 2).get("type")
		if target_path[0:len(path)] == path:
			return False
		elif type in ["index", "panel_part", "categories"]:
			return False
		elif type in ["cat", "cat-apps", "cat-subpages"] and target_type != "categories" and (pos == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE or pos == gtk.TREE_VIEW_DROP_INTO_OR_AFTER):
			return False
		elif type in ["cat", "cat-apps", "cat-subpages"] and target_type not in ["cat", "cat-apps", "cat-subpages"] and (pos == gtk.TREE_VIEW_DROP_BEFORE or pos == gtk.TREE_VIEW_DROP_AFTER):
			return False
		elif type in ["app", "separator", "panel_icon", "panel_sep"] and target_type not in ["cat", "cat-apps", "panel_part"] and (pos == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE or pos == gtk.TREE_VIEW_DROP_INTO_OR_AFTER):
			return False
		elif type in ["app", "separator", "panel_icon", "panel_sep"] and target_type not in ["app", "separator", "panel_icon", "panel_sep"] and (pos == gtk.TREE_VIEW_DROP_BEFORE or pos == gtk.TREE_VIEW_DROP_AFTER):
			return False
		elif type == "subpage" and target_type not in ["cat", "cat-subpages"] and (pos == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE or pos == gtk.TREE_VIEW_DROP_INTO_OR_AFTER):
			return False
		elif type == "subpage" and target_type != "subpage" and (pos == gtk.TREE_VIEW_DROP_BEFORE or pos == gtk.TREE_VIEW_DROP_AFTER):
			return False
		elif type == "panel_clock" and target_type != "panel_part" and (pos == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE or pos == gtk.TREE_VIEW_DROP_INTO_OR_AFTER):
			return False
		elif type == "panel_clock" and target_type not in ["panel_icon", "panel_sep"] and (pos == gtk.TREE_VIEW_DROP_BEFORE or pos == gtk.TREE_VIEW_DROP_AFTER):
			return False
		else:
			return True
	
	def move_iter(self, widget, store, iter, target, pos):
		src_iter = store.iter_parent(iter)
		
		src = store.get_value(src_iter, 2)
		link = store.get_value(iter, 2)
		target_link = store.get_value(target, 2)
		src_type = src.get("type")
		type = link.get("type")
		target_type = target_link.get("type")
		
		if type in ["app", "separator"] and target_type == "panel_part" and (pos == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE or pos == gtk.TREE_VIEW_DROP_INTO_OR_AFTER):
			link = link.move()
		elif type in ["app", "separator"] and target_type in ["panel_icon", "panel_sep"] and (pos == gtk.TREE_VIEW_DROP_BEFORE or pos == gtk.TREE_VIEW_DROP_AFTER):
			link = link.move()
		elif type in ["panel_icon", "panel_sep"] and target_type in ["cat-apps", "cat"] and (pos == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE or pos == gtk.TREE_VIEW_DROP_INTO_OR_AFTER):
			link = link.move()
		elif type in ["panel_icon", "panel_sep"] and target_type in ["app", "separator"] and (pos == gtk.TREE_VIEW_DROP_BEFORE or pos == gtk.TREE_VIEW_DROP_AFTER):
			link = link.move()
		
		if type == "subpage" and target_type == "cat":
			target_link.set("type", "cat-subpages")
		elif type == "app" and target_type == "cat":
			target_link.set("type", "cat-apps")
		
		if pos == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE or pos == gtk.TREE_VIEW_DROP_INTO_OR_AFTER:
			new = store.append(target, store.link_values(link))
		elif pos == gtk.TREE_VIEW_DROP_BEFORE:
			new = store.insert_before(None, target, store.link_values(link))
		elif pos == gtk.TREE_VIEW_DROP_AFTER:
			new = store.insert_after(None, target, store.link_values(link))
		if store.iter_has_child(iter):
			for i in range(0, store.iter_n_children(iter)):
				next = store.iter_nth_child(iter, i)
				self.move_iter(widget, store, next, new, gtk.TREE_VIEW_DROP_INTO_OR_BEFORE)
		
		if src_type in ["cat-apps", "cat-subpages"] and store.iter_n_children(src_iter) == 1:
			src.set("type", "cat")
		
		self.expand_to_path(self.store.get_path(new))
		self.get_selection().select_iter(new)
		self.emit("cursor-changed")
	
	def update_selection(self):
		(store, iter) = self.get_selection().get_selected()
		
		values = store.link_values(store[store.get_path(iter)][2])
		
		store.set_value(iter, 0, values[0])
		store.set_value(iter, 1, values[1])
	
	def update(self):
		self.store.update()
	
	def add_link(self, widget, type):
		(store, iter) = self.get_selection().get_selected()
		if iter != None:
			selectedtype = store[store.get_path(iter)][2].get("type")
		else:
			selectedtype = None
		if type == "app":
			if selectedtype == "panel_part":
				link = framakiosk.new_panel_icon(self.config)
				parent = iter
				after = None
			elif selectedtype in ["panel_icon", "panel_sep"]:
				link = framakiosk.new_panel_icon(self.config)
				parent = None
				after = iter
			elif selectedtype in ["app", "separator"]:
				link = framakiosk.new_app(self.config)
				parent = None
				after = iter
			elif selectedtype in ["cat", "cat-apps"]:
				link = framakiosk.new_app(self.config)
				parent = iter
				after = None
		elif type == "sep":
			if selectedtype == "panel_part":
				link = framakiosk.new_panel_sep(self.config)
				parent = iter
				after = None
			elif selectedtype in ["panel_icon", "panel_sep"]:
				link = framakiosk.new_panel_sep(self.config)
				parent = None
				after = iter
			elif selectedtype in ["app", "separator"]:
				link = framakiosk.new_sep(self.config)
				parent = None
				after = iter
			elif selectedtype in ["cat", "cat-apps"]:
				link = framakiosk.new_sep(self.config)
				parent = iter
				after = None
		elif type == "cat":
			if selectedtype in ["cat", "cat-apps", "cat-subpages"]:
				link = framakiosk.new_cat(self.config)
				parent = None
				after = iter
			else:
				link = framakiosk.new_cat(self.config)
				parent = self.store.categories
				after = None
		elif type == "clock":
			if selectedtype =="panel_part":
				link = framakiosk.new_clock(self.config)
				parent = iter
				after = None
			elif selectedtype in ["panel_icon", "panel_sep"]:
				link = framakiosk.new_clock(self.config)
				parent = None
				after = iter
		elif type == "subpage":
			if selectedtype == "subpage":
				link = framakiosk.new_subpage(self.config)
				parent = None
				after = iter
			elif selectedtype in ["cat", "cat-subpages"]:
				link = framakiosk.new_subpage(self.config)
				parent = iter
				after = None
				
		new = self.store.append_link_after(parent, after, link)
		
		self.expand_to_path(self.store.get_path(new))
		self.get_selection().select_iter(new)
		self.emit("cursor-changed")

class store(gtk.TreeStore):
	
	def __init__(self, config):
		self.config = config
		self.categories = None
		gtk.TreeStore.__init__(self, gtk.gdk.Pixbuf, str, gobject.TYPE_PYOBJECT)
		
	def update(self):
		self.clear()
		index = self.append_link(None, framakiosk.index(self.config))

	def append_link(self, iter, link):
		newiter = self.append(iter, self.link_values(link))
		
		if link.get("type") == "categories":
			self.categories = newiter
			
		for element in link.get_children():
			self.append_link(newiter, element)
			
	def link_values(self, link):
		theme = self.config.infos['Data']['actualtheme']
		if link.infos["type"] == "panel_icon" :
			return (gtk.gdk.pixbuf_new_from_file(self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/theme/" + theme + "/img/panel/" + link.get("icon")).scale_simple(22,22,gtk.gdk.INTERP_BILINEAR), link.get("name"), link)
		elif link.infos["type"] in ["cat", "cat-apps", "cat-subpages"]:
			return (gtk.gdk.pixbuf_new_from_file(self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/theme/" + theme + "/img/cat/" + link.get("icon")).scale_simple(22,22,gtk.gdk.INTERP_BILINEAR), link.get("name"), link)
		else:
			return (gtk.gdk.pixbuf_new_from_file(self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/" + link.get("icon")).scale_simple(22,22,gtk.gdk.INTERP_BILINEAR), link.get("name"), link)
	
	def append_link_after(self, parent, sibling, link):
		if sibling != None:
			return self.insert_after(parent, sibling, self.link_values(link))
		else:
			return self.append(parent, self.link_values(link))
	
	def get_children(self, iter):
		children = []
		child = self.iter_children(iter)
		
		while child != None:
			link = self.get_value(child, 2)
			link.set("iter", child)
			children.append(link)
			child = self.iter_next(child)
			
		return children
	
	def create_kiosk(self):
		index_iter = self.get_iter_first()
		index = self.get_value(index_iter, 2)
		
		index_code = index.code_start()
		
		for index_child in self.get_children(index_iter):
			index_code += index_child.code_start()
			if index_child.get("type") == "categories":
				for child in self.get_children(index_child.get("iter")):
					index_code += child.code()
					self.create_cat(child.get("iter"))
			else:
				for child in self.get_children(index_child.get("iter")):
					index_code += child.code()
			index_code += index_child.code_end()
		
		index_code += index.code_end()
	
		with io.open(self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/index.html", "w", encoding='utf_8_sig') as fp:
			fp.write(unicode(index_code))

	def create_cat(self, cat_iter):
		cat = self.get_value(cat_iter, 2)
		
		cat_code = cat.code_start()
		
		for child in self.get_children(cat_iter):
			cat_code += child.code()
			if child.get("type") in ["app", "panel_icon"]:
				self.create_app(child)
		
		cat_code += cat.code_end()
		
		with io.open(self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/" + cat.get("page"), "w", encoding='utf_8_sig') as fp:
			fp.write(unicode(cat_code))
	
	def create_app(self, app):
		if app.get("page") != "":
			with io.open(self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/" + app.get("page"), "w", encoding='utf_8_sig') as fp:
				fp.write(unicode(app.code_lch()))
