import sys, os

import rox
from rox import saving, g

import formats

use_combo_box = hasattr(g, 'ComboBox')

class ArchiveBox(saving.SaveBox, saving.Saveable):
	"A savebox with an operation selector."
	def __init__(self):
		self.data = None
		self.operation = None
		self.ops = None
		saving.SaveBox.__init__(self, self, '', 'text/plain')
	
	def save_cancelled(self):
		assert formats.current_command
		formats.current_command.kill()

	def set_save_in_progress(self, busy):
		if self.operation:
			self.operation.set_sensitive(not busy)
		saving.SaveBox.set_save_in_progress(self, busy)
	
	def build_main_area(self):
		self.vbox.add(self.save_area)

		frame = g.Frame(None)
		frame.set_shadow_type(g.SHADOW_NONE)
		if use_combo_box:
			self.operation = g.combo_box_new_text()
		else:
			self.operation = g.OptionMenu()
		frame.add(self.operation)
		self.vbox.pack_start(frame, False, True, 0)
		frame.set_border_width(3)
		frame.show_all()
		self.updating = 0

		self.delete_choice = g.CheckButton(_('_Delete file afterwards?'))
		self.vbox.pack_start(self.delete_choice, True, True, 0)

		if not use_combo_box:
			self.ops_menu = g.Menu()
			self.operation.set_menu(self.ops_menu)
		else:
			self.ops_menu = None
	
	def set_data(self, data):
		assert not self.data

		self.data = data
		self.save_mode = data.mode
		ops = [op for op in formats.operations if op.can_handle(data)]

		name = data.default_name
		self.save_area.entry.set_text(name)
		start = name.rfind('/') + 1
		#self.save_area.entry.select_region(start, -1)
		g.Editable.select_region(self.save_area.entry, start, -1)

		# Add all supported ops to the menu.
		self.ops = []
		if use_combo_box:
			for op in ops:
				self.operation.append_text(str(op))
				self.ops.append(op)
			try:
				self.operation.set_active(self.ops.index(data.default))
			except ValueError:
				print >>sys.stderr, "Warning: %s not in ops list!" % data.default

		else:
			last = None
			for op in ops:
				if last and last != op.__class__:
					item = g.MenuItem()
					item.show()
					self.ops_menu.append(item)
					self.ops.append(None)
				last = op.__class__
				item = g.MenuItem(str(op))
				item.show()
				self.ops_menu.append(item)
				self.ops.append(op)
		
			# Select the default
			try:
				self.operation.set_history(self.ops.index(data.default))
			except ValueError:
				print >>sys.stderr, "Warning: %s not in ops list!" % data.default

		self.operation.connect('changed', self.op_changed)
		self.save_area.entry.connect('changed', self.name_changed)

		self.save_area.set_type(data.default.type)

		if isinstance(data, formats.FileData) and data.path != '-':
			self.delete_choice.show()
	
	def name_changed(self, entry):
		if self.updating:
			return
		self.updating = 1

		name = entry.get_text()
		i = 0
		for op in self.ops:
			if op and name.endswith('.' + op.extension):
				if use_combo_box:
					self.operation.set_active(i)
				else:
					self.operation.set_history(i)
				break
			i += 1

		self.updating = 0

	def get_selected_op(self):
		if use_combo_box:
			return self.ops[self.operation.get_active()]
		else:
			return self.ops[self.operation.get_history()]
	
	def op_changed(self, operation):
		op = self.get_selected_op()
		assert op
		self.set_type(op.type)

		if self.updating:
			return
		self.updating = 1

		name = self.save_area.entry.get_text()
		for op2 in self.ops:
			if op2 and name.endswith('.' + op2.extension):
				name = name[:-len(op2.extension)-1]
				break
		if op.add_extension:
			name += '.' + op.extension
		self.save_area.entry.set_text(name)
		start = name.rfind('/') + 1
		#self.save_area.entry.select_region(start, -1)
		g.Editable.select_region(self.save_area.entry, start, -1)

		self.updating = 0
	
	def save_to_file(self, path):
		op = self.get_selected_op()
		if hasattr(op, 'save_to_file'):
			op.save_to_file(self.data, path)
		else:
			saving.Saveable.save_to_file(self, path)

		#If the delete_choice is set, try to remove the file
		if self.delete_choice.get_active():
			try:
				os.remove(sys.argv[1])
			except:
				rox.report_exception()
	
	def can_save_to_selection(self):
		if self.ops:
			op = self.get_selected_op()

			if op.type == 'inode/directory':
				return False
		return saving.Saveable.can_save_to_selection(self)
	
	def save_to_stream(self, stream):
		op = self.get_selected_op()
		op.save_to_stream(self.data, stream)
