# AjaxForm somehow replaces part of the django forms framework.
# It probably makes more sense to replace it with a django form generator using ajax-like fields

from django import forms

class AjaxForm(object):
    def __init__(self):
        self.renderers = {}
        
        # Registering some default renderers
        from rldjango.apps.imadj.fields import ImageField
        from django.db.models.fields import CharField, TextField
        from rldjango.common.htmlfield import HtmlField
        self.register(CharField, AjaxTextField)
        self.register(TextField, AjaxTextField)
        self.register(ImageField, AjaxImadjField)
        self.register(HtmlField, AjaxHTMLField)
    
    def register(self, field, renderer):
        self.renderers[field] = renderer

    def media(self):
        return reduce((lambda a,b: a+b),
                (r.media for r in self.renderers.values() if hasattr(r, 'media')),
                forms.Media())

    def renderField(self, field, obj):
        try:
            r = self.renderers[field.__class__]
        except KeyError, e:
            return ''#raise NotImplementedError("Field type %s cannot be transformed to an Ajax Form." % field.__class__)
        id = "%s:%s:%s" % (obj.__class__.__name__.lower(), obj.id, field.name)
        return r.render(field, obj, id)
        
    def renderObject(self, obj, exc_handler=(lambda *args: None)):
        html = []
        for f in obj.__class__._meta.fields:
            try:
                html.append(self.renderField(f, obj))
            except Exception, e:
                exc_handler(e, obj, f)
        return '\n'.join(html)
    
    def objectsIterator(self, objects, exc_handler=(lambda *args: None)):
        for obj in objects:
            yield obj, self.renderObject(obj, exc_handler)

class AjaxTextField(object):
    media = forms.Media(
            css={'all': (
                'imadj/rsrc/css/thickbox.css',)},
            js=(
                'common/rsrc/js/jquery-1.3.1.min.js',
                'imadj/rsrc/js/thickbox.js',
                'js/jquery.jeditable.mini.js',
                'common/rsrc/js/jeditable_textarea.js',
                'imadj/rsrc/js/imagepicker.js',))
                
    @staticmethod
    def render(f, obj, id):
        value = f._get_val_from_obj(obj)
        return '<h4>%s</h4><div class="text_holder"><p id="%s" class="editable_textarea">%s</p></div>' % (f.name, id, value)

class AjaxImadjField(object):
    media = forms.Media(
            css={'all': (
                'imadj/rsrc/css/thickbox.css',
                'imadj/rsrc/css/imagepicker.css',)},
            js=(
                'common/rsrc/js/jquery-1.3.1.min.js',
                'imadj/rsrc/js/thickbox.js',
                'imadj/rsrc/js/imagepicker.js',))
                
    @staticmethod
    def render(f, obj, id):
        thumb_url = getattr(obj, f.name).get_thumbnail_url()
        return '<h4>%s</h4><div class="image_holder2"><img id="%s" src="%s" class="imadjselect size:%s" alt=""/></div>' % (f.name, id, thumb_url, f.size)

class AjaxHTMLField(object):
    '''FIXME: This is not an ajax field right now. I cannot be saved.'''

    media = forms.Media(
            css={'all': (
                'imadj/rsrc/css/thickbox.css',
                'imadj/rsrc/css/imagepicker.css',)},
            js=(
                'common/rsrc/js/jquery-1.3.1.min.js',
                'common/rsrc/js/html_field/common.js',
                'common/rsrc/js/tiny_mce3/tiny_mce.js',
                'common/rsrc/js/html_field/tinymce_field.js'))
    
    @staticmethod
    def render(f, obj, id):
        value = f._get_val_from_obj(obj)
        return '<h4>%s</h4><div class="html_holder"><textarea rl:config="target:inline breaksAllowed:True allowImages:True" id="%s" class="html_editor">%s</textarea></div>' % (f.name, id, value)
         