import W
import Wkeys
import Fm
import WASTEconst
from types import *
import Events
import string
import sys
import traceback
import MacOS
import MacPrefs
import Qd
import PyInteractive

if not hasattr(sys, 'ps1'):
	sys.ps1 = '>>> '
if not hasattr(sys, 'ps2'):
	sys.ps2 = '... '

def inspect(foo):			# JJS 1/25/99
	"Launch the browser on the given object.  This is a general built-in function."
	import PyBrowser
	PyBrowser.Browser(foo)

class ConsoleTextWidget(W.EditText):
	
	def __init__(self, *args, **kwargs):
		apply(W.EditText.__init__, (self,) + args, kwargs)
		self._inputstart = 0
		self._buf = ''
		self.pyinteractive = PyInteractive.PyInteractive()
	
		import __main__
		self._namespace = __main__.__dict__
		self._namespace['inspect'] = inspect			# JJS 1/25/99
	
	def insert(self, text):
		self.checkselection()
		self.ted.WEInsert(text, None, None)
		self.changed = 1
		self.selchanged = 1
	
	def set_namespace(self, dict):
		if type(dict) <> DictionaryType:
			raise TypeError, "The namespace needs to be a dictionary"
		if 'inspect' not in dict.keys(): dict['inspect'] = inspect			# JJS 1/25/99
		self._namespace = dict
	
	def open(self):
		W.EditText.open(self)
		self.write('Python ' + sys.version + '\nType "copyright", "credits" or "license" for more information.\n')
		self.write(sys.ps1)
		self.flush()
	
	def key(self, char, event):
		(what, message, when, where, modifiers) = event
		if self._enabled and not modifiers & Events.cmdKey or char in Wkeys.arrowkeys:
			if char not in Wkeys.navigationkeys:
				self.checkselection()
			if char == Wkeys.enterkey:
				char = Wkeys.returnkey
			selstart, selend = self.getselection()
			if char == Wkeys.backspacekey:
				if selstart <= (self._inputstart - (selstart <> selend)):
					return
			self.ted.WEKey(ord(char), modifiers)
			if char not in Wkeys.navigationkeys:
				self.changed = 1
			if char not in Wkeys.scrollkeys:
				self.selchanged = 1
			self.updatescrollbars()
			if char == Wkeys.returnkey:
				text = self.get()[self._inputstart:selstart]
				text = string.join(string.split(text, "\r"), "\n")
				saveyield = MacOS.EnableAppswitch(0)
				self.pyinteractive.executeline(text, self, self._namespace)
				MacOS.EnableAppswitch(saveyield)
				selstart, selend = self.getselection()
				self._inputstart = selstart
	
	def domenu_save_as(self, *args):
		import macfs
		fss, ok = macfs.StandardPutFile('Save console text as:', 'console.txt')
		if not ok:
			return
		f = open(fss.as_pathname(), 'wb')
		f.write(self.get())
		f.close()
		fss.SetCreatorType(W._signature, 'TEXT')
	
	def write(self, text):
		self._buf = self._buf + text
		if '\n' in self._buf:
			self.flush()
	
	def flush(self):
		stuff = string.split(self._buf, '\n')
		stuff = string.join(stuff, '\r')
		self.setselection_at_end()
		self.ted.WEInsert(stuff, None, None)
		selstart, selend = self.getselection()
		self._inputstart = selstart
		self._buf = ""
		self.ted.WEClearUndo()
		self.updatescrollbars()
	
	def selection_ok(self):
		selstart, selend = self.getselection()
		return not (selstart < self._inputstart or selend < self._inputstart)
	
	def checkselection(self):
		if not self.selection_ok():
			self.setselection_at_end()
	
	def setselection_at_end(self):
		end = self.ted.WEGetTextLength()
		self.setselection(end, end)
		self.updatescrollbars()
		
	def domenu_cut(self, *args):
		if not self.selection_ok():
			return
		W.EditText.domenu_cut(self)
	
	def domenu_paste(self, *args):
		if not self.selection_ok():
			self.setselection_at_end()
		W.EditText.domenu_paste(self)
	
	def domenu_clear(self, *args):
		if not self.selection_ok():
			return
		W.EditText.domenu_clear(self)


