# TODO
#  - add whitelist enable checkbox
#  - add padding to the add host dialog
#  - handle the permission entries changing underneath us

import epiphany
import gtk

class CookieTreeModel (gtk.GenericTreeModel):
	def __init__ (self):
		gtk.GenericTreeModel.__init__ (self)
		self._s = epiphany.ephy_shell_get_default ().get_embed_single ()

	def _get_rules (self):
		return [p for p in self._s.list_permissions ('cookie') if p.permission == epiphany.PERMISSION_ALLOWED]
	
	def on_get_flags (self):
		return gtk.TREE_MODEL_LIST_ONLY
	
	def on_get_n_columns (self):
		return 1
	
	def on_get_column_type (self, index):
		assert index == 0
		return str

	def on_get_path (self, node):
		return (node, )

	def on_get_iter (self, path):
		i = path[0]
		if i >= 0 and i < len (self._get_rules ()):
			return i
		else:
			return None

	def on_get_value (self, node, column):
		assert column == 0
		return self._get_rules ()[node].host

	def on_iter_next (self, node):
		if node + 1 < len (self._get_rules ()):
			return node + 1
		else:
			return None
	
	def on_iter_children (self, node):
		return None

	def on_iter_has_child (self, node):
		return False
	
	def on_iter_n_children (self, node):
		return 0
	
	def on_iter_nth_child (self, node, n):
		if node == None:
			return (n, ) #huh?
		else:
			return None
	
	def on_iter_parent (self, node):
		return None
	
	def remove (self, iter):
		path = self.get_path (iter)
		index = path[0]
		host = self._get_rules ()[index].host
		self._s.remove_permission (host, 'cookie')
		self.row_deleted (path)
	
	# return an iter for the given host in the list of rules, or None if the
	# host is not present
	def search (self, host):
		i = 0
		for p in self._get_rules ():
			if p.host == host:
				path = (i, )
				return self.get_iter (path)
			i += 1
		return None
	
	def add (self, host):
		# do this check ourselves because weird things happen if we add a host
		# that is already in the list. possibly the order of entries changes
		# or something
		if self.search (host) == None:
			self._s.add_permission ('http://%s' % host, 'cookie', epiphany.PERMISSION_ALLOWED)
			iter = self.search (host)
			self.row_inserted (self.get_path (iter), iter)

		return self.search (host)

_ui_str = """
<ui>
 <menubar name="menubar">
  <menu name="ToolsMenu" action="Tools">
   <menuitem name="CookieWhitelist" action="CookieWhitelist"/>
  </menu>
 </menubar>
</ui>
"""

_cm_w = None

def _show_cm (action, window):
	global _cm_w

	if _cm_w:
		_cm_w.present ()
	else:
		ctm = CookieTreeModel ()
		cr = gtk.CellRendererText ()
		tvc = gtk.TreeViewColumn ('Host', cr)
		tvc.add_attribute (cr, 'text', 0)
		tv = gtk.TreeView (ctm)
		tv.append_column (tvc)

		def row_selected (selection):
			rb.set_sensitive (selection.count_selected_rows ()> 0)

		tv.get_selection ().connect ('changed', row_selected)

		sw = gtk.ScrolledWindow ()
		sw.set_policy (gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
		sw.set_shadow_type (gtk.SHADOW_IN)
		sw.add (tv)

		def add (button, model):
			l = gtk.Label ('Host')
			e = gtk.Entry (255)
			e.set_activates_default (True)

			hb = gtk.HBox (False, 12)
			hb.pack_start (l)
			hb.pack_end (e)
			hb.show_all ()

			d = gtk.Dialog ('Add host', _cm_w, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_ADD, gtk.RESPONSE_OK))
			d.vbox.add (hb)
			d.set_default_response(gtk.RESPONSE_OK)
			
			ret = d.run ()
			if ret == gtk.RESPONSE_OK:
				i = model.add (e.get_text ())
				tv.get_selection ().select_iter (i)
				tv.scroll_to_cell (model.get_path (i))

			d.destroy ()

		def remove (button, view):
			(model, iter) = view.get_selection ().get_selected ()
			model.remove (iter)

		ab = gtk.Button (stock=gtk.STOCK_ADD)
		ab.connect ('clicked', add, ctm)

		rb = gtk.Button (stock=gtk.STOCK_REMOVE)
		rb.connect ('clicked', remove, tv)
		
		bb = gtk.HButtonBox ()
		bb.add (rb)
		bb.add (ab)
		
		vb = gtk.VBox (False, 12)
		vb.pack_start (sw, True)
		vb.pack_end (bb, False)

		def hide (window, data):
			window.hide ()
			return True

		_cm_w = gtk.Window (gtk.WINDOW_TOPLEVEL)
		_cm_w.set_title ('Cookie Whitelist')
		_cm_w.set_border_width (12)
		_cm_w.set_size_request (320,240)
		_cm_w.set_position (gtk.WIN_POS_CENTER)
		_cm_w.add (vb)
		_cm_w.connect ('delete_event', hide)
		_cm_w.show_all ()

_actions = [('CookieWhitelist', None, 'Cooke Whitelist...', None, None, _show_cm)]

def attach_window (window):
	group = gtk.ActionGroup('CookieWhitelist')
	group.add_actions (_actions, window)

	ui_manager = window.get_ui_manager ()
	ui_manager.insert_action_group (group, -1)
	ui_id = ui_manager.add_ui_from_string (_ui_str)

	window._cookie_manager_data = (group, ui_id)

def detach_window (window):
	group, ui_id = window._cookie_manager_data
	del window._cookie_manager_data

	ui_manager = window.get_ui_manager ()
	ui_manager.remove_ui (ui_id)
	ui_manager.remove_action_group (group)

	ui_manager.ensure_update ()
