import re
import string
import sys
import os
import Image
import ImageDraw

from svxrecords import svxleg, svxleginfo, svxblock
from svxload import svxloader
from svxnetwork import Getlegbbox


class passagedata:
	def __init__(self, passagename):
		self.passagename = passagename
		self.legs = [ ]
		self.length = 0.0
		self.dates = [ ]
		self.teams = [ ]
		self.joiningpassages = [ ]
		self.description = "<p>No Description</p>"

	def addleg(self, leg):
		self.legs.append(leg)
		if not leg.leginfo.flags["splay"] and not leg.leginfo.flags["duplicate"] and not leg.leginfo.flags["surface"]:
			self.length += leg.tape
		if leg.leginfo.date not in self.dates:
			self.dates.append(leg.leginfo.date)
		for t in leg.leginfo.team:
			if t not in self.teams:
				self.teams.append(t)

		# search all joining legs to this passage
		for e in range(2):
			sx = (e and leg.sxto or leg.sxfrom)
			for jleg in sx.legs:
				if jleg.leginfo.title != self.passagename and jleg.leginfo.title not in self.joiningpassages:
					self.joiningpassages.append(jleg.leginfo.title)


	def write(self, fout, imname, imnamec, passagemap):


		fout.write('<table width="100%"><tr>\n')

		if imname:
				fout.write('<td valign="top"><img src="%s" border=1px></td>\n' % imname)

 		fout.write('<td width="70%" valign="top">\n')
		fout.write('<h2><a name="%s"></a>%s</h2>\n' % (self.aref, self.passagename))
		fout.write('<table>\n')

		fout.write('<tr><td width="40%"><b>Neighbouring passages:</b></td><td>\n')
		pjpass = None
		for jpass in self.joiningpassages:
			if pjpass:
				fout.write(', ')
			fout.write('<a href="#%s">%s</a>' % (passagemap[jpass].aref, jpass))
			pjpass = jpass
		fout.write('</td></tr>\n')

		fout.write('<tr><td><b>Dates of exploration:</b> </td><td> %s </td></tr>\n' % string.join(self.dates, ", "))
		fout.write('<tr><td><b>Passage length:</b> </td><td> %.1f </td></tr>\n' % self.length)
		fout.write('<tr><td><b>Number of survey legs:</b> </td><td> %d </td></tr>\n' % len(self.legs))

		# build up the bracketed list by merging duplicate names
		fout.write('<tr><td><b>Surveying teams:</b> </td><td>\n')
		self.teams.sort()
		prevt = None
		for t in self.teams:
			if prevt and prevt[0] == t[0]:
				if prevt[1] != t[1]:
					fout.write(", %s" % t[1]);
			else:
				if prevt:
					fout.write("), ")
				fout.write("%s (%s" % t)
			prevt = t
		if prevt:
			fout.write(")")
		fout.write('</td></tr>\n')
		fout.write('</table>\n')

		fout.write('<h3>Description</h3>\n');
		fout.write(self.description)
		fout.write('\n');

		if imnamec:
			fout.write('</td><td valign="top"><img src="%s" border=1px>\n' % imnamec)

		fout.write("</td></tr></table>\n")


def scaxy(x, y, bbox):
	scalefactor = 200/min((bbox[0][1] - bbox[0][0]),(bbox[1][1] - bbox[1][0]))
	return (int(scalefactor * (x - bbox[0][0])), int(scalefactor * (bbox[1][1] - y)))

def RenderPassage(legs, passagedata, bbox, imname):
	if (bbox[0][1]- bbox[0][0])> (bbox[1][1] - bbox[1][0]):  #make rectangle 200px on smallest side
		ywidth = 200
		xwidth = int(200 * (bbox[0][1]- bbox[0][0]) / (bbox[1][1] - bbox[1][0]) )
	else:
		ywidth = int(200 *  (bbox[1][1] - bbox[1][0])/ (bbox[0][1]- bbox[0][0]) )
		xwidth = 200
	im = Image.new("RGB", (xwidth, ywidth), (128,128,128))
	imd = ImageDraw.Draw(im)
	for leg in legs:
		if leg.leginfo.title == passagedata.passagename:
			imd.setink((105, 255, 80))
		elif leg.leginfo.title in passagedata.joiningpassages:
			imd.setink((255, 128, 0))
		else:
			imd.setink((225, 0, 0))

		p0 = scaxy(leg.sxfrom.pos[0], leg.sxfrom.pos[1], bbox)
		p1 = scaxy(leg.sxto.pos[0], leg.sxto.pos[1], bbox)
		imd.line((p0[0], p0[1], p1[0], p1[1]))
	print "Saving image", imname
	im.save(imname)


def ImportCavePassageData(passagemap, cavedatabasefile):
	print "Scanning '%s' for passage descriptions" % cavedatabasefile

	fin = open(cavedatabasefile)
	cavedata = fin.read()  # the whole thing as a string
	fin.close()

	for pd in re.findall('<Section\s+name="(.*?)"[\s\S]*?<Description>([\s\S]*?)</Description>', cavedata):
		if pd[0] in passagemap:
			# we have a description; mark up the passage names
			# after splitting on the em flags (although they shouldn't be necessary)
			spd = re.split('<em class="passage">(.*?)</em>', pd[1])
			lspd = [ ]
			for p in spd:
				if p in passagemap:
					lspd.append('<a href="#%s">%s</a>' % (passagemap[p].aref, p))
				else:
					lspd.append(p)
			passagemap[pd[0]].description = string.join(lspd)

# function which builds a table of all we know about the passages
def PassageInfo(legs, fout, bbox, imdire, sfileroot, cavedatabasefile):

	# put all the legs into passages
	passagemap = { }
	for leg in legs:
		if leg.leginfo.title not in passagemap:
			passagemap[leg.leginfo.title] = passagedata(leg.leginfo.title)
		passagemap[leg.leginfo.title].addleg(leg)

	# make the internal hyperlinks
	passages = passagemap.keys()
	passages.sort()
	for i in range(len(passages)):
		passage = passagemap[passages[i]]
		passage.aref = "pref%d" % i

	# import any descriptions from the database file
	if cavedatabasefile:
		ImportCavePassageData(passagemap, cavedatabasefile)
	passimname = "passim" + sfileroot[-min(6, len(sfileroot)):]
	n = 1
	fout.write('<html><body bgcolor=#808080 text=white link=yellow >\n') #set the style of the page

	for passagen in passages:
		passage = passagemap[passagen]
		if bbox and imdire:
			imname = os.path.join(imdire, "%s%d.png" % (passimname, n))
			RenderPassage(legs, passage, bbox, imname)

			# close-up view of the passage
			imnamec = os.path.join(imdire, "%sC%d.png" % (passimname, n))
			lpbbox = Getlegbbox(passage.legs)
			bboxoff = max(lpbbox[0][1] - lpbbox[0][0], lpbbox[1][1] - lpbbox[1][0])
			pbbox = [[lpbbox[0][0] - bboxoff, lpbbox[0][1] + bboxoff], [lpbbox[1][0] - bboxoff, lpbbox[1][1] + bboxoff]]
			RenderPassage(legs, passage, pbbox, imnamec)
		else:
			imname = None
			imnamec = None
		passage.write(fout, imname, imnamec, passagemap)
		n += 1