#!/usr/bin/env python
# -*- coding: utf-8 -*-
# TODO: nested layers für linked: All_List, Compare_List, Linked_List, Counter der Linked_Layers, Switch für for-Schleife Linked_layers

from gimpfu import *
import os, string, sys
import os.path

gettext.install("gimp20-python", gimp.locale_directory, unicode=True)

def python_cssdev(active_image, active_layer, 
	export_dir, export_hidden, export_layer, export_height, export_crop, export_divs, 
	li_color, ho_color, div_color, default_font, default_size, center_content, 
	generate_text):

	active_image.undo_group_start()
#---[ VARS ]---#		

	# Fontface Alternativ Lists
	arial = [ "Arial","Helvetica","FreeSans","Nimbus Sans L","Liberation Sans","sans-serif" ]
	courier = [ "Courier New","Courier","FreeMono","Nimbus Mono L","Liberation Mono","monospace" ]
	georgia = [ "Georgia","Bitstream Charter","Century Schoolbook L","Liberation Serif","Times","serif" ]
	lucida = [ "Lucida Sans","Lucida Sans Unicode","Lucida Grande","Lucida","sans-serif" ]
	console = [ "Lucida Console","Monaco","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","monospace" ]
	palatino = [ "Palatino","Palatino Linotype","Palladio","URW Palladio L","Book Antiqua","Liberation Serif","Times","serif" ]
	tahoma = [ "Tahoma","Geneva","DejaVu Sans Condensed","sans-serif" ]
	times = [ "Times New Roman","Times","Nimbus Roman No9 L","FreeSerif","Liberation Serif","serif" ]
	verdana  = [ "Verdana","Bitstream Vera Sans","DejaVu Sans","Liberation Sans","Geneva","sans-serif" ]
	
	# Fontface Alternativ Strings
	font_arial = "Arial,Helvetica,FreeSans,\"Nimbus Sans L\",\"Liberation Sans\",sans-serif"
	font_courier = "\"Courier New\",Courier,FreeMono,\"Nimbus Mono L\",\"Liberation Mono\",monospace"
	font_georgia = "Georgia,\"Bitstream Charter\",\"Century Schoolbook L\",\"Liberation Serif\",Times,serif"
	font_lucida = "\"Lucida Sans\",\"Lucida Sans Unicode\",\"Lucida Grande\",Lucida,sans-serif"	
	font_console = "\"Lucida Console\",Monaco,\"DejaVu Sans Mono\",\"Bitstream Vera Sans Mono\",\"Liberation Mono\",monospace"
	font_palatino = "Palatino,\"Palatino Linotype\",Palladio,\"URW Palladio L\",\"Book Antiqua\",\"Liberation Serif\",Times,serif"	
	font_tahoma = "Tahoma,Geneva,\"DejaVu Sans Condensed\",sans-serif"
	font_times = "\"Times New Roman\",Times,\"Nimbus Roman No9 L\",\"FreeSerif\",\"Liberation Serif\",serif"
	font_verdana = "Verdana,\"Bitstream Vera Sans\",\"DejaVu Sans\",\"Liberation Sans\",Geneva,sans-serif"

	# Variables
	ind_list = [""]
	ind_cnt = 0
	do_wrapper = 0
	do_position = "position:absolute; "
	do_layerbg = 1
	do_height = ""
	do_bold = ""
	do_italic = ""
	do_language = ""
	do_content = ""
	do_crop = 1
	num_Layers = pdb.gimp_image_get_layers(active_image)[0]
	xpos = 30
	ypos = 30
	valid_layer = []
	layer_text = []
	fg_color = gimp.get_foreground() 
	bg_color = gimp.get_background()
	image_width = active_image.width
	image_height = active_image.height

