# Text formatting abstractions
# Note -- this module is obsolete, it's too slow anyway


import string
import Para


# A formatter back-end object has one method that is called by the formatter:
# addpara(p), where p is a paragraph object.  For example:


# Formatter back-end to do nothing at all with the paragraphs
class NullBackEnd:
	#
	def __init__(self):
		pass
	#
	def addpara(self, p):
		pass
	#
	def bgn_anchor(self, id):
		pass
	#
	def end_anchor(self, id):
		pass


# Formatter back-end to collect the paragraphs in a list
class SavingBackEnd(NullBackEnd):
	#
	def __init__(self):
		self.paralist = []
	#
	def addpara(self, p):
		self.paralist.append(p)
	#
	def hitcheck(self, h, v):
		hits = []
		for p in self.paralist:
			if p.top <= v <= p.bottom:
				for id in p.hitcheck(h, v):
					if id not in hits:
						hits.append(id)
		return hits
	#
	def extract(self):
		text = ''
		for p in self.paralist:
			text = text + (p.extract())
		return text
	#
	def extractpart(self, long1, long2):
		if long1 > long2: long1, long2 = long2, long1
		para1, pos1 = long1
		para2, pos2 = long2
		text = ''
		while para1 < para2:
			ptext = self.paralist[para1].extract()
			text = text + ptext[pos1:]
			pos1 = 0
			para1 = para1 + 1
		ptext = self.paralist[para2].extract()
		return text + ptext[pos1:pos2]
	#
	def whereis(self, d, h, v):
		total = 0
		for i in range(len(self.paralist)):
			p = self.paralist[i]
			result = p.whereis(d, h, v)
			if result <> None:
				return i, result
		return None
	#
	def roundtowords(self, long1, long2):
		i, offset = long1
		text = self.paralist[i].extract()
		while offset > 0 and text[offset-1] <> ' ': offset = offset-1
		long1 = i, offset
		#
		i, offset = long2
		text = self.paralist[i].extract()
		n = len(text)
		while offset < n-1 and text[offset] <> ' ': offset = offset+1
		long2 = i, offset
		#
		return long1, long2
	#
	def roundtoparagraphs(self, long1, long2):
		long1 = long1[0], 0
		long2 = long2[0], len(self.paralist[long2[0]].extract())
		return long1, long2


# Formatter back-end to send the text directly to the drawing object
class WritingBackEnd(NullBackEnd):
	#
	def __init__(self, d, width):
		self.d = d
		self.width = width
		self.lineno = 0
	#
	def addpara(self, p):
		self.lineno = p.render(self.d, 0, self.lineno, self.width)


# A formatter receives a stream of formatting instructions and assembles
# these into a stream of paragraphs on to a back-end.  The assembly is
# parametrized by a text measurement object, which must match the output
# operations of the back-end.  The back-end is responsible for splitting
# paragraphs up in lines of a given maximum width.  (This is done because
# in a windowing environment, when the window size changes, there is no
# need to redo the assembly into paragraphs, but the splitting into lines
# must be done taking the new window size into account.)


