################################################################################
#
# Four Worlds
# Copyright (c) 2009-????
#
# Package: polc
#    File: renderers.py
#
# The automatic Python OLC system, capable of generating an online content editor
# for a given Python class or dict by using dictionaries to discover properties.
#
# Rendering of values for display in the OLC menu.
#
# Author: Stendec
#
################################################################################
from data import *
from types import *
from mud import format_string
try:
	from colour import highlight_color
except: highlight_color = lambda v: v.replace('{','{{')
################################################################################
# Basic Renderer Functions
################################################################################
def fancy_key(key):
	'''Attempt to make a key name fancy. If it's in an array of default names, return the
		 corresponding fancy name. Otherwise, convert underscores to spaces and make it
		 title case.'''
	if fancy_keys.has_key(key): return fancy_keys[key]
	else: return key.replace('_',' ').title()
def render_bool(sock, data, key, value):
	'''Render a boolean value for the automatic OLC system.'''
	return ': {c' + (value and 'yes' or 'no')
def render_number(sock, data, key, value):
	'''Render a number value for the automatic OLC system.'''
	if type(value) == float:
		 p = data.k(key, 'places')
		 if p: return ': {c' + str(int(value)) + ('%f' % round(value-int(value),p))[1:p+2]
	return ': {c' + str(value)
def render_list(sock, data, key, value):
	'''Render a list for the automatic OLC system. Strings are
		 output without being escaped and surrounded in quotation
		 marks.'''
	val = ''
	for i in value:
		val += '{D, {c'
		if type(i) == str: val += i
		else: val += str(i)
	return ': {c' + val[6:]
def render_string(sock, data, key, value):
	'''Render a string value for the automatic OLC system.'''
	n = data.k(key,'name')
	if n is None: n = fancy_key(key)
	
	if value.endswith('\r\n'): value = value[:-2]
	
	if data.k(key, 'same-line'): prefix = ' ' * (15-len(n)) + ': {c'
	else:
		prefix = ':\r\n{c'
		value = format_string(value, False, sock.cols)
	if value == '': return prefix[:-1] + 'D' + (data.k(key, 'empty') or '<NONE>')
	
	# Should we be post-processing the text?
	func = data.k(key, 'process')
	if data.k(key,'nocolor') or func is 'no-color': value = highlight_color(value)
	elif type(func) in (FunctionType,LambdaType,BuiltinFunctionType,BuiltinMethodType,type(str.upper)): value = func(value)
	
	return prefix + value
def render_subitem(sock, data, key, value):
	'''Render a subitem key for the automatic OLC system.'''
	return ' menu'
def render_choice_list(sock, data, key, value):
	'''Render a list of choices for the automatic OLC system.'''
	c = data.k(key, 'choices')
	val = ''
	if type(c) == dict:
		for i in value: val += '{D, {c' + str(c[i])
	else:
		for i in value: val += '{D, {c' + str(i)
	return ': {c' + val[6:]
def render_choice(sock, data, key, value):
	'''Render a choice for the automatic OLC system.'''
	w = data.k(key, 'width')
	if w is None: w = '0'
	else: w = str(w)
	c = data.k(key, 'choices')
	if type(c) == dict: return ('{y[{c%'+w+'s{y]') % str(c[value])
	else: return ('{y[{c%'+w+'s{y]') % str(value)
def render_choice_select(sock, data, key, value):
	'''Render a list of choices to select from for the prompt after selecting a key.'''
	buf = []
	longest = 0
	
	c = data.k(key, 'choices')
	if type(c) == dict:
		ks = sorted(c.keys())
		for i in range(0, len(ks)):
			b = '  {c%2d{y) {g%s' % (i, c[ks[i]])
			longest = max(longest, len(b) - 6)
			buf.append(b)
	else:
		c = sorted(c)
		for i in range(0, len(c)):
			b = '  {c%2d{y) {g%s' % (i, c[i])
			longest = max(longest, len(b) - 6)
			buf.append(b)
	
	# Get the screen width, if supported.
	if hasattr(sock, 'cols'): w = sock.cols
	else: w = 80
	num_cols = w / longest
	
	# Print the list out
	i = 0
	longest += 6
	val = ''
	for b in buf:
		val += b + ' ' * (longest - len(b))
		i += 1
		if i >= num_cols:
			val += '\r\n'
			i = 0
	if val.endswith('\r\n'): val = val[:-2]
	return val