#---[ TOOLS ]---#

	# Function getting Language Information
	def content_language(do_language, do_content):
		for this_layer in range(len(active_image.layers)):
			try:
				if pdb.gimp_drawable_is_text_layer(active_image.layers[this_layer]):
					this_language = pdb.gimp_text_layer_get_language(active_image.layers[this_layer])
					do_content = "<meta http-equiv=\"content-language\" content=\"%s\" />" % this_language
					do_language = "<meta name=\"language\" content=\"%s\" />" % this_language
					break
			except:
				do_language = ""
				do_content = ""
		return do_language, do_content

	# Function getting Font
	def font_basics(gimp_font, do_bold, do_italic):
		#Font Style auslesen
		new_font = ""
		all_attr = gimp_font.split(" ")
		num_attr = len(all_attr)
		if num_attr > 1:
			for this_attr in range(num_attr):
				if all_attr[this_attr] == "Bold Italic" or all_attr[this_attr] == "Fett Kursiv" or all_attr[this_attr] == "Bold Oblique":
					do_bold = "font-weight:bold; "
					do_italic = "font-style:italic; "
				elif all_attr[this_attr] == "Bold" or all_attr[this_attr] == "Fett":
					do_bold = "font-weight:bold; "
				elif all_attr[this_attr] == "Italic" or all_attr[this_attr] == "Oblique" or all_attr[this_attr] == "Kursiv":
					do_italic = "font-style:italic; "
				else:
					new_font = new_font + all_attr[this_attr] + " "
			#Kill Space at the End 
			gimp_font = new_font[:len(new_font)-1]
	
		# Determine Font-Face
		if gimp_font in times:
			this_font = font_times
		elif gimp_font in arial:
			this_font = font_arial
		elif gimp_font in courier:
			this_font = font_courier
		elif gimp_font in georgia:
			this_font = font_georgia
		elif gimp_font in lucida:
			this_font = font_lucida
		elif gimp_font in console:
			this_font = font_console
		elif gimp_font in palatino:
			this_font = font_palatino	
		elif gimp_font in tahoma:
			this_font = font_tahoma
		elif gimp_font in verdana:
			this_font = font_verdana
		else:
			this_font = "\"" + gimp_font + "\"," + font_arial
		return this_font, do_bold, do_italic
		
