import Qd
import Win
import QuickDraw
import Evt
import string
from types import *
import sys

WidgetsError = "WidgetsError"

DEBUG = 0

class Widget:
	
	"""Base class for all widgets."""
	
	_selectable = 0
	
	def __init__(self, possize):
		self._widgets = []
		self._widgetsdict = {}
		self._possize = possize
		self._bounds = None
		self._visible = 1
		self._enabled = 0
		self._selected = 0
		self._activated = 0
		self._callback = None
		self._parent = None
		self._parentwindow = None
		self._bindings = {}
		self._backcolor = None
	
	def show(self, onoff):
		self._visible = onoff
		for w in self._widgets:
			w.show(onoff)
		if self._parentwindow is not None and self._parentwindow.wid is not None:
			self.SetPort()
			if onoff:
				self.draw()
			else:
				Qd.EraseRect(self._bounds)
	
	def draw(self, visRgn = None):
		if self._visible:
			# draw your stuff here
			pass
	
	def getpossize(self):
		return self._possize
	
	def getbounds(self):
		return self._bounds
	
	def move(self, x, y = None):
		"""absolute move"""
		if y == None:
			x, y = x
		if type(self._possize) <> TupleType:
			raise WidgetsError, "can't move widget with bounds function"
		l, t, r, b = self._possize
		self.resize(x, y, r, b)
	
	def rmove(self, x, y = None):
		"""relative move"""
		if y == None:
			x, y = x
		if type(self._possize) <> TupleType:
			raise WidgetsError, "can't move widget with bounds function"
		l, t, r, b = self._possize
		self.resize(l + x, t + y, r, b)
		
	def resize(self, *args):
		if len(args) == 1:
			if type(args[0]) == FunctionType or type(args[0]) == MethodType:
				self._possize = args[0]
			else:
				apply(self.resize, args[0])
		elif len(args) == 2:
			self._possize = (0, 0) + args
		elif len(args) == 4:
			self._possize = args
		else:
			raise TypeError, "wrong number of arguments"
		self._calcbounds()
	
	def open(self):
		self._calcbounds()
	
	def close(self):
		del self._callback
		del self._possize
		del self._bindings
		del self._parent
		del self._parentwindow
	
	def bind(self, key, callback):
		"""bind a key or an 'event' to a callback"""
		if callback:
			self._bindings[key] = callback
		elif self._bindings.has_key(key):
			del self._bindings[key]
	
	def adjust(self, oldbounds):
		self.SetPort()
		self.GetWindow().InvalWindowRect(oldbounds)
		self.GetWindow().InvalWindowRect(self._bounds)
	
	def _calcbounds(self):
		# calculate absolute bounds relative to the window origin from our
		# abstract _possize attribute, which is either a 4-tuple or a callable object
		oldbounds = self._bounds
		pl, pt, pr, pb = self._parent._bounds
		if callable(self._possize):
			# _possize is callable, let it figure it out by itself: it should return 
			# the bounds relative to our parent widget.
			width = pr - pl
			height = pb - pt
			self._bounds = Qd.OffsetRect(self._possize(width, height), pl, pt)
		else:
			# _possize must be a 4-tuple. This is where the algorithm by Peter Kriens and
			# Petr van Blokland kicks in. (*** Parts of this algorithm are applied for 
			# patents by Ericsson, Sweden ***)
			l, t, r, b = self._possize
			# depending on the values of l(eft), t(op), r(right) and b(ottom), 
			# they mean different things:
			if l < -1:
				# l is less than -1, this mean it measures from the *right* of it's parent
				l = pr + l
			else:
				# l is -1 or greater, this mean it measures from the *left* of it's parent
				l = pl + l
			if t < -1:
				# t is less than -1, this mean it measures from the *bottom* of it's parent
				t = pb + t
			else:
				# t is -1 or greater, this mean it measures from the *top* of it's parent
				t = pt + t
			if r > 1:
				# r is greater than 1, this means r is the *width* of the widget
				r = l + r
			else:
				# r is less than 1, this means it measures from the *right* of it's parent
				r = pr + r
			if b > 1:
				# b is greater than 1, this means b is the *height* of the widget
				b = t + b
			else:
				# b is less than 1, this means it measures from the *bottom* of it's parent
				b = pb + b
			self._bounds = (l, t, r, b)
		if oldbounds and oldbounds <> self._bounds:
			self.adjust(oldbounds)
		for w in self._widgets:
			w._calcbounds()
	
	def test(self, point):
		if Qd.PtInRect(point, self._bounds):
			return 1
	
	def click(self, point, modifiers):
		pass
	
	def findwidget(self, point, onlyenabled = 1):
		if self.test(point):
			for w in self._widgets:
				widget = w.findwidget(point)
				if widget is not None:
					return widget
			if self._enabled or not onlyenabled:
				return self
	
	def forall(self, methodname, *args):
		for w in self._widgets:
			rv = apply(w.forall, (methodname,) + args)
			if rv: 
				return rv
		if self._bindings.has_key("<" + methodname + ">"):
			callback = self._bindings["<" + methodname + ">"]
			rv = apply(callback, args)
			if rv: 
				return rv
		if hasattr(self, methodname):
			method = getattr(self, methodname)
			return apply(method, args)
	
	def forall_butself(self, methodname, *args):
		for w in self._widgets:
			rv = apply(w.forall, (methodname,) + args)
			if rv: 
				return rv
	
	def forall_frombottom(self, methodname, *args):
		if self._bindings.has_key("<" + methodname + ">"):
			callback = self._bindings["<" + methodname + ">"]
			rv = apply(callback, args)
			if rv: 
				return rv
		if hasattr(self, methodname):
			method = getattr(self, methodname)
			rv = apply(method, args)
			if rv: 
				return rv
		for w in self._widgets:
			rv = apply(w.forall_frombottom, (methodname,) + args)
			if rv: 
				return rv
	
	def _addwidget(self, key, widget):
		if widget in self._widgets:
			raise ValueError, "duplicate widget"
		if self._widgetsdict.has_key(key):
			self._removewidget(key)
		self._widgets.append(widget)
		self._widgetsdict[key] = widget
		widget._parent = self
		self._setparentwindow(widget)
		if self._parentwindow and self._parentwindow.wid:
			widget.forall_frombottom("open")
			self.GetWindow().InvalWindowRect(widget._bounds)
	
	def _setparentwindow(self, widget):
		widget._parentwindow = self._parentwindow
		for w in widget._widgets:
			self._setparentwindow(w)
	
	def _removewidget(self, key):
		if not self._widgetsdict.has_key(key):
			raise KeyError, "no widget with key " + `key`
		widget = self._widgetsdict[key]
		for k in widget._widgetsdict.keys():
			widget._removewidget(k)
		if self._parentwindow._currentwidget == widget:
			widget.select(0)
			self._parentwindow._currentwidget = None
		self.SetPort()
		self.GetWindow().InvalWindowRect(widget._bounds)
		widget.close()
		del self._widgetsdict[key]
		self._widgets.remove(widget)
	
	def __setattr__(self, attr, value):
		if type(value) == InstanceType and isinstance(value, Widget) and	\
				attr not in ("_currentwidget", "_lastrollover", 
				"_parent", "_parentwindow", "_defaultbutton"):
			if hasattr(self, attr):
				raise ValueError, "Can't replace existing attribute: " + attr
			self._addwidget(attr, value)
		self.__dict__[attr] = value
	
	def __delattr__(self, attr):
		if attr == "_widgetsdict":
			raise AttributeError, "cannot delete attribute _widgetsdict"
		if self._widgetsdict.has_key(attr):
			self._removewidget(attr)
			if self.__dict__.has_key(attr):
				del self.__dict__[attr]
		elif self.__dict__.has_key(attr):
			del self.__dict__[attr]
		else:
			raise AttributeError, attr
	
	def __setitem__(self, key, value):
		self._addwidget(key, value)
	
	def __getitem__(self, key):
		if not self._widgetsdict.has_key(key):
			raise KeyError, key
		return self._widgetsdict[key]
	
	def __delitem__(self, key):
		self._removewidget(key)
	
	def SetPort(self):
		self._parentwindow.SetPort()
		

	def GetWindow(self):
		return self._parentwindow.GetWindow()
		
	def __del__(self):
		if DEBUG:
			print "%s instance deleted" % self.__class__.__name__
	
	def _drawbounds(self):
		Qd.FrameRect(self._bounds)


