import cryptobox.plugins.base
import cryptobox.plugins.manage


class plugin_manager(cryptobox.plugins.base.CryptoBoxPlugin):

	pluginCapabilities = [ "system" ]
	pluginVisibility = [ "preferences" ]
	requestAuth = True
	rank = 90

	def doAction(self, store=None, action=None, plugin_name=None, **args):
		import re
		if plugin_name:
			## check for invalid characters
			if re.search(u'\W', plugin_name): return "plugin_list"
			pluginList = cryptobox.plugins.manage.PluginManager(self.cbox, self.cbox.prefs["Locations"]["PluginDir"])
			plugin = pluginList.getPlugin(plugin_name)
			if not plugin: return "plugin_list"
			## take only plugins, that are of the same type as the choosen one
			self.plugins = [e for e in pluginList.getPlugins() if e.pluginCapabilities == plugin.pluginCapabilities]
			if action == "up":
				self.__move_up(plugin)
			elif action == "down":
				self.__move_down(plugin)
			return "plugin_list"
		elif store:
			for key in args.keys():
				if key.endswith("_listed"):
					if not re.search(u'\W',key):
						self.__setConfig(key[:-7], args)
					else:
						self.cbox.log.info("plugin_manager: invalid plugin name (%s)" % str(key[:-7]))
			try:
				self.cbox.prefs.pluginConf.write()
			except IOError:
				self.cbox.log.warn("failed to write plugin configuration")
		return "plugin_list"


	def getStatus(self):
		return "no status"


	def __sortPlugins(self):
		"""sort all plugins in the list according to their rank"""
		def cmp_func(x,y):
			xRank = x.getRank()
			yRank = y.getRank()
			if xRank < yRank:	return -1
			elif xRank == yRank:	return 0
			else:	return 1
		self.plugins.sort(cmp = cmp_func)
	
	
	def __distributeRanks(self):
		"""evenly distribute the 'rank' values according to the current order of
		the list"""
		dist = 100/len(self.plugins)
		for index,pl in enumerate(self.plugins):
			try:
				self.cbox.prefs.pluginConf[pl.getName()]["rank"] = dist*index
			except KeyError:
				self.cbox.prefs.pluginConf[pl.getName()] = {}
				self.cbox.prefs.pluginConf[pl.getName()]["rank"] = dist*index
		self.cbox.prefs.pluginConf.write()


	def __move_up(self, plugin):
		self.__sortPlugins()
		try:
			index = self.plugins.index(plugin)
			## first elements may not move up
			if index == 0:
				return
		except ValueError:
			return
		self.plugins.remove(plugin)
		self.plugins.insert(index-1, plugin)
		self.__distributeRanks()
		

	def __move_down(self, plugin):
		self.__sortPlugins()
		try:
			index = self.plugins.index(plugin)
			## last elements may not move down
			if index == len(self.plugins) - 1:
				return
		except ValueError:
			return
		self.plugins.remove(plugin)
		self.plugins.insert(index+1, plugin)
		self.__distributeRanks()


	def __setConfig(self, name, args):
		import re
		setting = {}
		setting["visibility"] = []
		## look for "_visible_" values and apply them
		pattern = re.compile(u'%s_visible_([\w]+)$' % name)
		for key in args.keys():
			if key.startswith(name + "_visible_"):
				(vis_type, ) = pattern.match(key).groups()
				setting["visibility"].append(vis_type)
		setting["rank"] = "50"
		try:
			r = int(args[name + "_rank"])
			if r>=0 and  r<=100:
				setting["rank"] = r
		except (KeyError, ValueError):
			pass
		setting["requestAuth"] = False
		try:
			if args[name + "_auth"]:
				setting["requestAuth"] = True
		except (KeyError, ValueError):
			pass
		self.cbox.prefs.pluginConf[name] = setting