#---[ MAIN ]---#	

	# Trying getting content language	
	do_language, do_content = content_language(do_language, do_content)

	# Determine the OS
	if os.sep == "\\":
		export_file = "\\gimp_cssdev.html"
	else:
		export_file = "/gimp_cssdev.html"
	
	# Gimp version
	gimp_version = pdb.gimp_version().split(".")
	this_version = "%s%s%s" % (gimp_version[0], gimp_version[1], gimp_version[2])
	this_version = int(this_version)
	
	# Path and File
	this_filepath = export_dir + export_file
	
	# Creating the Indention List 
	for i in xrange(20):
		ind_list.append("%s\t" % ind_list[-1])
	
	# Getting Data for the default Font
	this_font, do_bold, do_italic = font_basics(default_font, do_bold, do_italic)

	# Center WrapperCSS
	if center_content and export_layer == "2":
		do_wrapper = 1
		do_position = ""
		
	# Image Properties
	this_title = pdb.gimp_image_get_name(active_image)
	this_wrapper = pdb.gimp_image_width(active_image)

	# Start writing the Image
	file = open(this_filepath, 'w')
	
	# Head
	file.write("%s<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" % ind_list[ind_cnt])
	file.write("%s<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\n" % ind_list[ind_cnt])
	file.write("%s<head>\n" % ind_list[ind_cnt])
	ind_cnt += 1
	file.write("%s<title>%s</title>\n" % (ind_list[ind_cnt],this_title))
	file.write("%s<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" % ind_list[ind_cnt])
	file.write("%s<meta http-equiv=\"imagetoolbar\" content=\"no\" />\n" % ind_list[ind_cnt])
	if do_language:
		file.write("%s%s\n" % (ind_list[ind_cnt], do_content))	
		file.write("%s%s\n" % (ind_list[ind_cnt], do_language))	
	file.write("%s<meta name=\"robots\" content=\"INDEX,follow\" />\n" % ind_list[ind_cnt])
	file.write("%s<meta name=\"Keywords\" content=\"\" />\n" % ind_list[ind_cnt])
	file.write("%s<meta name=\"Description\" content=\"\" />\n" % ind_list[ind_cnt])
	file.write("%s<meta name=\"revisit-after\" content=\"14 Days\" />\n" % ind_list[ind_cnt])
	file.write("%s<meta name=\"generator\" content=\"CSSdev for GIMP, http://www.area42.de, http://my.opera.com/area42/blog/\" />\n" % ind_list[ind_cnt])
	
	# Styleblock
	file.write("%s<style type=\"text/css\" media=\"screen\">\n" % ind_list[ind_cnt])
	ind_cnt += 1
	
	# BodyCSS
	file.write("%shtml, body { background:rgb(%s,%s,%s); color:rgb(%s,%s,%s);\n" % (ind_list[ind_cnt], bg_color[0],bg_color[1],bg_color[2], fg_color[0], fg_color[1], fg_color[2]))
	ind_cnt += 1
	file.write("%sfont-family:%s; font-size:%ipx; %s%s}\n" % (ind_list[ind_cnt], this_font, default_size, do_bold, do_italic))
	ind_cnt -= 1
	file.write("%sa { color:rgb(%s,%s,%s) }\n" % (ind_list[ind_cnt], li_color[0],li_color[1],li_color[2]))
	file.write("%sa:hover { color:rgb(%s,%s,%s) }\n" % (ind_list[ind_cnt], ho_color[0],ho_color[1],ho_color[2]))
	file.write("%simg { border:none; }\n" % ind_list[ind_cnt])
	file.write("%sp { color:rgb(%s,%s,%s); font-family:%s; font-size:12px; %s%s}\n" % (ind_list[ind_cnt], fg_color[0], fg_color[1], fg_color[2], this_font, do_bold, do_italic))
	
	# WrapperCSS
	if do_wrapper:
		file.write("%s#wrapperCSSDEV { width:%spx; margin:0 auto; }\n" % (ind_list[ind_cnt], this_wrapper))
	
	# LayerCSS
	for this_layer in range(len(active_image.layers)):
		do_bold = ""
		do_italic = ""
		do_layerbg = 1
		do_indent = "\n\t\t\t"
		layer_width = active_image.layers[this_layer].width
		layer_height = active_image.layers[this_layer].height
		layer_pos = active_image.layers[this_layer].offsets
		layer_name = active_image.layers[this_layer].name
		layer_opacity = active_image.layers[this_layer].opacity
		layer_mask = active_image.layers[this_layer].mask
				
		# Determine the Height of a Layer
		if export_height:
			do_height = "height:%spx; " % layer_height
		
		if export_crop:
			if this_version > 249:
				if pdb.gimp_drawable_is_text_layer(active_image.layers[this_layer]):
					do_crop = 0
				else:
					do_crop = 1
			else:
				do_crop = 1
			if do_crop:
				pdb.gimp_selection_layer_alpha(active_image.layers[this_layer])
				this_bounds = pdb.gimp_selection_bounds(active_image)
				active_image.layers[this_layer].translate(0-this_bounds[1], 0-this_bounds[2])
				pdb.gimp_layer_resize_to_image_size(active_image.layers[this_layer])
				crop_width = this_bounds[3]-this_bounds[1]
				crop_height = this_bounds[4]-this_bounds[2]
				active_image.layers[this_layer].resize(crop_width, crop_height, 0, 0) 
				active_image.layers[this_layer].translate(this_bounds[1], this_bounds[2])
	
		# Try to compute the Background Color 
		layer_bg = active_image.layers[this_layer].get_pixel(xpos,ypos)
		if this_version > 249:
			if pdb.gimp_drawable_is_text_layer(active_image.layers[this_layer]):
				do_layerbg = 0
		else:
			do_layerbg = 1
			
		# Create a valid Layer Name
		layer_text.append(layer_name)
		if layer_name[0].isdigit():
			layer_name = "%s%s" % ("_",layer_name)
		for bad_char in [' ','/','\t','"','#',"'",',','.',':',';','[','\\',']','{','}','ä','Ä','ö','Ö','ü','Ü','ß','Ž','`','~']:
			layer_name = layer_name.replace(bad_char,'')
			layer_name = string.lower(layer_name)
		if len(layer_name) > 12:
			layer_name = layer_name[:12]
			
		# Creating a Layer List with valid Names for the HTML output
		valid_layer.append(layer_name)
		num_Layers -= 1
		
		# Skip unvisible Layers if unwanted 
		if export_hidden == "0" and not active_image.layers[this_layer].visible:
			continue
		file.write("%s#%s { left:%spx; top:%spx; width:%spx; %sz-index:%s; %s" % (ind_list[ind_cnt], layer_name, layer_pos[0], layer_pos[1], layer_width, do_height, num_Layers, do_position))
		if export_hidden == "4" and export_layer == "0" and not active_image.layers[this_layer].visible:
			file.write("visibility:hidden; ")
			
		# Export Hidden Layers
		elif export_hidden == "4" and export_layer == "2" and not active_image.layers[this_layer].visible:
			file.write("display:none; ")
			
		# Writing the Background Color
		if div_color and do_layerbg == 1:
			file.write("background:rgb(%s,%s,%s); " % (layer_bg[0], layer_bg[1], layer_bg[2]))

		# Is it a Textlayer determine Fontface
		if this_version > 249:
			if pdb.gimp_drawable_is_text_layer(active_image.layers[this_layer]):
				layer_font 		= pdb.gimp_text_layer_get_font(active_image.layers[this_layer])
				layer_size 		= int(pdb.gimp_text_layer_get_font_size(active_image.layers[this_layer])[0])
				layer_line 		= int(pdb.gimp_text_layer_get_line_spacing(active_image.layers[this_layer])) #<p style="line-height:1.4em; 
				layer_letter	= int(pdb.gimp_text_layer_get_letter_spacing(active_image.layers[this_layer])) #<span style="letter-spacing:0.1em">
				layer_color 	= pdb.gimp_text_layer_get_color(active_image.layers[this_layer])
				layer_justify	= pdb.gimp_text_layer_get_justification(active_image.layers[this_layer]) #<p style="text-align:left; center,right, justify
				layer_indent	= int(pdb.gimp_text_layer_get_indent(active_image.layers[this_layer])) #<p style="text-indent:1
				
				do_fontsize = "" 
				do_fontface = "" 
				do_letterspace = ""
				do_textindent = ""
				do_justify = ""
				do_lineheight = ""
				do_color = "color:rgb(%s,%s,%s); " % (layer_color[0],layer_color[1],layer_color[2])

				layer_font, do_bold, do_italic = font_basics(layer_font, do_bold, do_italic)

				if layer_size != default_size:
					do_fontsize = "font-size:%ipx; " % layer_size
				if layer_font != this_font:
					do_fontface = "font-family:%s; " % layer_font
				if layer_letter != 0:
					do_letterspace = "letter-spacing:%ipx; " % layer_letter
				if layer_indent > 0:
					do_textindent = "text-indent:%ipx; " % layer_indent
				if layer_justify != 0:
					if layer_justify == 1:
						this_justify = "right"
					elif layer_justify == 2:
						this_justify = "center"
					elif layer_justify == 3:
						this_justify = "justify"					
					do_justify = "text-align:%s; " % this_justify
				if layer_line != 0:
					this_lineheight = int(layer_size * 1.2) + layer_line
					do_lineheight = "line-height:%ipx; " % this_lineheight

				ind_cnt += 1
				file.write("\n%s%s%s%s%s" % (ind_list[ind_cnt], do_fontface, do_fontsize, do_bold, do_italic))
				file.write("\n%s%s%s%s%s%s" % (ind_list[ind_cnt], do_color, do_justify, do_lineheight, do_letterspace, do_textindent))
				ind_cnt -= 1						
		
		# Writing Opacity if not 100
		if (layer_opacity != 100.0) and (layer_opacity > 0):
			layer_ieopacity = str(round(float(layer_opacity),3))
			layer_opacity = str(round(layer_opacity/100,3))
			ind_cnt += 1
			file.write("\n%sfilter:alpha(opacity=%s); -moz-opacity:%s; opacity:%s; khtml-opacity:%s; " % (ind_list[ind_cnt], layer_ieopacity, layer_opacity, layer_opacity, layer_opacity))
			ind_cnt -= 1
			do_indent = ""
			
		# Getting the Layer Mask for CSS property clip
		if layer_mask and layer_mask.visible == 1:
			pdb.gimp_selection_none(active_image)
			white = pdb.gimp_by_color_select(layer_mask,gimpcolor.RGB(255, 255, 255), 0, 0, False, False, 0, False)
			this_mask = layer_mask.mask_bounds
			if this_mask[0] == 0 and this_mask[1] == 0 and this_mask[2] == image_width and this_mask[2] == image_height:
				black = pdb.gimp_by_color_select(active_image.layers[this_layer],gimpcolor.RGB(0, 0, 0), 0, 0, False, False, 0, False)
				this_mask = layer_mask.mask_bounds
			correct_width = (image_width - layer_width)/2
			correct_height = (image_height - layer_height)/2
			clip_startx = this_mask[0]-correct_width
			clip_starty = this_mask[1]-correct_height
			clip_endx = this_mask[2]-correct_width
			clip_endy = this_mask[3]-correct_height
			file.write("%sclip:rect(%spx, %spx, %spx, %spx); " % (do_indent, clip_starty, clip_endx, clip_endy, clip_startx))
				
		file.write("}\n")
	ind_cnt -= 1
	file.write("%s</style>\n" % ind_list[ind_cnt])
	ind_cnt -= 1
	file.write("%s</head>\n\n" % ind_list[ind_cnt])	
	
	#Start XHTML Output
	file.write("%s<body>\n" % ind_list[ind_cnt])	
	ind_cnt += 1
	
	# WrapperDIV open
	if do_wrapper:	
		file.write("%s<div id=\"wrapperCSSDEV\">\n" % ind_list[ind_cnt])
		ind_cnt += 1

	# LayerDIV
	for this_layer in range(len(valid_layer)):
		if this_version > 249:
			if pdb.gimp_drawable_is_text_layer(active_image.layers[this_layer]):
				do_text = pdb.gimp_text_layer_get_text(active_image.layers[this_layer])
				do_text = do_text.replace("\n","<br/>")
				if pdb.gimp_text_layer_get_base_direction(active_image.layers[this_layer]):
					do_dir = " dir=\"rtl\""
				else:
					do_dir = ""
			else:
				do_text = layer_text[this_layer]
				do_dir = ""
		else:
			do_text = layer_text[this_layer]
			do_dir = ""
		file.write("%s<div id=\"%s\"%s>\n" % (ind_list[ind_cnt], valid_layer[this_layer], do_dir))
		ind_cnt += 1
		file.write("%s%s\n" % (ind_list[ind_cnt], do_text))
		ind_cnt -= 1
		file.write("%s</div>\n" % ind_list[ind_cnt])
				
	# WrapperDIV close
	if do_wrapper:	
		ind_cnt -= 1
		file.write("%s</div>\n" % ind_list[ind_cnt])	
		
	ind_cnt -= 1
	file.write("%s</body>\n\n" % ind_list[ind_cnt])
	file.write("%s</html>\n" % ind_list[ind_cnt])
	file.close()
	
	active_image.undo_group_end()

