# wdbframewin.py -- frame window for wdb.py

# XXX To do:
# - display function name in window title
# - execute arbitrary statements instead of just evaluating expressions
# - allow setting variables by editing their values


import stdwin
from stdwinevents import *
import basewin
import sys

WIDTH = 40
MINHEIGHT = 8
MAXHEIGHT = 16

class FrameWindow(basewin.BaseWindow):

	def __init__(self, debugger, frame, dict, name):
		self.debugger = debugger
		self.frame = frame # Not used except for identity tests
		self.dict = dict
		self.name = name
		nl = max(MINHEIGHT, len(self.dict) + 5)
		nl = min(nl, MAXHEIGHT)
		width = WIDTH*stdwin.textwidth('0')
		height = nl*stdwin.lineheight()
		stdwin.setdefwinsize(width, height)
		basewin.BaseWindow.__init__(
			  self, '--Frame ' + name + '--')
		# XXX Should use current function name
		self.initeditor()
		self.displaylist = ['>>>', '', '-'*WIDTH]
		self.refreshframe()
	
	def initeditor(self):
		r = (stdwin.textwidth('>>> '), 0), (30000, stdwin.lineheight())
		self.editor = self.win.textcreate(r)
	
	def closeeditor(self):
		self.editor.close()
	
	def dispatch(self, event):
		type, win, detail = event
		if type == WE_NULL: return # Dummy tested by mainloop
		if type in (WE_DRAW, WE_COMMAND) \
				or not self.editor.event(event):
			basewin.BaseWindow.dispatch(self, event)
	
	def close(self):
		del self.debugger.framewindows[self.name]
		del self.debugger, self.dict
		self.closeeditor()
		basewin.BaseWindow.close(self)
	
	def command(self, detail):
		if detail == WC_RETURN:
			self.re_eval()
		else:
			dummy = self.editor.event(WE_COMMAND, \
						self.win, detail)
	
	def mouse_down(self, detail):
		(h, v), clicks, button, mask = detail
		if clicks != 2:
			return
		i = v / stdwin.lineheight()
		if 5 <= i < len(self.displaylist):
			import string
			name = string.splitfields(self.displaylist[i],' = ')[0]
			if not self.dict.has_key(name):
				stdwin.fleep()
				return
			value = self.dict[name]
			if not hasattr(value, '__dict__'):
				stdwin.fleep()
				return
			name = 'instance ' + `value`
			if self.debugger.framewindows.has_key(name):
				self.debugger.framewindows[name].popup()
			else:
				self.debugger.framewindows[name] = \
					  FrameWindow(self.debugger,
						  self.frame, value.__dict__,
						  name)
			return
		stdwin.fleep()

	def re_eval(self):
		import string, repr
		expr = string.strip(self.editor.gettext())
		if expr == '':
			output = ''
		else:
			globals = self.frame.f_globals
			globals['__privileged__'] = 1
			locals = self.dict
			try:
				value = eval(expr, globals, locals)
				output = repr.repr(value)
			except:
				if type(sys.exc_type) == type(''):
					exc_type_name = sys.exc_type
				else: exc_type_name = sys.exc_type.__name__
				output = exc_type_name + ': ' + `sys.exc_value`
		self.displaylist[1] = output
		lh = stdwin.lineheight()
		r = (-10, 0), (30000, 2*lh)
		self.win.change(r)
		self.editor.setfocus(0, len(expr))
	
	def draw(self, detail):
		(left, top), (right, bottom) = detail
		dummy = self.editor.draw(detail)
		d = self.win.begindrawing()
		try:
			lh = d.lineheight()
			h, v = 0, 0
			for line in self.displaylist:
				if v+lh > top and v < bottom:
					d.text((h, v), line)
				v = v + lh
		finally:
			d.close()
	
	def refreshframe(self):
		import repr
		del self.displaylist[3:]
		self.re_eval()
		names = self.dict.keys()
		for key, label in ('__args__', 'Args: '), \
				  ('__return__', 'Return: '):
			if self.dict.has_key(key):
				names.remove(key)
				value = self.dict[key]
				label = label + repr.repr(value)
			self.displaylist.append(label)
		names.sort()
		for name in names:
			value = self.dict[name]
			line = name + ' = ' + repr.repr(value)
			self.displaylist.append(line)
		self.win.setdocsize(0, \
			stdwin.lineheight() * len(self.displaylist))
		self.refreshall() # XXX Be more subtle later