class PyConsole(W.Window):
	
	def __init__(self, bounds, show = 1, fontsettings = ("Monaco", 0, 9, (0, 0, 0)), 
			tabsettings = (32, 0), unclosable = 0):
		W.Window.__init__(self,
					bounds, 
					"Python Interactive", 
					minsize = (200, 100), 
					tabbable = 0, 
					show = show)
		
		self._unclosable = unclosable
		consoletext = ConsoleTextWidget((-1, -1, -14, 1), inset = (6, 5), 
				fontsettings = fontsettings, tabsettings = tabsettings)
		self._bary = W.Scrollbar((-15, 14, 16, -14), consoletext.vscroll, max = 32767)
		self.consoletext = consoletext
		self.namespacemenu = W.PopupMenu((-15, -1, 16, 16), [], self.consoletext.set_namespace)
		self.namespacemenu.bind('<click>', self.makenamespacemenu)
		self.open()
	
	def makenamespacemenu(self, *args):
		W.SetCursor('watch')
		namespacelist = self.getnamespacelist()
		self.namespacemenu.set([("Clear window", self.clearbuffer), ("Font settings\xc9", self.dofontsettings), 
				["Namespace"] + namespacelist, ("Browse namespace\xc9", self.browsenamespace)])
		currentname = self.consoletext._namespace["__name__"]
		for i in range(len(namespacelist)):
			if namespacelist[i][0] == currentname:
				break
		else:
			return
		# XXX this functionality should be generally available in Wmenus
		submenuid = self.namespacemenu.menu.menu.GetItemMark(3)
		menu = self.namespacemenu.menu.bar.menus[submenuid]
		menu.menu.CheckMenuItem(i + 1, 1)
	
	def browsenamespace(self):
		import PyBrowser, W
		W.SetCursor('watch')
		PyBrowser.Browser(self.consoletext._namespace, self.consoletext._namespace["__name__"])
	
	def clearbuffer(self):
		import Res
		self.consoletext.ted.WEUseText(Res.Resource(''))
		self.consoletext.write(sys.ps1)
		self.consoletext.flush()
	
	def getnamespacelist(self):
		import os
		import __main__
		editors = filter(lambda x: x.__class__.__name__ == "Editor", self.parent._windows.values())
		
		namespaces = [ ("__main__",__main__.__dict__) ]
		for ed in editors:
			modname = os.path.splitext(ed.title)[0]
			if sys.modules.has_key(modname):
				module = sys.modules[modname] 
				namespaces.append((modname, module.__dict__))
			else:
				if ed.title[-3:] == '.py':
					modname = ed.title[:-3]
				else:
					modname = ed.title
				ed.globals["__name__"] = modname
				namespaces.append((modname, ed.globals))
		return namespaces
	
	def dofontsettings(self):
		import FontSettings
		settings = FontSettings.FontDialog(self.consoletext.getfontsettings(),
				self.consoletext.gettabsettings())
		if settings:
			fontsettings, tabsettings = settings
			self.consoletext.setfontsettings(fontsettings)
			self.consoletext.settabsettings(tabsettings)
	
	def show(self, onoff = 1):
		W.Window.show(self, onoff)
		if onoff:
			self.select()
	
	def close(self):
		if self._unclosable:
			self.show(0)
			return -1
		W.Window.close(self)
	
	def writeprefs(self):
		prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
		prefs.console.show = self.isvisible()
		prefs.console.windowbounds = self.getbounds()
		prefs.console.fontsettings = self.consoletext.getfontsettings()
		prefs.console.tabsettings = self.consoletext.gettabsettings()
		prefs.save()


class OutputTextWidget(W.EditText):
	
	def domenu_save_as(self, *args):
		title = self._parentwindow.gettitle()
		import macfs
		fss, ok = macfs.StandardPutFile('Save %s text as:' % title, title + '.txt')
		if not ok:
			return
		f = open(fss.as_pathname(), 'wb')
		f.write(self.get())
		f.close()
		fss.SetCreatorType(W._signature, 'TEXT')
	

