#
# A simple address book for pyne
#

import utils
import gtk
import gobject
import string
import pynei18n
import ptk.misc_widgets

class AddressEditBox:
	"""
	A box allowing the editing of the address book and
	also selection of an entry by means of connecting
	'clicked' on ok_button.
	If gtkentry is set then the selected address will be
	dumped in usable form to the specified gtkentry. if append=1
	then it will be appended to existing contents.
	"""
	def __init__(self, addresses, parent_win, gtkentry=None, append=0):
		self.addresses = addresses
		self.gtkentry = gtkentry
		self.append = append
		self.user = parent_win.user

		self.win = gtk.Window()
		self.win.set_default_size(600,440)
		self.win.set_title(_("Address Book"))
		self.win.set_transient_for(parent_win)

		box1 = gtk.VBox()
		box1.set_border_width(2)
		self.win.add(box1)
		box1.show()
		
		if len (addresses):
			self.selected_address = 0
		else:
			self.selected_address = None

		def _on_click(widget, event, self=self):
			"""
			If someone double-clicks on an address return it.
			"""
			x, y = event.x, event.y
			# path of clicked item
			selected = widget.get_path_at_pos (int (x), int (y))
			if selected == None:
				return
			model = self.entry_list.get_model ()
			# get tree iter from path
			iter = model.get_iter (selected[0])
			# invisible field gives address index
			self.selected_address = model.get_value (iter, 3)

			if event.type == gtk.gdk._2BUTTON_PRESS:
				self.dump_address()

		self.entry_list = gtk.TreeView ()
		cell = gtk.CellRendererText ()

		col = gtk.TreeViewColumn (_("Name"), cell, text=0)
		col.set_sizing (gtk.TREE_VIEW_COLUMN_AUTOSIZE)
		self.entry_list.append_column (col)
		col = gtk.TreeViewColumn (_("Email Address"), cell, text=1)
		col.set_sizing (gtk.TREE_VIEW_COLUMN_AUTOSIZE)
		self.entry_list.append_column (col)
		col = gtk.TreeViewColumn (_("Notes"), cell, text=2)
		col.set_sizing (gtk.TREE_VIEW_COLUMN_AUTOSIZE)
		self.entry_list.append_column (col)
		
		model = gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT)
		self.entry_list.set_model (model)
		
		self.entry_list.connect("button_press_event", _on_click)
		self.update_entry_list()

		swin = gtk.ScrolledWindow()
		swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		box1.pack_start(swin)
		swin.show()
		swin.add(self.entry_list)
		self.entry_list.show()

		##### BOX3. Buttons
		buttonbox = ptk.misc_widgets.MyButtonBox()
		box1.pack_start(buttonbox, expand=False)
		buttonbox.show()

		button = gtk.Button(stock="gtk-add")
		button.connect("clicked", self.add_address)
		buttonbox.pack_end(button, expand=False)
		button.show()

		button = gtk.Button(" "+_("Edit")+" ")
		button.connect("clicked", self.edit_address)
		buttonbox.pack_end(button, expand=False)
		button.show()

		button = gtk.Button(stock="gtk-delete")
		button.connect("clicked", self.del_address)
		buttonbox.pack_end(button, expand=False)
		button.show()

		self.ok_button = gtk.Button(stock="gtk-ok")
		if gtkentry != None:
			self.ok_button.connect("clicked", self.dump_address)
		buttonbox.pack_end(self.ok_button, expand=False)
		self.ok_button.show()

		button = gtk.Button(stock="gtk-cancel")
		button.connect("clicked", self.close)
		buttonbox.pack_end(button, expand=False)
		button.show()

		self.win.show()

	def dump_address(self, _button=None):
		addr = self.addresses[self.selected_address]
		if self.gtkentry != None:
			if addr[0] == "":
				# no name
				format = addr[1]
			else:
				# push in form: "name" <email@ddress>
				format = "\""+addr[0]+"\" <"+addr[1]+">"
			if self.append == 0:
				self.gtkentry.set_text(format)
			else:
				if self.gtkentry.get_text() != "":
					format = self.gtkentry.get_text() + ", " + format
				self.gtkentry.set_text(format)
		self.win.destroy()
				
	def del_address(self, _button=None):
		"""
		delete an address.
		"""
		if self.selected_address != None:
			index = self.selected_address

			del self.addresses[index]
			self.update_entry_list()

	def add_address(self, _button=None):
		"""
		Add an address.
		"""
		self.addresses.append(["","",""])
		self.update_entry_list()
		self.edit_address(index=len(self.addresses)-1)

	def close(self, _button=None):
		self.win.destroy()

	def edit_address(self, _button=0, index=-1):
		"""
		Edit an existing entry.
		"""
		if index == -1 and self.selected_address != None:
			index = self.selected_address
		if index == -1:
			return

		entry = self.addresses[index]

		win = gtk.Window()
		win.set_title(_("Pyne - Edit Address"))
		win.set_transient_for(self.win)
		box = gtk.VBox()
		win.add(box)
		box.show()

		box1 = gtk.HBox()
		box.pack_start(box1)
		box1.show()
		box1_1 = gtk.VBox(spacing=5)
		box1_1.set_border_width(5)
		box1.pack_start(box1_1)
		box1_1.show()
		box1_2 = gtk.VBox(spacing=5)
		box1_2.set_border_width(5)
		box1.pack_start(box1_2)
		box1_2.show()

		label = gtk.Label(_("Name"))
		box1_1.pack_start(label)
		label.show()
		label = gtk.Label(_("Email Address"))
		box1_1.pack_start(label)
		label.show()
		label = gtk.Label(_("Note"))
		box1_1.pack_start(label)
		label.show()

		name_entry = gtk.Entry()
		box1_2.pack_start(name_entry)
		name_entry.set_text(entry[0])
		name_entry.show()
		addr_entry = gtk.Entry()
		box1_2.pack_start(addr_entry)
		addr_entry.set_text(entry[1])
		addr_entry.show()
		note_entry = gtk.Entry()
		box1_2.pack_start(note_entry)
		note_entry.set_text(entry[2])
		note_entry.show()

		buttonbox = ptk.misc_widgets.MyButtonBox()
		buttonbox.set_border_width(5)
		box.pack_end(buttonbox, expand=False)
		buttonbox.show()

		def make_it_so(_button, self=self, name_entry=name_entry, index=index, \
		                addr_entry=addr_entry, note_entry=note_entry, win=win):
			name = name_entry.get_text()
			addr = addr_entry.get_text()
			note = note_entry.get_text()
			if name=="" and addr=="" and note=="":
				del self.addresses[index]
			else:
				self.addresses[index] = [ name,addr,note ]
			self.sort()
			self.update_entry_list()
			
			win.destroy()

		def _cancel_edit(_button, self=self, index=index, win=win):
			# if this was a new address delete it
			name, addr, note = self.addresses[index]
			if name=="" and addr=="" and note=="":
				del self.addresses[index]
				self.sort()
				self.update_entry_list()
			win.destroy()

		button = gtk.Button(stock="gtk-ok")
		button.connect("clicked", make_it_so)
		buttonbox.pack_end(button, expand=False)
		button.show()
				
		button = gtk.Button(stock="gtk-cancel")
		button.connect("clicked", _cancel_edit)
		buttonbox.pack_end(button, expand=False)
		button.show()
		
		win.show()

	def update_entry_list(self):
		"""
		Update the list of addresses.
		"""
		model = self.entry_list.get_model ()
		model.clear ()
		
		for y in range(0, len(self.addresses)):
			iter = model.append ()
			model.set (iter, 0, self.addresses[y][0], 1, self.addresses[y][1], 2, self.addresses[y][2], 3, y)

	def get_selected(self):
		"""
		Return currently selected address.
		"""
		if self.selected_address == None:
			return [ "", "", "" ]
		else:
			return self.addresses[self.selected_address]

	def destroy(self):
		# save changes
		self.user.save()
		# nuke window
		self.win.destroy()
	
	def add_senders_address(self, msg, addr_editbox):
		"""
		Add the sender of a message to the address book.
		"""
		if msg.headers.has_key("reply-to"):
			realname, emailaddress = utils.split_address(msg.headers["reply-to"])
		else:
			realname, emailaddress = utils.split_address(msg.headers["from"])
		if not emailaddress:
			emailaddress = realname
			realname = ""
			
		self.addresses.append( [ realname, emailaddress, "" ] )
		addr_editbox.update_entry_list()
		addr_editbox.edit_address(index=len(self.addresses)-1)

	def sort(self):
		"""
		Sort address book by alphabetic order
		"""
		def _sort(a, b):
			a_name = string.split(string.lower(a[0]), " ")
			b_name = string.split(string.lower(b[0]), " ")

			# find last names
			a_lastname = a_name[len(a_name)-1]
			b_lastname = b_name[len(b_name)-1]

			if a_lastname < b_lastname:
				return -1
			elif a_lastname > b_lastname:
				return 1
			else:
				# same last name. decide by first name
				if a_name[0] < b_name[0]:
					return -1
				elif a_name[0] > b_name[0]:
					return 1
				# equal :-o
				return 0

		self.addresses.sort(_sort)




syntax highlighted by Code2HTML, v. 0.9.1