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

import os.path, xml.etree.ElementTree, pyquery, pathutils, ConfigParser, gtk, re, lxml.html, io

#######################
##  Classes de base  ##
#######################

class link():
	"""Lien"""
	def __init__(self, config, page, icon, name, type="link", defaulticon=""):
		self.config = config
		if type == "panel_icon":
			iconpath = "theme/" + self.config.infos['Data']['actualtheme'] + "/img/panel/" + icon
		elif type == "cat":
			iconpath = "theme/" + self.config.infos['Data']['actualtheme'] + "/img/cat/" + icon
		else:
			iconpath = icon
		if not os.path.isfile(self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/" + iconpath):
			if defaulticon == "":
				icon = pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/cat.png")
			else:
				icon = defaulticon
		self.infos = {
			"page" : page,
			"icon" : icon,
			"name" : name,
			"type" : type,
		}
			
	def get(self, key, default=""):
		if self.infos.has_key(key):
			return self.infos[key]
		else:
			return default
			
	def set(self, key, value):
		self.infos[key] = value
	
	def _get_code(self):
		try:
			file = open(self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/" + self.infos["page"])
			data = file.read()
			file.close()
			return data
		except IOError:
			return ""
	
	def _get_pyquery(self):
		try:
			return pyquery.PyQuery(filename=self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/" + self.infos["page"])
		except (IOError, lxml.etree.ParserError):
			return pyquery.PyQuery("<html></html>")
		
	def get_children(self):
		return []
		
	def make_code(self):
		return (self.code_start, self.code_end)

class launcher(link):
	"""Lanceur"""
	def __init__(self, config, page, icon, name, desc, type="launcher", defaulticon="", exe=None, dir=None, param=None):
		if defaulticon == "":
			defaulticon = pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/app.png")
		link.__init__(self, config, page, icon, name, type, defaulticon)
		self.infos["desc"] = desc
		if exe==None and dir==None and param==None:
			exe, dir, param = self.read_lch()
		self.infos["exe"] = exe
		self.infos["dir"] = dir
		self.infos["param"] = param
		
	def read_lch(self):
		try:
			config = ConfigParser.ConfigParser()
			# les lch n'ont pas de caractères accentués, utf_8_sig permet donc de s'assurer qu'ils soient lus
			with io.open(self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/" + self.infos["page"], 'r', encoding='utf_8_sig') as fp:
				config.readfp(fp)
			try: exe = config.get("Launch", "ExecuteFile")
			except ConfigParser.NoOptionError: exe = ""
			try: dir = config.get("Launch", "ExecuteDirectory")
			except ConfigParser.NoOptionError: dir = ""
			try: param = config.get("Launch", "ExecuteParameters")
			except ConfigParser.NoOptionError: param = ""
		except (IOError, ConfigParser.NoSectionError, ConfigParser.ParsingError):
			exe = ""
			dir = ""
			param = ""
		
		return (exe, dir, param)
	
	def code_lch(self):
		return '''[Launch] 
ExecuteFile=''' + self.infos["exe"] + '''
ExecuteDirectory=''' + self.infos["dir"] + '''
ExecuteParameters=''' + self.infos["param"]
	
###############
##  Classes  ##
###############

class index(link):
	"""Index"""
	def __init__(self, config):
		link.__init__(self, config, "index.html", pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/FramaNouille.png"), "Index", "index")
		q = self._get_pyquery()
		self.infos["theme"] = q("link#theme").attr("theme")
		self.infos["title"] = q("title").text()
		config.infos['Data']['actualtheme'] = self.infos["theme"]
		
	def get_children(self):
		return [panel_part(self.config, "left"), panel_part(self.config, "right"), categories(self.config)]
	
	def code_start(self):
		return '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
	<head>
		<title>''' + self.get("title") + '''</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<link id="theme" rel="stylesheet" media="screen" type="text/css" title="Theme" theme="''' + self.get("theme") + '''" href="./theme/''' + self.get("theme") + '''/design.css" />
		<script type="text/javascript" src="./scripts/jquery.js"></script>
		<script type="text/javascript" src="./scripts/mousewheel.js"></script>
		<script type="text/javascript" src="./scripts/ui.js"></script>
		<script type="text/javascript" src="./scripts/css-transform.js"></script>
		<script type="text/javascript" src="./scripts/rotate.js"></script>
		<script type="text/javascript" src="./scripts/color.js"></script>
		<script type="text/javascript" src="./scripts/clock.js"></script>
		<script type="text/javascript" src="./scripts/tooltip.js"></script>
		<script type="text/javascript" src="./scripts/script.js"></script>
	</head>
	<body>
		<div id="panel">\n'''
	
	def code_end(self):
		return '''	</body>
</html>'''
	
class categories(link):
	"""Catégories"""
	def __init__(self, config):
		link.__init__(self, config, "index.html", pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/categories.png"), "Catégories", "categories")
		
	def _get_code(self):
		q = link._get_pyquery(self)
		return q("ul#cat-list").html()
	
	def _get_pyquery(self):
		return pyquery.PyQuery(self._get_code())
		
	def get_children(self):
		list = []
		q = self._get_pyquery()
		for element in q("li"):
			list.append(cat(self.config, element))
		
		return list
	
	def code_start(self):
		return '''		</div>
		<small>Framakey ''' + self.config.get("FramaKioskTune", "FramaVer") + '''</small>
		<ul id="cat-list">\n'''
	
	def code_end(self):
		return '		</ul>\n'

class cat(link):
	"""Catégorie"""
	def __init__(self, config, element, page="", icon="", name=""):
		if element != None:
			link.__init__(self, config, element.get("page", ""), element.get("icon", ""), element.text, "cat")
		else:
			link.__init__(self, config, page, icon, name, "cat")
		
	def get_children(self):
		list = []
		q = self._get_pyquery()
		try:
			for element in q("div"):
				if element.get("class") == "app" and self.get("type") != "cat-subpage":
					self.set("type", "cat-apps")
					list.append(app(self.config, element))
				elif element.get("class") == 'separator' and self.get("type") != "cat-subpage":
					self.set("type", "cat-apps")
					list.append(separator(self.config, element))
				elif element.get("class") == "subtabs" and self.get("type") != "cat-apps":
					self.set("type", "cat-subpages")
					r = pyquery.PyQuery(element)
					for i in r("a"):
						list.append(subpage(self.config, i))
			return list
		except:
			return list
	
	def code(self):
		return '			<li page="' + self.get("page") + '" icon="' + self.get("icon") + '">' + self.get("name") + '</li>\n'
	
	def code_start(self):
		if self.get("type") == "cat-subpages":
			return '''<?xml version="1.0" encoding="UTF-8"?>
<div class="subtabs">\n'''
		else:
			return '<?xml version="1.0" encoding="UTF-8"?>\n'
	
	def code_end(self):
		if self.get("type") == "cat-subpages":
			return '''</div>
<div class="subcontent"></div>'''
		else:
			return ''

class subpage(link):
	"""Sous-page"""
	def __init__(self, config, element, page="", name="", content=""):
		if element != None:
			link.__init__(self, config, element.get("href", ""), pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/subpage.png"), element.text, "subpage")
			self.infos["content"] = open(os.path.join(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", element.get("href", "")), "r").read()
		else:
			link.__init__(self, config, page, pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/subpage.png"), name, "subpage")
			self.infos["content"] = content
	
	def code(self):
		if self.get("page") != "":
			f = open(self.config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/" + self.get("page"), "w")
			f.write(self.get("content"))
			f.close()

		return '	<a href="' + self.get("page") + '">' + self.get("name") + '</a>\n'

class separator(link):
	"""Icône du panel"""
	def __init__(self, config, element, name=""):
		if element != None:
			link.__init__(self, config, "", pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/sep.png"), element.text, "separator")
		else:
			link.__init__(self, config, "", pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/sep.png"), name, "separator")

	def move(self):
		return panel_sep(self.config)
	
	def code(self):
		return '<div class="separator">' + self.get("name") + '</div>\n\n'
	
class app(launcher):
	"""Application"""
	def __init__(self, config, element, lch="", icon="", name="", desc="", exe="", dir="", param=""):
		if element != None:
			r = pyquery.PyQuery(element)
			launcher.__init__(self, config, element.get("lch"), r("img")[0].get("src"), r.text(), element.get("desc"), "app")
		else:
			launcher.__init__(self, config, lch, icon, name, desc, "app", "", exe, dir, param)
			
	def move(self):
		return panel_icon(self.config, None, self.infos["page"], self.infos["icon"], self.infos["name"], self.infos["exe"], self.infos["dir"], self.infos["param"])
	
	def code(self):
		return '''<div class="app" lch="''' + self.infos["page"] + '''" desc="''' + self.infos["desc"] + '''">
	<img src="''' + self.infos["icon"] + '''" />
	''' + self.infos["name"] + '''
</div>\n\n'''

#############
##  Panel  ##
#############

class panel_part(link):
	"""Panel (gauche ou droite)"""
	def __init__(self, config, place):
		self.place = place
		if place == "right":
			icon = pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/panel-right.png")
			name = "Panel (Droite)"
		else:
			icon = pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/panel-left.png")
			name = "Panel (Gauche)"
		link.__init__(self, config, "index.html", icon, name, "panel_part")
		
	def _get_code(self):
		q = link._get_pyquery(self)
		return q("#panel div#panel-" + self.place).html()
	
	def _get_pyquery(self):
		return pyquery.PyQuery(self._get_code())
		
	def get_children(self):
		list = []
		q = self._get_pyquery()
		for element in q("div *"):
			if element.tag == "img":
				list.append(panel_icon(self.config, element))
			elif element.get("class") == 'panel-sep':
				list.append(panel_sep(self.config))
			elif element.get("id") == 'clock':
				list.append(panel_clock(self.config))
		return list
	
	def code_start(self):
		return '			<div id="panel-' + self.place + '">\n'
	
	def code_end(self):
		return '			</div>\n'

class panel_icon(launcher):
	"""Icône du panel"""
	def __init__(self, config, element, lch="", icon="", desc="", exe="", dir="", param=""):
		if element != None:
			launcher.__init__(self, config, element.get("lch"), element.get("icon", ""), element.get("desc"), "", "panel_icon")
		else:
			launcher.__init__(self, config, lch, icon, desc, "", "panel_icon", "", exe, dir, param)

	def move(self):
		return app(self.config, None, self.infos["page"], self.infos["icon"], self.infos["name"], "", self.infos["exe"], self.infos["dir"], self.infos["param"])
	
	def code(self):
		return '				<img class="panel-icon" icon="' + self.get("icon") + '" lch="' + self.get("page") + '" desc="' + self.get("name") + '" />\n'

class panel_sep(link):
	"""Icône du panel"""
	def __init__(self, config):
		link.__init__(self, config, "", pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/sep.png"), "---------------------", "panel_sep")
	
	def move(self):
		return separator(self.config, None)
	
	def code(self):
		return '				<div class="panel-sep"></div>\n'
	
class panel_clock(link):
	"""Icône du panel"""
	def __init__(self, config):
		link.__init__(self, config, "", pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "/Data/FramaKiosk/", "img/clock.png"), "Horloge", "panel_clock")
	
	def code(self):
		return '				<div id="clock"></div>\n'

#################
##  Fonctions  ##
#################

def new_panel_icon(config):
	return panel_icon(config, None, "", "app.png", "Nouveau lanceur")

def new_app(config):
	chooser = gtk.FileChooserDialog("Sélectionnez une application : ",action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
	filtre = gtk.FileFilter()
	filtre.set_name("Programmes")
	filtre.add_pattern("*.exe")
	chooser.add_filter(filtre)
	chooser.set_current_folder(os.path.join(config.get("FramaKioskTune", "FramaRoot"),"Apps"))
	response = chooser.run()
	chooser.hide()
	if response == gtk.RESPONSE_OK:
		try:
			lchfile = "lch/Apps/" + os.path.basename(os.path.dirname(chooser.get_filename())) + ".lch"
			if os.path.isfile(os.path.join(os.path.dirname(chooser.get_filename()),"App\\AppInfo\\appinfo.ini")):
				conf = ConfigParser.ConfigParser()
				with io.open(os.path.join(os.path.dirname(chooser.get_filename()),"App\\AppInfo\\appinfo.ini"), 'r', encoding='utf_8_sig') as fp:
					conf.readfp(fp)
				description = conf.get("Framakey", "FriendlyName")
				longdesc = conf.get("Details", "Description")
			if os.path.isfile(os.path.join(os.path.dirname(chooser.get_filename()),"App\\AppInfo\\appicon_64.png")):
				appicon = pathutils.relpath(config.get("FramaKioskTune", "FramaKioskPath") + "\\Data\\FramaKiosk\\", os.path.join(os.path.dirname(chooser.get_filename()),"App\\AppInfo\\appicon_64.png")).replace("/", "\\")
			relexe = "Framaroot\\" + pathutils.relpath(config.get("FramaKioskTune", "FramaRoot"), chooser.get_filename()).replace("/", "\\")
			reldir = "Framaroot\\" + pathutils.relpath(config.get("FramaKioskTune", "FramaRoot"), os.path.dirname(chooser.get_filename())).replace("/", "\\")
			return app(config, None, lchfile, appicon, description, longdesc, relexe, reldir)
		except:
			return app(config, None, "", "", "Nouveau lanceur")
	return app(config, None, "", "", "Nouveau lanceur")

def new_panel_sep(config):
	return panel_sep(config)

def new_sep(config):
	return separator(config, None, "Nouveau séparateur")

def new_cat(config):
	return cat(config, None, "", "cat.png", "Nouvelle catégorie")

def new_clock(config):
	return panel_clock(config)

def new_subpage(config):
	return subpage(config, None, "", "Nouvelle sous-page")
