#! /usr/bin/python
# -*- coding: iso-8859-15 -*-

##
## bilderspur_std_plugin.py
##  - a part of Bilderspur, a tool for converting Google Earth into
##    a photo album
##
##    This module provides the default functionality for generating
##    URLs of thumbnail images and the HTML description texts embedded
##    within the KML file.
##
## See http://www.ohrner.net/ for latest news and updates, please.
## 
## Copyright (C) 2007  Gunter Ohrner "gunter _(@)_ ohrner.net"
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
##

from bilderspur import BilderspurException

import Image
import ImageDraw
import os
from xml.sax import saxutils


debug = True


BILDERSPUR_PLUGIN_API_VERSION = 1



def init(BILDERSPUR_APP, plugin_args):
	global debug

	return BilderspurDefaultPlugin(BILDERSPUR_APP, plugin_args)


class BilderspurDefaultPlugin( object ):

	def __init__(self, BILDERSPUR_APP, plugin_args):
		self.actions = { BILDERSPUR_APP.ACTION_THUMBNAIL_GENERATION:
										 self.generateThumbnailLink,
										 BILDERSPUR_APP.ACTION_IMAGE_DETAIL_GENERATION:
										 self.generateDetailHtmlForImage }

		self.BILDERSPUR_APP = BILDERSPUR_APP
		
		self.icon_generation_path = plugin_args
		if self.icon_generation_path == None:
			import tempfile
			self.icon_generation_path = tempfile.mkdtemp()

		self.tn_id_gen = thumbnailIdGenerator()


	def getSupportedActions(self):
		return self.actions.keys()


	def getActionFunction(self, action_name):
		return self.actions[action_name]


	def generateDetailHtmlForImage(self, iir, width, height, url):
		"""Default HTML generator for the details document of the
		generated placemarks.
		This default method generates an <img />-tag with the image's
		path as its src-attribute and a paragraph containing the
		image comment, if one exists.
		If 'url' is not None, the src-attribute is generated by
		prepending the given URL to the image's file name.
		"""

		img_basename = os.path.basename(iir.filename)
		if url == None:
			src_url = iir.filename
		else:
			src_url = '%s%s' % (url, img_basename)

		html_width = html_height = ''
		if width != None:
			html_width = ' width="%s"' % width
		if height != None:
			html_height = ' height="%s"' % height

		img_body_str = '<a href="%s"><img%s%s src="%s" /></a>' \
									 % (saxutils.escape(src_url),
											html_width, html_height,
											saxutils.escape(src_url))

		if 'EXIF DateTimeOriginal' in iir.tags:
			datetimestr = iir.tags['EXIF DateTimeOriginal'].values
		else:
			datetimestr = ''

		if iir.comment != None:
			commentstr = iir.comment
		else:
			commentstr = ''

		result_str = '''<table width="100%%">
		<tr><td colspan="2" align="center"><strong>%s</strong></td></tr>
		<tr><td colspan="2" align="center">%s</td></tr>
		<tr><td>%s</td><td align="right">%s</td></tr>
		</table>''' % (commentstr, img_body_str, saxutils.escape(img_basename),
									 datetimestr)

		return self.BILDERSPUR_APP.GeneratorResult(result_str, [])



	def generateThumbnailLink(self, image_cluster, url):
		"""Default generator for the thumbnail image 'href' text.
		This default method generates an <href />-tag with the image's
		path as its text contents.
		If 'url' is not None, the src-attribute is generated by
		prepending the given URL to the image's file name.
		"""
		
		self.generateThumbnailForCluster(image_cluster)

		thumb_basename = os.path.basename(image_cluster.thumb_file_name)
		
		if url == None:
			src_url = image_cluster.thumb_file_name
		else:
			src_url = '%s%s' % (url, thumb_basename)

		filename_pair = self.BILDERSPUR_APP.PublicTempFileNamePair(
			image_cluster.thumb_file_name,
			thumb_basename
		)

		return self.BILDERSPUR_APP.GeneratorResult(src_url, [ filename_pair ])



	def generateThumbnailForCluster(self, cluster):
		'''generate an icon thumbnail image for the given cluster'''

		icon_path = self.icon_generation_path
		icon_width_px = self.BILDERSPUR_APP.options.thumbnail_width

		cluster.thumb_file_name = '%s/tn%s.png' \
															% (icon_path, self.tn_id_gen.next(),)

		self.generateThumbnailForImagelist(cluster.thumb_file_name,
																			 icon_width_px,
																			 cluster.images)



	def generateThumbnailForImagelist(self, icon_fname,
																		thumbnailsize, image_list):
		'draw a representative thumbnail image for the given image list'

		if len(image_list) == 0 or thumbnailsize < 10:
			return None

		imgnum = min(len(image_list)-1, 4) ## 0-based
		offset = int(thumbnailsize / 10.0)

		## GE expects a completely transparent icon frame of
		## a least one pixel width. So make all icons somewhat
		## smaller and leave a pixel space around them.

		tn = Image.new('RGBA',
									 ## "+2" to leave space for a one pixel completely transparent border
									 2 * [thumbnailsize + imgnum*offset + 2],
									 (0, 0, 0, 0))

		## "+1" to leave space for a one pixel completely transparent border
		origin = 2 * [ offset * imgnum + 1 ]
		max_dim = [ 0, 0 ]

		for i in xrange(imgnum, -1, -1):
			img = Image.open(image_list[i].filename)
			sfactor = float(thumbnailsize) / max(img.size)
			new_size = [ int(x * sfactor) for x in img.size ]
			img = img.resize(new_size, Image.BICUBIC)
			img_max_coord = addElementWise(new_size, (-1, -1))
			draw = ImageDraw.Draw(img)
			draw.rectangle([ 0, 0 ] + img_max_coord, outline = 0)

			img_max_coord_in_tn = addElementWise(origin, new_size)
			tn.paste(img, origin + img_max_coord_in_tn)
			max_dim = map(max, max_dim, img_max_coord_in_tn)
			origin = map(lambda x: x-offset, origin)

		## GE icons must have dimensions which are a power of 2!
		## Leave some space for a one-pixel transparent border.
		max_dim = addElementWise(max_dim, (1, 1))
		tn = tn.crop([ 0, 0 ] + max_dim)
		tn.save(icon_fname)



def addElementWise(iterable1, iterable2):
	return [ x + y for (x, y) in zip(iterable1, iterable2) ]



def thumbnailIdGenerator():
	'returns natural numbers in ascending order, starting by 0'
	tn_id = 0
	while True:
		yield tn_id
		tn_id += 1