class PyOutput:
	
	def __init__(self, bounds, show = 1, fontsettings = ("Monaco", 0, 9, (0, 0, 0)), tabsettings = (32, 0)):
		self.bounds = bounds
		self.fontsettings = fontsettings
		self.tabsettings = tabsettings
		self.w = None
		self.closed = 1
		self._buf = ''
		# should be able to set this
		self.savestdout, self.savestderr = sys.stdout, sys.stderr
		sys.stderr = sys.stdout = self
		if show:
			self.show()
	
	def setupwidgets(self):
		self.w = W.Window(self.bounds, "Output", 
				minsize = (200, 100), 
				tabbable = 0)
		self.w.outputtext = OutputTextWidget((-1, -1, -14, 1), inset = (6, 5), 
				fontsettings = self.fontsettings, tabsettings = self.tabsettings, readonly = 1)
		menuitems = [("Clear window", self.clearbuffer), ("Font settings\xc9", self.dofontsettings)]
		self.w.popupmenu = W.PopupMenu((-15, -1, 16, 16), menuitems)
		
		self.w._bary = W.Scrollbar((-15, 14, 16, -14), self.w.outputtext.vscroll, max = 32767)
		self.w.bind("<close>", self.close)
		self.w.bind("<activate>", self.activate)
	
	def write(self, text):
		oldyield = MacOS.EnableAppswitch(-1)
		try:
			self._buf = self._buf + text
			if '\n' in self._buf:
				self.flush()
		finally:
			MacOS.EnableAppswitch(oldyield)
	
	def flush(self):
		self.show()
		stuff = string.split(self._buf, '\n')
		stuff = string.join(stuff, '\r')
		end = self.w.outputtext.ted.WEGetTextLength()
		self.w.outputtext.setselection(end, end)
		self.w.outputtext.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 0)
		self.w.outputtext.ted.WEInsert(stuff, None, None)
		self._buf = ""
		self.w.outputtext.updatescrollbars()
		self.w.outputtext.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 1)
	
	def show(self):
		if self.closed:
			if not self.w:
				self.setupwidgets()
				self.w.open()
				self.w.outputtext.updatescrollbars()
				self.closed = 0
			else:
				self.w.show(1)
				self.closed = 0
				self.w.select()
	
	def writeprefs(self):
		if self.w is not None:
			prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
			prefs.output.show = self.w.isvisible()
			prefs.output.windowbounds = self.w.getbounds()
			prefs.output.fontsettings = self.w.outputtext.getfontsettings()
			prefs.output.tabsettings = self.w.outputtext.gettabsettings()
			prefs.save()
	
	def dofontsettings(self):
		import FontSettings
		settings = FontSettings.FontDialog(self.w.outputtext.getfontsettings(),
				self.w.outputtext.gettabsettings())
		if settings:
			fontsettings, tabsettings = settings
			self.w.outputtext.setfontsettings(fontsettings)
			self.w.outputtext.settabsettings(tabsettings)
	
	def clearbuffer(self):
		import Res
		self.w.outputtext.set('')
	
	def activate(self, onoff):
		if onoff:
			self.closed = 0
	
	def close(self):
		self.w.show(0)
		self.closed = 1
		return -1


class SimpleStdin:
	
	def readline(self):
		import EasyDialogs
		# A trick to make the input dialog box a bit more palatable
		if hasattr(sys.stdout, '_buf'):
			prompt = sys.stdout._buf
		else:
			prompt = ""
		if not prompt:
			prompt = "Stdin input:"
		sys.stdout.flush()
		rv = EasyDialogs.AskString(prompt)
		if rv is None:
			return ""
		return rv + '\n'


def installconsole(defaultshow = 1):
	global console
	prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
	if not prefs.console or not hasattr(prefs.console, 'show'):
		prefs.console.show = defaultshow
	if not hasattr(prefs.console, "windowbounds"):
		prefs.console.windowbounds = (450, 250)
	if not hasattr(prefs.console, "fontsettings"):
		prefs.console.fontsettings = ("Monaco", 0, 9, (0, 0, 0))
	if not hasattr(prefs.console, "tabsettings"):
		prefs.console.tabsettings = (32, 0)
	console = PyConsole(prefs.console.windowbounds, prefs.console.show, 
			prefs.console.fontsettings, prefs.console.tabsettings, 1)

def installoutput(defaultshow = 0, OutPutWindow = PyOutput):
	global output
	
	# quick 'n' dirty std in emulation
	sys.stdin = SimpleStdin()
	
	prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
	if not prefs.output or not hasattr(prefs.output, 'show'):
		prefs.output.show = defaultshow
	if not hasattr(prefs.output, "windowbounds"):
		prefs.output.windowbounds = (450, 250)
	if not hasattr(prefs.output, "fontsettings"):
		prefs.output.fontsettings = ("Monaco", 0, 9, (0, 0, 0))
	if not hasattr(prefs.output, "tabsettings"):
		prefs.output.tabsettings = (32, 0)
	output = OutPutWindow(prefs.output.windowbounds, prefs.output.show, 
			prefs.output.fontsettings, prefs.output.tabsettings)
