import os
from PIL import Image

from django.forms import Widget, FileInput
from django.utils.safestring import mark_safe
from django.conf import settings
from django.core.urlresolvers import reverse
from django.template.loader import render_to_string

FILEUPLOAD_STATIC_URL = getattr(settings, 'FILEUPLOAD_STATIC_URL', settings.MEDIA_ROOT + "fileupload/")

class SimpleFileWidget(FileInput):
    """
    Works like AdminFileWidget
    Displays an image thumb if the current file is an image 
    """

    TEMPLATE = "simple_file_widget_template.html"

    def __init__(self, attrs = {}):
        "attrs are capable to override TEMPLATE value"
        for key, value in attrs.items():
            setattr(self, key, value)
        super(SimpleFileWidget, self).__init__()

    def render(self, name, value, attrs={}):
        context = self.build_attrs(
            attrs,
            file = value,
            input_field = super(SimpleFileWidget, self).render(name, value, attrs),
        )

        # special case of image
        if value and value.path:
            try:
                Image.open(value.path)
                context['image'] = value
            except IOError:
                pass
        
        return mark_safe(render_to_string(self.TEMPLATE, context))

class FileUploadWidget(Widget):
    """
    Base widget for working with files uploaded via AJAX in admin interface. 
    Needs special url for file uploading
    Generates html info block for file uploaded via AJAX request
    """
    
    TEMPLATE = "file_upload_widget_template.html"
    AJAX_TEMPLATE = "file_upload_widget_ajax_template.html"
    ALLOW_CHANGE = True
    ALLOW_DELETE = True
    
    # use lazy calculation to avoid looping of url dispatcher
    LOAD_URL = lambda self: reverse('load_file_via_admin')

    class Media(object):
        css = {
            'all': (
                FILEUPLOAD_STATIC_URL + "jquery-ui.css",
                FILEUPLOAD_STATIC_URL + "custom.css",
            )
        }
        js = (
            FILEUPLOAD_STATIC_URL + "namespace-fix.js",
            FILEUPLOAD_STATIC_URL + "jquery-ui.js",
            FILEUPLOAD_STATIC_URL + "jquery.form.js",
            FILEUPLOAD_STATIC_URL + "jquery.frmdialog.js",
            FILEUPLOAD_STATIC_URL + "jquery.picrelated.js",
        )
        
    def __init__(self, attrs = {}):
        "attrs are capable to override TEMPLATE value"
        for key, value in attrs.items():
            setattr(self, key, value)
        super(FileUploadWidget, self).__init__()
        
    def ajax_render(self, rel_path, attrs = {}):
        "Part of server AJAX answer"
        abs_path = os.path.join(settings.MEDIA_ROOT, rel_path)
        file_size = os.stat(abs_path).st_size
        context = self.build_attrs(
            attrs,
            file_url = settings.MEDIA_URL + rel_path,
            file_size = file_size,
            file_path = rel_path,
        )
        return mark_safe(render_to_string(self.AJAX_TEMPLATE, context))

    def render(self, name, value, attrs = {}):
        "Value - Django File object or path relative to MEDIA_ROOT"
        rel_path = unicode(value) if value else ''
        context = self.build_attrs(
            attrs,
            rel_path = rel_path,
            file_info = self.ajax_render(rel_path) if rel_path else u'',
            load_url = self.LOAD_URL() if callable(self.LOAD_URL) else self.LOAD_URL,
            field_name = name,
            allow_change = self.ALLOW_CHANGE,
            allow_delete = self.ALLOW_DELETE,
        )
        return mark_safe(render_to_string(self.TEMPLATE, context))

class ImageUploadWidget(FileUploadWidget):
    """
    Image download widget
    """
    
    AJAX_TEMPLATE = "image_upload_widget_ajax_template.html"
    LOAD_URL = lambda self: reverse('load_image_via_admin')
        
    def ajax_render(self, rel_path, attrs = {}):
        abs_path = os.path.join(settings.MEDIA_ROOT, rel_path)
        resolution = Image.open(abs_path).size
        attrs['img_x_size'] = resolution[0]
        attrs['img_y_size'] = resolution[1]
            
        return super(ImageUploadWidget, self).ajax_render(rel_path, attrs)
