from DocumentTemplate.DT_Util import html_quote
from Globals import HTMLFile 
from OFS import PropertySheets
import string
def getPropertyInputHTML( self, propertyMapping):
	''' Retrieve the appropriate HTML input field for this datatype '''
	ID = propertyMapping["id"]
	if self.hasProperty (ID):
		value = self.getProperty (ID)
		# input converters is a global mapping...
		converter = inputConverters.get ( propertyMapping.get ("type", "string"), "string" )
		return converter (propertyMapping, value, self)
	elif propertyMapping.has_key ("default"):
		converter = inputConverters.get ( propertyMapping.get ("type", "string"), "string" )
		return converter (propertyMapping, propertyMapping["default"], self)
	else:
		return ""
def getPropertyTypes( self ):
	'''Retrieve the names of all known property types'''
	keys = inputConverters.keys()
	keys.sort()
	return keys
PropertySheets.PropertySheet.getPropertyInputHTML = getPropertyInputHTML
PropertySheets.PropertySheet.getPropertyTypes = getPropertyTypes
PropertySheets.PropertySheet.manage = HTMLFile( "properties", globals())

def RepresentationInput ( mapping, value, sheet):
	''' Create HTML input field for integer/float value '''
	template = '''<input type="text" name="%(id)s:%(type)s" size="35" value="%(value)s">'''
	value = html_quote(repr( value))
	id = mapping.get ("id")
	type = mapping.get ("type")
	return template%locals ()
def LongInput(mapping, value, sheet):
	''' Create HTML input field for integer/float value '''
	template = '''<input type="text" name="%(id)s:%(type)s" size="35" value="%(value)s">'''
	value = repr( value )
	if value and value[-1] in ('l',"L"):
		value = value[:-1]
	value = html_quote( value )
	id = mapping.get ("id")
	type = mapping.get ("type")
	return template%locals ()
def StringInput (mapping, value, sheet):
	''' Create HTML input field for string value'''
	template = '''<input type="text" name="%(id)s:%(type)s" size="35" value="%(value)s">'''
	value = html_quote(str( value))
	id = mapping.get ("id")
	type = mapping.get ("type")
	return template%locals ()
StandardDateInput = StringInput

def BooleanInput (mapping, value, sheet):
	''' Create HTML boolean input field '''
	template = '''<input type="checkbox" name="%(id)s:%(type)s" size="35" %(checked)s>'''
	id = mapping.get ("id")
	type = mapping.get ("type")
	if value:
		checked = "CHECKED"
	else:
		checked = ""
	return template% locals ()

def TokenInput (mapping, value, sheet):
	''' Create HTML token input field '''
	template = '''<input type="text" name="%(id)s:%(type)s" size="35" value="%(values)s">'''
	id = mapping.get ("id")
	type = mapping.get ("type")
	values = string.join ( map (html_quote, map( str, value)), " " )
	return template% locals ()

def TextInput (mapping, value, sheet):
	'''Create an HTML text input field (i.e. multiple lines of text) '''
	template = '''<textarea name="%(id)s:%(type)s" rows="6" cols="35">%(value)s</textarea>'''
	id = mapping.get ("id")
	type = mapping.get ("type")
	value = html_quote(value)
	return template% locals ()

def LinesInput(mapping, value, sheet):
	''' Creating HTML lines input field (i.e. lines of separated text strings) '''
	template = '''<textarea name="%(id)s:%(type)s" rows="6" cols="35">%(value)s</textarea>'''
	id = mapping.get ("id")
	type = mapping.get ("type")
	value = string.join ( map (html_quote, map( str, value)), "\n" )
	return template% locals ()

def resolveAttribute(object, attribute):
	variable = string.split (attribute, ".")
	while variable:
		try:
			object = object.getProperty( variable[0])
		except (AttributeError, KeyError):
			try:
				object = getattr (object, variable [0])
			except (AttributeError, KeyError):
				try:
					object = object [variable [0]]
				except (AttributeError, KeyError, TypeError), value:
					raise AttributeError("Object %s does not have attribute %s, (failed to resolve %s)"% (object, attribute, value))
		del variable[0]
	return object
def SelectionInput( mapping, value, sheet):
	''' Create an HTML input for a selection property '''
	if mapping.has_key("select_variable"):
		id = mapping ["id"]
		type = mapping ["type"]
		bigTemplate = '''<select name="%(id)s:%(type)s">%(options)s</select>'''
		selectionList = resolveAttribute( sheet, mapping ["select_variable"])
		if callable(selectionList):
			selectionList = selectionList()
		optionTemplate = '''<option %(selected)s>%(item)s</option>'''
		optionList = []
		for item in selectionList:
			if item == value:
				selected = "SELECTED"
			else:
				selected = ""
			item = html_quote(str(item))
			optionList.append (optionTemplate% locals ())
		options = string.join ( optionList,'\n')
		return bigTemplate%locals()
	else:
		return '''No source attribute specified for selection property'''
def MultipleSelectionInput (mapping, value, sheet):
	''' Create an HTML input for a multiple selection property '''
	if mapping.has_key("select_variable"):
		id = mapping ["id"]
		type = "list" # note: this is not the type specified, this is not likely a good idea
		bigTemplate = '''<select name="%(id)s:%(type)s" size="%(size)s" MULTIPLE>%(options)s</select>'''
		selectionList = resolveAttribute( sheet, mapping ["select_variable"])
		if callable(selectionList):
			selectionList = selectionList()
		optionTemplate = '''<option %(selected)s>%(item)s</option>'''
		optionList = []
		for item in selectionList:
			if item in value:
				selected = "SELECTED"
			else:
				selected = ""
			item = html_quote(str(item))
			optionList.append (optionTemplate% locals ())
		size = min( 7, len(optionList))
		options = string.join ( optionList,'\n')
		return bigTemplate%locals()
	else:
		return '''No source attribute specified for multiple selection property'''


inputConverters = {
	"string": StringInput,
	"long": LongInput,
	"int": RepresentationInput,
	"float": RepresentationInput,
	"date": StandardDateInput,
	"datetime": StandardDateInput,
	"boolean": BooleanInput,
	"tokens": TokenInput,
	"text": TextInput,
	"lines": LinesInput,
	"selection": SelectionInput,
	"multiple selection": MultipleSelectionInput,
}