# Formatter base class.  Initialize it with a text measurement object,
# which is used for text measurements, and a back-end object,
# which receives the completed paragraphs.  The formatting methods are:
# setfont(font)
# setleftindent(nspaces)
# setjust(type) where type is 'l', 'c', 'r', or 'lr'
# flush()
# vspace(nlines)
# needvspace(nlines)
# addword(word, nspaces)
class BaseFormatter:
	#
	def __init__(self, d, b):
		# Drawing object used for text measurements
		self.d = d
		#
		# BackEnd object receiving completed paragraphs
		self.b = b
		#
		# Parameters of the formatting model
		self.leftindent = 0
		self.just = 'l'
		self.font = None
		self.blanklines = 0
		#
		# Parameters derived from the current font
		self.space = d.textwidth(' ')
		self.line = d.lineheight()
		self.ascent = d.baseline()
		self.descent = self.line - self.ascent
		#
		# Parameter derived from the default font
		self.n_space = self.space
		#
		# Current paragraph being built
		self.para = None
		self.nospace = 1
		#
		# Font to set on the next word
		self.nextfont = None
	#
	def newpara(self):
		return Para.Para()
	#
	def setfont(self, font):
		if font == None: return
		self.font = self.nextfont = font
		d = self.d
		d.setfont(font)
		self.space = d.textwidth(' ')
		self.line = d.lineheight()
		self.ascent = d.baseline()
		self.descent = self.line - self.ascent
	#
	def setleftindent(self, nspaces):
		self.leftindent = int(self.n_space * nspaces)
		if self.para:
			hang = self.leftindent - self.para.indent_left
			if hang > 0 and self.para.getlength() <= hang:
				self.para.makehangingtag(hang)
				self.nospace = 1
			else:
				self.flush()
	#
	def setrightindent(self, nspaces):
		self.rightindent = int(self.n_space * nspaces)
		if self.para:
			self.para.indent_right = self.rightindent
			self.flush()
	#
	def setjust(self, just):
		self.just = just
		if self.para:
			self.para.just = self.just
	#
	def flush(self):
		if self.para:
			self.b.addpara(self.para)
			self.para = None
			if self.font <> None:
				self.d.setfont(self.font)
		self.nospace = 1
	#
	def vspace(self, nlines):
		self.flush()
		if nlines > 0:
			self.para = self.newpara()
			tuple = None, '', 0, 0, 0, int(nlines*self.line), 0
			self.para.words.append(tuple)
			self.flush()
			self.blanklines = self.blanklines + nlines
	#
	def needvspace(self, nlines):
		self.flush() # Just to be sure
		if nlines > self.blanklines:
			self.vspace(nlines - self.blanklines)
	#
	def addword(self, text, space):
		if self.nospace and not text:
			return
		self.nospace = 0
		self.blanklines = 0
		if not self.para:
			self.para = self.newpara()
			self.para.indent_left = self.leftindent
			self.para.just = self.just
			self.nextfont = self.font
		space = int(space * self.space)
		self.para.words.append(self.nextfont, text, \
			self.d.textwidth(text), space, space, \
			self.ascent, self.descent)
		self.nextfont = None
	#
	def bgn_anchor(self, id):
		if not self.para:
			self.nospace = 0
			self.addword('', 0)
		self.para.bgn_anchor(id)
	#
	def end_anchor(self, id):
		if not self.para:
			self.nospace = 0
			self.addword('', 0)
		self.para.end_anchor(id)


# Measuring object for measuring text as viewed on a tty
class NullMeasurer:
	#
	def __init__(self):
		pass
	#
	def setfont(self, font):
		pass
	#
	def textwidth(self, text):
		return len(text)
	#
	def lineheight(self):
		return 1
	#
	def baseline(self):
		return 0


# Drawing object for writing plain ASCII text to a file
class FileWriter:
	#
	def __init__(self, fp):
		self.fp = fp
		self.lineno, self.colno = 0, 0
	#
	def setfont(self, font):
		pass
	#
	def text(self, (h, v), str):
		if not str: return
		if '\n' in str:
			raise ValueError, 'can\'t write \\n'
		while self.lineno < v:
			self.fp.write('\n')
			self.colno, self.lineno = 0, self.lineno + 1
		while self.lineno > v:
			# XXX This should never happen...
			self.fp.write('\033[A') # ANSI up arrow
			self.lineno = self.lineno - 1
		if self.colno < h:
			self.fp.write(' ' * (h - self.colno))
		elif self.colno > h:
			self.fp.write('\b' * (self.colno - h))
		self.colno = h
		self.fp.write(str)
		self.colno = h + len(str)


# Formatting class to do nothing at all with the data
class NullFormatter(BaseFormatter):
	#
	def __init__(self):
		d = NullMeasurer()
		b = NullBackEnd()
		BaseFormatter.__init__(self, d, b)


# Formatting class to write directly to a file
class WritingFormatter(BaseFormatter):
	#
	def __init__(self, fp, width):
		dm = NullMeasurer()
		dw = FileWriter(fp)
		b = WritingBackEnd(dw, width)
		BaseFormatter.__init__(self, dm, b)
		self.blanklines = 1
	#
	# Suppress multiple blank lines
	def needvspace(self, nlines):
		BaseFormatter.needvspace(self, min(1, nlines))


# A "FunnyFormatter" writes ASCII text with a twist: *bold words*,
# _italic text_ and _underlined words_, and `quoted text'.
# It assumes that the fonts are 'r', 'i', 'b', 'u', 'q': (roman,
# italic, bold, underline, quote).
# Moreover, if the font is in upper case, the text is converted to
# UPPER CASE.
class FunnyFormatter(WritingFormatter):
	#
	def flush(self):
		if self.para: finalize(self.para)
		WritingFormatter.flush(self)


