import gtk
from logging import warn
import os, sys
from iface_browser import InterfaceBrowser
import help_box
from gui import policy
from dialog import Dialog, MixedButton

tips = gtk.Tooltips()

SHOW_PREFERENCES = 0

class MainWindow(Dialog):
	progress = None
	browser = None
	download_box = None

	def __init__(self, download_only):
		Dialog.__init__(self)
		self.set_title('Zero Install')
		self.set_default_size(gtk.gdk.screen_width() * 2 / 5, 300)

		self.connect('destroy', lambda w: self.destroyed())

		vbox = gtk.VBox(False, 4)
		vbox.set_border_width(4)
		self.vbox.pack_start(vbox, True, True, 0)

		# Global actions
		hbox = gtk.HBox(False, 0)
		vbox.pack_start(hbox, False, True, 0)
		hbox.set_spacing(4)

		label = gtk.Label(_('Choose the versions to use:'))
		label.set_alignment(0.0, 0.5)
		hbox.pack_start(label, True, True, 0)

		button = MixedButton('_Refresh all now', gtk.STOCK_REFRESH)
		button.connect('clicked', lambda b: policy.refresh_all())
		tips.set_tip(button, _('Check all the interfaces below for updates.'))
		hbox.pack_start(button, False, True, 0)

		cache = MixedButton('_Show Cache', gtk.STOCK_OPEN)
		cache.connect('clicked',
			lambda b: os.spawnlp(os.P_WAIT, sys.argv[0], sys.argv[0], '-c'))
		hbox.pack_start(cache, False, True, 0)

		# Tree view
		self.browser = InterfaceBrowser()
		vbox.pack_start(self.browser, True, True, 0)
		self.browser.show()

		# Interface actions
		hbox = gtk.HBox(False, 0)
		vbox.pack_start(hbox, False, True, 0)
		hbox.set_spacing(4)

		button = gtk.Button('Interface Properties...')
		self.browser.edit_properties.connect_proxy(button)
		hbox.pack_start(button, False, True, 0)
		tips.set_tip(button, _('See and edit the details of the selected interface.'))

		vbox.show_all()

		# Progress bar (hidden by default)
		self.progress = gtk.ProgressBar()
		hbox.pack_start(self.progress, True, True, 0)

		# Responses

		self.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
		b = self.add_button(gtk.STOCK_PREFERENCES, SHOW_PREFERENCES)
		self.action_area.set_child_secondary(b, True)

		self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
		if download_only:
			self.add_mixed_button('Download', gtk.STOCK_NETWORK, gtk.RESPONSE_OK)
		else:
			self.add_mixed_button('Run', gtk.STOCK_EXECUTE, gtk.RESPONSE_OK)
		self.set_default_response(gtk.RESPONSE_OK)
		self.default_widget.grab_focus()

		def response(dialog, resp):
			import download_box
			if resp in (gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT):
				self.destroy()
				sys.exit(1)
			elif resp == gtk.RESPONSE_OK:
				download_box.download_with_gui(self)
			elif resp == gtk.RESPONSE_HELP:
				gui_help.display()
			elif resp == SHOW_PREFERENCES:
				import preferences
				preferences.show_preferences()
		self.connect('response', response)

		# Warnings
		try:
			version_stream = os.popen('gpg --version')
			gpg_version = map(int, version_stream.readline().split(' ')[-1].strip().split('.'))
			version_stream.close()
		except Exception, ex:
			warn("Failed to get GPG version: %s", ex)
		else:
			if gpg_version < [1, 4, 2, 2]:
				# Don't want about versions < 1.4.6 because Ubuntu fixed it without
				# updating the version number.
				warning_label = gtk.Label("Warning: Your version of gnupg (%s) contains a signature\n"
					"checking vulnerability. Suggest upgrading to 1.4.6 or later." % '.'.join(map(str, gpg_version)))
				vbox.pack_start(warning_label, False, True, 0)
				warning_label.show()
	
	def destroyed(self):
		policy.abort_all_downloads()
		

gui_help = help_box.HelpBox("Injector Help",
('Overview', """
A program is made up of many different components, typically written by different \
groups of people. Each component is available in multiple versions. The injector is \
used when starting a program. Its job is to decide which implementation of each required \
component to use.

An interface describes what a component does. The injector starts with \
the interface for the program you want to run (like 'The Gimp') and chooses an \
implementation (like 'The Gimp 2.2.0'). However, this implementation \
will in turn depend on other interfaces, such as 'GTK' (which draws the menus \
and buttons). Thus, the injector must choose implementations of \
each dependency (each of which may require further interfaces, and so on)."""),

('List of interfaces', """
The main window displays all these interfaces, and the version of each chosen \
implementation. The top-most one represents the program you tried to run, and each direct \
child is a dependency. The 'Fetch' column shows the amount of data that needs to be \
downloaded, or '(cached)' if it is already on this computer.

If you are happy with the choices shown, click on the Download (or Run) button to \
download (and run) the program."""),

('Choosing different versions', """
To control which implementations (versions) are chosen you can click on Preferences \
and adjust the network policy and the overall stability policy. These settings affect \
all programs run using Zero Install.

Alternatively, you can edit the policy of an individual interface by selecting it \
and clicking on the 'Interface Properties' button. \
See that dialog's help text for more information.

Right-click on an interface in the list for a menu.
"""),

('Reporting bugs', """
To report a bug, right-click over the interface which you think contains the problem \
and choose 'Report a Bug...' from the menu. If you don't know which one is the cause, \
choose the top one (i.e. the program itself). The program's author can reassign the \
bug if necessary, or switch to using a different version of the library.
"""),

('The cache', """
Each version of a program that is downloaded is stored in the Zero Install cache. This \
means that it won't need to be downloaded again each time you run the program. Click on \
the 'Show Cache' button to see what is currently in the cache, or to remove versions \
you no longer need to save disk space."""),
)


syntax highlighted by Code2HTML, v. 0.9.1