class ClickableWidget(Widget):
	
	"""Base class for clickable widgets. (note: self._enabled must be true to receive click events.)"""
	
	def click(self, point, modifiers):
		pass
	
	def enable(self, onoff):
		self._enabled = onoff
		self.SetPort()
		self.draw()
	
	def callback(self):
		if self._callback:
			return CallbackCall(self._callback, 1)
	

class SelectableWidget(ClickableWidget):

	"""Base class for selectable widgets."""
	
	_selectable = 1
	
	def select(self, onoff, isclick = 0):
		if onoff == self._selected:
			return 1
		if self._bindings.has_key("<select>"):
			callback = self._bindings["<select>"]
			if callback(onoff):
				return 1
		self._selected = onoff
		if onoff:
			if self._parentwindow._currentwidget is not None:
				self._parentwindow._currentwidget.select(0)
			self._parentwindow._currentwidget = self
		else:
			self._parentwindow._currentwidget = None
	
	def key(self, char, event):
		pass
	
	def drawselframe(self, onoff):
		if not self._parentwindow._hasselframes:
			return
		thickrect = Qd.InsetRect(self._bounds, -3, -3)
		state = Qd.GetPenState()
		Qd.PenSize(2, 2)
		if onoff:
			Qd.PenPat(Qd.qd.black)
		else:
			Qd.PenPat(Qd.qd.white)
		Qd.FrameRect(thickrect)
		Qd.SetPenState(state)
	
	def adjust(self, oldbounds):
		self.SetPort()
		if self._selected:
			self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3))
			self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3))
		else:
			self.GetWindow().InvalWindowRect(oldbounds)
			self.GetWindow().InvalWindowRect(self._bounds)


