import W
import sys
from Carbon import Qd

__version__ = "0.2"
__author__ = "jvr"

class _modulebrowser:
	
	def __init__(self):
		self.editmodules = []
		self.modules = []
		self.window = W.Window((210, 1000), "Module Browser", minsize = (210, 160), maxsize = (340, 20000))
		
		self.window.openbutton = W.Button((10, 8, 90, 16), "Open", self.openbuttonhit)
		self.window.browsebutton = W.Button((110, 8, 90, 16), "Browse\xc9", self.browsebuttonhit)
		self.window.reloadbutton = W.Button((10, 32, 90, 16), "Reload", self.reloadbuttonhit)
		self.window.openotherbutton = W.Button((110, 32, 90, 16), "Open other\xc9", self.openother)
		
		self.window.openbutton.enable(0)
		self.window.reloadbutton.enable(0)
		self.window.browsebutton.enable(0)
		self.window.setdefaultbutton(self.window.browsebutton)
		
		self.window.bind("cmdr", self.window.reloadbutton.push)
		self.window.bind("cmdb", self.window.browsebutton.push)
	
		self.window.bind("<activate>", self.activate)
		self.window.bind("<close>", self.close)
		
		self.window.list = W.List((-1, 56, 1, -14), [], self.listhit)
		
		self.window.open()
		self.checkbuttons()
	
	def close(self):
		global _browser
		_browser = None
	
	def activate(self, onoff):
		if onoff:
			self.makelist()
		
	def listhit(self, isdbl):
		self.checkbuttons()
		if isdbl:
			if self.window._defaultbutton:
				self.window._defaultbutton.push()
	
	def checkbuttons(self):
		sel = self.window.list.getselection()
		if sel:
			for i in sel:
				if self.editmodules[i]:
					self.window.openbutton.enable(1)
					self.window.reloadbutton.enable(1)
					self.window.setdefaultbutton(self.window.openbutton)
					break
			else:
				self.window.openbutton.enable(0)
				self.window.reloadbutton.enable(0)
				self.window.setdefaultbutton(self.window.browsebutton)
			self.window.browsebutton.enable(1)
		else:
			#self.window.setdefaultbutton(self.window.browsebutton)
			self.window.openbutton.enable(0)
			self.window.reloadbutton.enable(0)
			self.window.browsebutton.enable(0)
	
	def openbuttonhit(self):
		import imp
		sel = self.window.list.getselection()
		W.SetCursor("watch")
		for i in sel:
			modname = self.window.list[i]
			try:
				self.openscript(sys.modules[modname].__file__, modname)
			except IOError:
				try:
					file, path, description = imp.find_module(modname)
				except ImportError:
					W.SetCursor("arrow")
					W.Message("Can't find file for module '%s'." 
							% modname)
				else:
					self.openscript(path, modname)					
	
	def openscript(self, path, modname):
		import os
		if path[-3:] == '.py':
			W.getapplication().openscript(path, modname=modname)
		elif path[-4:] in ['.pyc', '.pyo']:
			W.getapplication().openscript(path[:-1], modname=modname)
		else:
			W.Message("Can't edit '%s'; it might be a shared library or a .pyc file." 
					% modname)
	
	def openother(self):
		import imp
		import EasyDialogs
		
		modname = EasyDialogs.AskString("Open module:")
		if modname:
			try:
				file, path, description = imp.find_module(modname)
			except ImportError:
				if modname in sys.builtin_module_names:
					alerttext = "'%s' is a builtin module, which you can't edit." % modname
				else:
					alerttext = "No module named '%s'." % modname
				raise W.AlertError, alerttext
			self.openscript(path, modname)
	
	def reloadbuttonhit(self):
		sel = self.window.list.getselection()
		W.SetCursor("watch")
		for i in sel:
			mname = self.window.list[i]
			m = sys.modules[mname]
			# Set the __name__ attribute of the module to its real name.
			# reload() complains if it's __main__, which is true
			# when it recently has been run as a script with "Run as __main__" 
			# enabled.
			m.__name__ = mname
			reload(m)
	
	def browsebuttonhit(self):
		sel = self.window.list.getselection()
		if not sel:
			return
		import PyBrowser
		for i in sel:
			PyBrowser.Browser(sys.modules[self.window.list[i]])
	
	def makelist(self):
		editmodules, modules = getmoduleslist()
		if modules == self.modules:
			return
		self.editmodules, self.modules = editmodules, modules
		self.window.list.setdrawingmode(0)
		sel = self.window.list.getselectedobjects()
		self.window.list.set(self.modules)
		self.window.list.setselectedobjects(sel)
		self.window.list.setdrawingmode(1)


def getmoduleslist():
	import PyBrowser	# for caselesssort function
	moduleitems = sys.modules.items()
	moduleitems = filter(lambda (name, module): module is not None, moduleitems)
	modules = map(lambda (name, module): name, moduleitems)
	modules = PyBrowser.caselesssort(modules)
	editmodules = []
	sysmodules = sys.modules
	modulesappend = editmodules.append
	for m in modules:
		module = sysmodules[m]
		try:
			if sysmodules[m].__file__[-3:] == '.py' or \
					sysmodules[m].__file__[-4:] in ['.pyc', '.pyo']:
				modulesappend(1)
			else:
				modulesappend(0)
		except AttributeError:
			modulesappend(0)
	return editmodules, modules
	
	

_browser = None

def ModuleBrowser():
	global _browser
	if _browser is not None:
		_browser.window.select()
	else:
		_browser = _modulebrowser()
