from django import template

register = template.Library()

class Info(object):
    pass

def fixup(text):
    t = str(text)
    if len(t) > 30:
        return str(t)[:27]+"..."
    else:
        return t
    
def fixuplist(l):
    nl = []
    for i in range(0,len(l)):
        nl.append(fixup(l[i]))
    return nl

def inspect_model_instance(instance):
    mm = instance.__class__._meta
    model = instance.__class__.__name__
    fields = []
    for f in mm.fields + mm.many_to_many:
        field = Info()
        field.name = f.name
        field.type = f.__class__.__name__
        field.value = fixup(getattr(instance,f.name))
        fields.append(field)
    return {'model': model, 'fields': fields }

def inspect_form_instance(instance):
    fields = []
    bound = str(instance.is_bound)
    for f in instance.fields.keys():
        field = Info()
        field.name = f
        field.type = instance.fields[f].__class__.__name__
        field.widget = instance.fields[f].widget.__class__.__name__
        field.initial = fixup(instance.initial.get(f,''))
        field.bound = fixup(instance.data.get(f,''))
        field.errors = fixuplist(instance[f].errors)
        fields.append(field)
    return {'bound': bound, 'fields': fields }

def inspect_dict(instance):
    keys = []
    for k in instance.keys():
        key = Info()
        key.name = k
        key.type = instance[k].__class__.__name__
        key.value = fixup(instance[k])
        keys.append(key)
    return {'keys': keys }

def inspect_object(obj,name=""):
    dtype = 'basic'
    classname = obj.__class__.__name__
    meta = fixup(obj) 
    if getattr(obj,'__metaclass__',None):
        if obj.__metaclass__.__name__ == 'DeclarativeFieldsMetaclass': 
            dtype = 'form'
            meta = inspect_form_instance(obj)
        elif obj.__metaclass__.__name__ == 'ModelBase': 
            dtype = 'model'
            meta = inspect_model_instance(obj)
    elif classname == 'dict':
        dtype = 'dict'
        meta = inspect_dict(obj)
    elif classname == 'list':
        dtype = 'list'
        meta = fixuplist(obj)
        
    return {'classname': classname,'name': name, 'dtype': dtype, 'meta': meta}

register.inclusion_tag('inspect_object.html')(inspect_object)

"""  Template goes in file: inspect_object.html

<table style="border: 1px solid;background-color: green">
 <tr style="background-color:#e2b753"><th>{{name}}({{classname}})</th></tr>
{% ifequal dtype "basic" %}
 <tr style="background-color:#F9FBCE"><td style="padding:4px;">{{meta}}</td></tr>
{% endifequal %}
{% ifequal dtype "model" %}
 <tr>
  <td>
   <table style="background-color: green" cellpadding="4px">
    <tr><th>Field</th><th>Type</th><th>Value</th></tr>
    {% for f in meta.fields %}
    <tr style="background-color:{% cycle #F9FBCE,#E1E2D5 %}">
        <td>{{ f.name }}</td>
        <td>{{ f.type }}</td>
        <td>{{ f.value }}</td>
    </tr>
    {% endfor %}
   </table>
  </td>
 </tr>
{% endifequal %}
{% ifequal dtype "form" %}
 <tr>
  <td>
   <table style="background-color: green;" cellpadding="4px">
    <tr>
        <th>Field</th>
        <th>Type</th>
        <th>Widget</th>
        <th>Initial</th>
        <th>Bound</th>
        <th>Errors</th>
    </tr>
    {% for f in meta.fields %}
    <tr style="background-color:{% cycle #F9FBCE,#E1E2D5 %}">
        <td>{{ f.name }}</td>
        <td>{{ f.type }}</td>
        <td>{{ f.widget }}</td>
        <td>{{ f.initial }}</td>
        <td>{{ f.bound }}</td>
	<td>
 	{% for e in f.errors %}
	{{ e }}
	{% endfor %}
	</td>
    </tr>
    {% endfor %}
   </table>
  </td>
 </tr>
{% endifequal %}
{% ifequal dtype "dict" %}
 <tr>
  <td>
   <table style="background-color: green" cellpadding="4px">
    <tr><th>Key</th><th>Type</th><th>Value</th></tr>
    {% for k in meta.keys %}
    <tr style="background-color:{% cycle #F9FBCE,#E1E2D5 %}">
        <td>{{ k.name }}</td>
        <td>{{ k.type }}</td>
        <td>{{ k.value }}</td>
    </tr>
    {% endfor %}
   </table>
  </td>
 </tr>
{% endifequal %}
{% ifequal dtype "list" %}
 <tr>
  <td>
   <table style="background-color: green" cellpadding="4px">
    {% for i in meta %}
    <tr style="background-color:{% cycle #F9FBCE,#E1E2D5 %}">
        <td>{{ i }}</td>
    </tr>
    {% endfor %}
   </table>
  </td>
 </tr>
{% endifequal %}
</table>

"""