/
################################################################################
#
# 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'
    if hasattr(sock, 'cols'): w = sock.cols
    else: w = 80
    value = format_string(value, False, w)
  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