# 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:
				output = sys.exc_type + ': ' + `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
