#custom text fields prototype
"""Custom fields which clean up content when saved.

"""


from django.db import models
from django.forms import widgets, fields
from django.conf import settings
from rldjango.common.utils import assertedMedia


class HtmlInput(widgets.Textarea):
    # @property
    # def media(self):
    class Media:
        css = {
            "all": (
                "common/rsrc/js/wymeditor/skins/rptlab/skin.css", 
                "common/rsrc/css/html_field.css", 
                "imadj/rsrc/css/imagepicker.css",
                "imadj/rsrc/css/thickbox.css",
                )
            }

        js = [
            "common/rsrc/js/jquery-1.2.6.min.js",
            "common/rsrc/js/html_field/common.js",
            "imadj/rsrc/js/imagepicker.js",
            "imadj/rsrc/js/thickbox.js",
            ]
        try:
            edef=dict(
                wymeditor=[
                    "common/rsrc/js/wymeditor/jquery.wymeditor.pack.js",
                    "common/rsrc/js/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js",
                    "common/rsrc/js/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js",
                    "common/rsrc/js/html_field/wymeditor_field.js",
                    ],
                tinymce=[
                    "common/rsrc/js/tiny_mce3/tiny_mce.js",
                    "common/rsrc/js/html_field/tinymce_field.js",
                    ],
                )
            js.extend(edef.get(getattr(settings,'HTML_FIELD_EDITOR','tinymce'),edef['tinymce']))
        except KeyError:
            pass
        # return assertedMedia(css, js)

config_args = set(('breaksAllowed', 'convertEntities', 'stripComments', 'allowImages', 'allowTables'))

def clean_html(html, target, **kwargs):
    from rlextra.radxml import html_cleaner
    if target == 'block':
        return html_cleaner.cleanBlocks(html)
    elif target == 'inline':
        return html_cleaner.cleanInline(html)
    elif target == 'plain':
        return html_cleaner.cleanPlain(html)

class HtmlField(models.TextField):
    """
    For text to use in a paragraph, do
    
    intro = HtmlField(target='inline', max_length=100  etc)
    """
    def __init__(self, *args, **kwargs):
        target = kwargs.pop('target')   #don't pass this through to the underlying class
        assert target in ['inline','block', 'plain'], "unexpected HtmlField target %s" % target
        self.target = target
        
        for arg in config_args.intersection(kwargs):
            setattr(self, arg, kwargs.pop(arg))

        super(HtmlField, self).__init__(*args, **kwargs)
        
    def get_db_prep_value(self, value, connection=None, prepared=None):
        """Get content ready for database.
        
        This should normalize any input before storage.
        If it raises exceptions, they won't look pretty, but
        it will at least stop bad stuff getting in out database.
        
        Add options to the __init__ and use them here.
        """
        
        return clean_html(value, self.target)

    def formfield(self, **kwargs): 
        """Return the form field to use.  This is used to
        pass through anything defined in the model-field to
        the equivalent form-field, since the latter should not
        be coupled to models in any way.
        """
        kwargs['form_class'] = HtmlFormField
        kwargs['target'] = self.target
        
        for arg in config_args.intersection(self.__dict__):
            try:
                kwargs[arg] = getattr(self, arg)
            except AttributeError:
                pass

        if self.target == 'plain':
            kwargs['widget'] = widgets.TextInput()
        else:
            kwargs['widget'] = HtmlInput()
        return super(HtmlField, self).formfield(**kwargs)


class HtmlFormField(fields.CharField):
    "This handles checking and html generation"

    def __init__(self, *args, **kwargs):
        target = kwargs.pop('target')   #don't pass this through to the underlying class
        assert target in ['inline', 'block', 'plain'], "unexpected HtmlField target %s" % target
        self.target = target
        
        self.config = {}
        for arg in config_args.intersection(kwargs):
            self.config[arg] = kwargs.pop(arg)

        super(HtmlFormField, self).__init__(*args, **kwargs)

    def widget_attrs(self, widget):
        #this provides the attributes to be used in the textarea tag            
        self.configString = " ".join(( "%s:%s" % kv for kv in self.config.iteritems() ))
        if self.target != 'plain':
            classes = ['html_editor']
            classText = ' '.join(classes)
            return {'class': classText, 'rl:config': 'target:%s %s' % (self.target, self.configString)}
        else:
            return {'rl:config': 'target:%s%s' % (self.target, self.config)}
        
    def clean(self, value):
        "Validation hook - may not be needed"
        super(HtmlFormField, self).clean(value)
        return clean_html(value, self.target, **self.config)


try:
    from south.modelsinspector import add_introspection_rules
    add_introspection_rules([([HtmlField],[],{"target": ["target", {}],},),], ["^rldjango\.common\.htmlfield\.HtmlField"])
except ImportError:
    pass