class _Line(Widget):
	
	def __init__(self, possize, thickness = 1):
		Widget.__init__(self, possize)
		self._thickness = thickness
	
	def open(self):
		self._calcbounds()
		self.SetPort()
		self.draw()
	
	def draw(self, visRgn = None):
		if self._visible:
			Qd.PaintRect(self._bounds)
	
	def _drawbounds(self):
		pass

class HorizontalLine(_Line):
	
	def _calcbounds(self):
		Widget._calcbounds(self)
		l, t, r, b = self._bounds
		self._bounds = l, t, r, t + self._thickness

class VerticalLine(_Line):
	
	def _calcbounds(self):
		Widget._calcbounds(self)
		l, t, r, b = self._bounds
		self._bounds = l, t, l + self._thickness, b


class Frame(Widget):
	
	def __init__(self, possize, pattern = Qd.qd.black, color = (0, 0, 0)):
		Widget.__init__(self, possize)
		self._framepattern = pattern
		self._framecolor = color
	
	def setcolor(self, color):
		self._framecolor = color
		self.SetPort()
		self.draw()
	
	def setpattern(self, pattern):
		self._framepattern = pattern
		self.SetPort()
		self.draw()
		
	def draw(self, visRgn = None):
		if self._visible:
			penstate = Qd.GetPenState()
			Qd.PenPat(self._framepattern)
			Qd.RGBForeColor(self._framecolor)
			Qd.FrameRect(self._bounds)
			Qd.RGBForeColor((0, 0, 0))
			Qd.SetPenState(penstate)

def _darkencolor((r, g, b)):
	return 0.75 * r, 0.75 * g, 0.75 * b

class BevelBox(Widget):
	
	"""'Platinum' beveled rectangle."""
	
	def __init__(self, possize, color = (0xe000, 0xe000, 0xe000)):
		Widget.__init__(self, possize)
		self._color = color
		self._darkercolor = _darkencolor(color)
	
	def setcolor(self, color):
		self._color = color
		self.SetPort()
		self.draw()
	
	def draw(self, visRgn = None):
		if self._visible:
			l, t, r, b = Qd.InsetRect(self._bounds, 1, 1)
			Qd.RGBForeColor(self._color)
			Qd.PaintRect((l, t, r, b))
			Qd.RGBForeColor(self._darkercolor)
			Qd.MoveTo(l, b)
			Qd.LineTo(r, b)
			Qd.LineTo(r, t)
			Qd.RGBForeColor((0, 0, 0))


class Group(Widget):
	
	"""A container for subwidgets"""