# Surrounds *bold words* and _italic text_ in a paragraph with
# appropriate markers, fixing the size (assuming these characters'
# width is 1).
openchar = \
    {'b':'*', 'i':'_', 'u':'_', 'q':'`', 'B':'*', 'I':'_', 'U':'_', 'Q':'`'}
closechar = \
    {'b':'*', 'i':'_', 'u':'_', 'q':'\'', 'B':'*', 'I':'_', 'U':'_', 'Q':'\''}
def finalize(para):
	oldfont = curfont = 'r'
	para.words.append(('r', '', 0, 0, 0, 0)) # temporary, deleted at end
	for i in range(len(para.words)):
		fo, te, wi = para.words[i][:3]
		if fo <> None: curfont = fo
		if curfont <> oldfont:
			if closechar.has_key(oldfont):
				c = closechar[oldfont]
				j = i-1
				while j > 0 and para.words[j][1] == '': j = j-1
				fo1, te1, wi1 = para.words[j][:3]
				te1 = te1 + c
				wi1 = wi1 + len(c)
				para.words[j] = (fo1, te1, wi1) + \
					para.words[j][3:]
			if openchar.has_key(curfont) and te:
				c = openchar[curfont]
				te = c + te
				wi = len(c) + wi
				para.words[i] = (fo, te, wi) + \
					para.words[i][3:]
			if te: oldfont = curfont
			else: oldfont = 'r'
		if curfont in string.uppercase:
			te = string.upper(te)
			para.words[i] = (fo, te, wi) + para.words[i][3:]
	del para.words[-1]


# Formatter back-end to draw the text in a window.
# This has an option to draw while the paragraphs are being added,
# to minimize the delay before the user sees anything.
# This manages the entire "document" of the window.
class StdwinBackEnd(SavingBackEnd):
	#
	def __init__(self, window, drawnow):
		self.window = window
		self.drawnow = drawnow
		self.width = window.getwinsize()[0]
		self.selection = None
		self.height = 0
		window.setorigin(0, 0)
		window.setdocsize(0, 0)
		self.d = window.begindrawing()
		SavingBackEnd.__init__(self)
	#
	def finish(self):
		self.d.close()
		self.d = None
		self.window.setdocsize(0, self.height)
	#
	def addpara(self, p):
		self.paralist.append(p)
		if self.drawnow:
			self.height = \
				p.render(self.d, 0, self.height, self.width)
		else:
			p.layout(self.width)
			p.left = 0
			p.top = self.height
			p.right = self.width
			p.bottom = self.height + p.height
			self.height = p.bottom
	#
	def resize(self):
		self.window.change((0, 0), (self.width, self.height))
		self.width = self.window.getwinsize()[0]
		self.height = 0
		for p in self.paralist:
			p.layout(self.width)
			p.left = 0
			p.top = self.height
			p.right = self.width
			p.bottom = self.height + p.height
			self.height = p.bottom
		self.window.change((0, 0), (self.width, self.height))
		self.window.setdocsize(0, self.height)
	#
	def redraw(self, area):
		d = self.window.begindrawing()
		(left, top), (right, bottom) = area
		d.erase(area)
		d.cliprect(area)
		for p in self.paralist:
			if top < p.bottom and p.top < bottom:
				v = p.render(d, p.left, p.top, p.right)
		if self.selection:
			self.invert(d, self.selection)
		d.close()
	#
	def setselection(self, new):
		if new:
			long1, long2 = new
			pos1 = long1[:3]
			pos2 = long2[:3]
			new = pos1, pos2
		if new <> self.selection:
			d = self.window.begindrawing()
			if self.selection:
				self.invert(d, self.selection)
			if new:
				self.invert(d, new)
			d.close()
			self.selection = new
	#
	def getselection(self):
		return self.selection
	#
	def extractselection(self):
		if self.selection:
			a, b = self.selection
			return self.extractpart(a, b)
		else:
			return None
	#
	def invert(self, d, region):
		long1, long2 = region
		if long1 > long2: long1, long2 = long2, long1
		para1, pos1 = long1
		para2, pos2 = long2
		while para1 < para2:
			self.paralist[para1].invert(d, pos1, None)
			pos1 = None
			para1 = para1 + 1
		self.paralist[para2].invert(d, pos1, pos2)
	#
	def search(self, prog):
		import re, string
		if type(prog) == type(''):
			prog = re.compile(string.lower(prog))
		if self.selection:
			iold = self.selection[0][0]
		else:
			iold = -1
		hit = None
		for i in range(len(self.paralist)):
			if i == iold or i < iold and hit:
				continue
			p = self.paralist[i]
			text = string.lower(p.extract())
			match = prog.search(text)
			if match:
				a, b = match.group(0)
				long1 = i, a
				long2 = i, b
				hit = long1, long2
				if i > iold:
					break
		if hit:
			self.setselection(hit)
			i = hit[0][0]
			p = self.paralist[i]
			self.window.show((p.left, p.top), (p.right, p.bottom))
			return 1
		else:
			return 0
	#
	def showanchor(self, id):
		for i in range(len(self.paralist)):
			p = self.paralist[i]
			if p.hasanchor(id):
				long1 = i, 0
				long2 = i, len(p.extract())
				hit = long1, long2
				self.setselection(hit)
				self.window.show( \
					(p.left, p.top), (p.right, p.bottom))
				break


