import os
from django import template
from django.db.models.fields.files import ImageFieldFile
import Image as PImage
from urlparse import urljoin
from os import path

register = template.Library()

class NotImageFieldError(ValueError):
    pass

def get_thumb(imagefield, width, height):
    size = width, height
    pathname, filename = path.split(imagefield.path)
    shortname, extname = path.splitext(filename)
    thumbname = '%s-%dx%d%s' % (shortname, width, height, extname)
    p = path.join(pathname, 'thumbs', thumbname)
    if path.isfile(p):
        pass
    else:
        if not path.isdir(path.dirname(p)):
            os.mkdir(path.dirname(p), 0755)
        img = PImage.open(imagefield.path)
        img.thumbnail(size, PImage.ANTIALIAS)
        img.save(p)

    return urljoin(imagefield.url, 'thumbs/' + thumbname)


def get_rescale(imagefield, width, height):
    pathname, filename = path.split(imagefield.path)
    shortname, extname = path.splitext(filename)
    thumbname = '%s-%dx%d%s' % (shortname, width, height, extname)
    p = path.join(pathname, 'rescaled', thumbname)
    if path.isfile(p):
        pass
    else:
        if not path.isdir(path.dirname(p)):
            os.mkdir(path.dirname(p), 0755)
        img = PImage.open(imagefield.path)
        src_width, src_height = img.size
        src_ratio = float(src_width) / float(src_height)
        dst_ratio = float(width) / float(height)

        if dst_ratio < src_ratio:
            crop_height = src_height
            crop_width = crop_height * dst_ratio
            x_offset = float(src_width - crop_width) / 2
            y_offset = 0
        else:
            crop_width = src_width
            crop_height = crop_width / dst_ratio
            x_offset = 0
            y_offset = float(src_height - crop_height) / 3
        img = img.crop((int(x_offset), int(y_offset), int(x_offset+crop_width), int(y_offset+crop_height)))
        img = img.resize((width, height), PImage.ANTIALIAS)
        img.save(p)

    return urljoin(imagefield.url, 'rescaled/' + thumbname)

class ThumbNail(template.Node):
    def __init__(self, imagestr, width, height, rescale=False):
        self.imagestr = template.Variable(imagestr)
        self.width = width
        self.height = height
        self.rescale = rescale

    def render(self, context):
        image = self.imagestr.resolve(context)
        if not isinstance(image, ImageFieldFile):
            raise NotImageFieldError, '%s is not an instance of ImageFieldFile.' % self.imagestr
        if self.rescale:
            self.url = get_rescale(image, self.width, self.height)
        else:
            self.url = get_thumb(image, self.width, self.height)
        return self.url

@register.tag(name='thumb')
def do_thumb(parser, token):
    try:
        tagname, imagestr, widthstr, heightstr, rescalestr = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires exactly 4 arguments" % token.contents.split()[0]
    try:
        width = int(widthstr)
        height = int(heightstr)
        if rescalestr in ('1', 'yes', 'true', 'True'):
            rescale = True
        else:
            rescale = False
    except ValueError:
        raise template.TemplateSyntaxError, 'Arguments error in tag %r' % token.contents.split()[0]
    return ThumbNail(imagestr, width, height, rescale)