class HorizontalPanes(Widget):
	
	"""Panes, a.k.a. frames. Works a bit like a group. Devides the widget area into "panes",
	which can be resized by the user by clicking and dragging between the subwidgets."""
	
	_direction = 1
	
	def __init__(self, possize, panesizes = None, gutter = 8):
		"""panesizes should be a tuple of numbers. The length of the tuple is the number of panes, 
		the items in the tuple are the relative sizes of these panes; these numbers should add up 
		to 1 (the total size of all panes)."""
		ClickableWidget.__init__(self, possize)
		self._panesizes = panesizes
		self._gutter = gutter
		self._enabled = 1
		self.setuppanes()
	
	#def open(self):
	#	self.installbounds()
	#	ClickableWidget.open(self)
	
	def _calcbounds(self):
		# hmmm. It should not neccesary be override _calcbounds :-(
		self.installbounds()
		Widget._calcbounds(self)
	
	def setuppanes(self):
		panesizes = self._panesizes
		total = 0
		if panesizes is not None:
			#if len(self._widgets) <> len(panesizes):
			#	raise TypeError, 'number of widgets does not match number of panes'
			for panesize in panesizes:
				if not 0 < panesize < 1:
					raise TypeError, 'pane sizes must be between 0 and 1, not including.'
				total = total + panesize
			if round(total, 4) <> 1.0:
				raise TypeError, 'pane sizes must add up to 1'
		else:
			# XXX does not work!
			step = 1.0 / len(self._widgets)
			panesizes = []
			for i in range(len(self._widgets)):
				panesizes.append(step)
		current = 0
		self._panesizes = []
		self._gutters = []
		for panesize in panesizes:
			if current:
				self._gutters.append(current)
			self._panesizes.append((current, current + panesize))
			current = current + panesize
		self.makepanebounds()
	
	def getpanesizes(self):
		return map(lambda (fr, to): to-fr,  self._panesizes)
	
	boundstemplate = "lambda width, height: (0, height * %s + %d, width, height * %s + %d)"
	
	def makepanebounds(self):
		halfgutter = self._gutter / 2
		self._panebounds = []
		for i in range(len(self._panesizes)):
			panestart, paneend = self._panesizes[i]
			boundsstring = self.boundstemplate % (`panestart`, panestart and halfgutter, 
							`paneend`, (paneend <> 1.0) and -halfgutter)
			self._panebounds.append(eval(boundsstring))
	
	def installbounds(self):
		#self.setuppanes()
		for i in range(len(self._widgets)):
			w = self._widgets[i]
			w._possize = self._panebounds[i]
			#if hasattr(w, "setuppanes"):
			#	w.setuppanes()
			if hasattr(w, "installbounds"):
				w.installbounds()
	
	def rollover(self, point, onoff):
		if onoff:
			orgmouse = point[self._direction]
			halfgutter = self._gutter / 2
			l, t, r, b = self._bounds
			if self._direction:
				begin, end = t, b
			else:
				begin, end = l, r
			
			i = self.findgutter(orgmouse, begin, end)
			if i is None:
				SetCursor("arrow")
			else:
				SetCursor(self._direction and 'vmover' or 'hmover')
	
	def findgutter(self, orgmouse, begin, end):
		tolerance = max(4, self._gutter) / 2
		for i in range(len(self._gutters)):
			pos = begin + (end - begin) * self._gutters[i]
			if abs(orgmouse - pos) <= tolerance:
				break
		else:
			return
		return i
	
	def click(self, point, modifiers):
		# what a mess...
		orgmouse = point[self._direction]
		halfgutter = self._gutter / 2
		l, t, r, b = self._bounds
		if self._direction:
			begin, end = t, b
		else:
			begin, end = l, r
		
		i = self.findgutter(orgmouse, begin, end)
		if i is None:
			return
		
		pos = orgpos = begin + (end - begin) * self._gutters[i]	# init pos too, for fast click on border, bug done by Petr
		
		minpos = self._panesizes[i][0]
		maxpos = self._panesizes[i+1][1]
		minpos = begin + (end - begin) * minpos + 64
		maxpos = begin + (end - begin) * maxpos - 64
		if minpos > orgpos and maxpos < orgpos:
			return
		
		#SetCursor("fist")
		self.SetPort()
		if self._direction:
			rect = l, orgpos - 1, r, orgpos
		else:
			rect = orgpos - 1, t, orgpos, b
		
		# track mouse --- XXX  move to separate method?
		Qd.PenMode(QuickDraw.srcXor)
		Qd.PenPat(Qd.qd.gray)
		Qd.PaintRect(rect)
		lastpos = None
		while Evt.Button():
			pos = orgpos - orgmouse + Evt.GetMouse()[self._direction]
			pos = max(pos, minpos)
			pos = min(pos, maxpos)
			if pos == lastpos:
				continue
			Qd.PenPat(Qd.qd.gray)
			Qd.PaintRect(rect)
			if self._direction:
				rect = l, pos - 1, r, pos
			else:
				rect = pos - 1, t, pos, b
			Qd.PenPat(Qd.qd.gray)
			Qd.PaintRect(rect)
			lastpos = pos
		Qd.PaintRect(rect)
		Qd.PenNormal()
		SetCursor("watch")
		
		newpos = (pos - begin) / float(end - begin)
		self._gutters[i] = newpos
		self._panesizes[i] = self._panesizes[i][0], newpos
		self._panesizes[i+1] = newpos, self._panesizes[i+1][1]
		self.makepanebounds()
		self.installbounds()
		self._calcbounds()
	