# GL extensions

class GLFontCache:
	#
	def __init__(self):
		self.reset()
		self.setfont('')
	#
	def reset(self):
		self.fontkey = None
		self.fonthandle = None
		self.fontinfo = None
		self.fontcache = {}
	#
	def close(self):
		self.reset()
	#
	def setfont(self, fontkey):
		if fontkey == '':
			fontkey = 'Times-Roman 12'
		elif ' ' not in fontkey:
			fontkey = fontkey + ' 12'
		if fontkey == self.fontkey:
			return
		if self.fontcache.has_key(fontkey):
			handle = self.fontcache[fontkey]
		else:
			import string
			i = string.index(fontkey, ' ')
			name, sizestr = fontkey[:i], fontkey[i:]
			size = eval(sizestr)
			key1 = name + ' 1'
			key = name + ' ' + `size`
			# NB key may differ from fontkey!
			if self.fontcache.has_key(key):
				handle = self.fontcache[key]
			else:
				if self.fontcache.has_key(key1):
					handle = self.fontcache[key1]
				else:
					import fm
					handle = fm.findfont(name)
					self.fontcache[key1] = handle
				handle = handle.scalefont(size)
				self.fontcache[fontkey] = \
					self.fontcache[key] = handle
		self.fontkey = fontkey
		if self.fonthandle <> handle:
			self.fonthandle = handle
			self.fontinfo = handle.getfontinfo()
			handle.setfont()


class GLMeasurer(GLFontCache):
	#
	def textwidth(self, text):
		return self.fonthandle.getstrwidth(text)
	#
	def baseline(self):
		return self.fontinfo[6] - self.fontinfo[3]
	#
	def lineheight(self):
		return self.fontinfo[6]


class GLWriter(GLFontCache):
	#
	# NOTES:
	# (1) Use gl.ortho2 to use X pixel coordinates!
	#
	def text(self, (h, v), text):
		import gl, fm
		gl.cmov2i(h, v + self.fontinfo[6] - self.fontinfo[3])
		fm.prstr(text)
	#
	def setfont(self, fontkey):
		oldhandle = self.fonthandle
		GLFontCache.setfont(fontkey)
		if self.fonthandle <> oldhandle:
			handle.setfont()


class GLMeasurerWriter(GLMeasurer, GLWriter):
	pass


class GLBackEnd(SavingBackEnd):
	#
	def __init__(self, wid):
		import gl
		gl.winset(wid)
		self.wid = wid
		self.width = gl.getsize()[1]
		self.height = 0
		self.d = GLMeasurerWriter()
		SavingBackEnd.__init__(self)
	#
	def finish(self):
		pass
	#
	def addpara(self, p):
		self.paralist.append(p)
		self.height = p.render(self.d, 0, self.height, self.width)
	#
	def redraw(self):
		import gl
		gl.winset(self.wid)
		width = gl.getsize()[1]
		if width <> self.width:
			setdocsize = 1
			self.width = width
			for p in self.paralist:
				p.top = p.bottom = None
		d = self.d
		v = 0
		for p in self.paralist:
			v = p.render(d, 0, v, width)
