from django.db import models
from django.dispatch import dispatcher
from django.db.models import signals
from django.utils.functional import curry

from django.conf import settings
import os

def default_thumbnalaizer(src, width=100, height=100):
    """
    Make a thumbnail from src file,
    return value should be raw_field compatatible
    """
    import Image

    try:
        from cStringIO import StringIO
    except ImportError:
        from StringIO import StringIO

    img_src = Image.open(src)
    img_src.thumbnail((width, height))

    ret = StringIO()
    img_src.save(fp=ret, format=img_src.format)
    return ret.getvalue()

class ThumbnailField(models.ImageField):
    def __init__(self, thumb_for, thumb_func=default_thumbnalaizer, **kwargs):
        kwargs['blank']=True
        super(ThumbnailField, self).__init__(**kwargs)
        self.thumb_for = thumb_for
        self.thumb_func = thumb_func
        self._cached_attr = '__cached_image_%s' % self.get_attname()

    def contribute_to_class(self, cls, name):
        super(ThumbnailField, self).contribute_to_class(cls, name)
        setattr(cls, 'force_%s_rethumb' % self.name, curry(self.force_rethumb))
        dispatcher.connect(self.post_init, signal=signals.post_init, sender=cls)
        
    def pre_save(self, instance, add):
        cached = getattr(instance, self._cached_attr)
        image = getattr(instance, self.thumb_for)
        thumb = getattr(instance, self.get_attname())

        if add or cached != image or (image and not thumb):
            self.force_rethumb(instance)
        return super(ThumbnailField, self).pre_save(instance, add)

    def post_init(self, instance):
        image = getattr(instance, self.thumb_for)
        setattr(instance, self._cached_attr, image)

    def force_rethumb(self, instance):
        image = getattr(instance, self.thumb_for)
        filename = self.get_filename(image)
        raw_field = self.thumb_func(os.path.join(settings.MEDIA_ROOT, image))
        instance._save_FIELD_file(self, filename, raw_field, save=False)
        setattr(instance, self._cached_attr, image)
##
## Just an example usage
##
# class Picture(models.Model):
#     image = models.ImageField(upload_to='images')
#     thumb = ThumbnailField(thumb_for='image', upload_to='images/thumbs')
#   
#     def thumbnail(self):
#         return '<img src="%s" />' % self.get_thumb_url()
#     thumbnail.allow_tags=True
#
# from django.contrib import admin
#
# class PictureAdmin(admin.ModelAdmin):
#     list_display=('thumbnail',)
#
# admin.site.register(Picture, PictureAdmin)
#