register(
	"python-fu-cssdev",
	"CSSdev 0.5\nCreating XHTML and CSS source from an layered image. \nPresented by area42 - Agentur & Systempartner: \nwww.area42.de",
	"CSSdev 0.5\nCreating XHTML and CSS source from an layered image. \nPresented by area42 - Agentur & Systempartner: \nwww.area42.de",
	"Eckhard M. Jaeger",
	"Eckhard M. Jaeger",
	"2008",
	"<Image>/CSSdev...",
#	"<Image>/Filters/Web/CSSdev...",
	"",
	[
		(PF_DIRNAME,	"export_dir", 		_("Export to"), ""),
		(PF_RADIO, 		"export_hidden", 	_("Export hidden Layers"), "0", (("No","0"), ("As visible","2"), ("As hidden in XHTML/ CSS","4"))),
		(PF_RADIO, 		"export_layer", 	_("Export Layers as"), "0", (("Absolute aligned wit z-Index","0"), ("As nested with margins","2"))),
		(PF_TOGGLE,		"export_height", 	_("Export Layer Height"), False),
		(PF_TOGGLE, 	"export_crop", 	_("Crop Layers to Layer Content"), False),
		(PF_TOGGLE, 	"export_divs", 	_("Export Linked Layers as nested Div"), True),
		(PF_COLOR, 		"li_color", 		_("Link Color"), (0,0,192)),
		(PF_COLOR, 		"ho_color", 		_("Link Hover Color"), (0,0,255)),
		(PF_TOGGLE, 	"div_color", 		_("Caclculate Background Color of Layers"), True),
		(PF_FONT, 		"default_font", 	_("Default Webpage Font"), "Verdana"),
		(PF_SPINNER,	"default_size", 	_("Default Font Size (px)"), 12, (0,100,1)),
		(PF_TOGGLE, 	"center_content", _("Center Page in Browser (for nesting only)"), True),
		(PF_TOGGLE, 	"generate_text", _("Generate Text"), False),
	],
	[],
	python_cssdev,
	domain=("gimp20-python", gimp.locale_directory))

main()