class VerticalPanes(HorizontalPanes):
	"""see HorizontalPanes"""
	_direction = 0
	boundstemplate = "lambda width, height: (width * %s + %d, 0, width * %s + %d, height)"


class ColorPicker(ClickableWidget):
	
	"""Color picker widget. Allows the user to choose a color."""
	
	def __init__(self, possize, color = (0, 0, 0), callback = None):
		ClickableWidget.__init__(self, possize)
		self._color = color
		self._callback = callback
		self._enabled = 1
	
	def click(self, point, modifiers):
		if not self._enabled:
			return
		import ColorPicker
		newcolor, ok = ColorPicker.GetColor("", self._color)
		if ok:
			self._color = newcolor
			self.SetPort()
			self.draw()
			if self._callback:
				return CallbackCall(self._callback, 0, self._color)
	
	def set(self, color):
		self._color = color
		self.SetPort()
		self.draw()
	
	def get(self):
		return self._color
	
	def draw(self, visRgn=None):
		if self._visible:
			if not visRgn:
				visRgn = self._parentwindow.wid.GetWindowPort().visRgn
			Qd.PenPat(Qd.qd.gray)
			rect = self._bounds
			Qd.FrameRect(rect)
			rect = Qd.InsetRect(rect, 3, 3)
			Qd.PenNormal()
			Qd.RGBForeColor(self._color)
			Qd.PaintRect(rect)
			Qd.RGBForeColor((0, 0, 0))
			

# misc utils

def CallbackCall(callback, mustfit, *args):
	"""internal helper routine for W"""
	# XXX this function should die.
	if type(callback) == FunctionType:
		func = callback
		maxargs = func.func_code.co_argcount
	elif type(callback) == MethodType:
		func = callback.im_func
		maxargs = func.func_code.co_argcount - 1
	else:
		if callable(callback):
			return apply(callback, args)
		else:
			raise TypeError, "uncallable callback object"
	
	if func.func_defaults:
		minargs = maxargs - len(func.func_defaults)
	else:
		minargs = maxargs
	if minargs <= len(args) <= maxargs:
		return apply(callback, args)
	elif not mustfit and minargs == 0:
		return callback()
	else:
		if mustfit:
			raise TypeError, "callback accepts wrong number of arguments: " + `len(args)`
		else:
			raise TypeError, "callback accepts wrong number of arguments: 0 or " + `len(args)`


def HasBaseClass(obj, class_):
	try:
		raise obj
	except class_:
		return 1
	except:
		pass
	return 0


_cursors = {
	"watch"	: Qd.GetCursor(QuickDraw.watchCursor).data,
	"arrow"	: Qd.qd.arrow,
	"iBeam"	: Qd.GetCursor(QuickDraw.iBeamCursor).data,
	"cross"	: Qd.GetCursor(QuickDraw.crossCursor).data,
	"plus"		: Qd.GetCursor(QuickDraw.plusCursor).data,
	"hand"	: Qd.GetCursor(468).data,
	"fist"		: Qd.GetCursor(469).data,
	"hmover"	: Qd.GetCursor(470).data,
	"vmover"	: Qd.GetCursor(471).data,
	"zoomin"	: Qd.GetCursor(472).data,
	"zoomout"	: Qd.GetCursor(473).data,
	"zoom"	: Qd.GetCursor(474).data,
}

def SetCursor(what):
	"""Set the cursorshape to any of these: 'arrow', 'cross', 'fist', 'hand', 'hmover', 'iBeam', 
	'plus', 'vmover', 'watch', 'zoom', 'zoomin', 'zoomout'."""
	Qd.SetCursor(_cursors[what])
