from StringIO import StringIO
import json, os
import urllib2
from utils import urljoin, subrect, pdf2img

from models import Image, Size, Tag, ImageException, TMP_DIR, TMP_URL
    
PREVIEWSIZE = 640, 480

def genPreviews(info, pdf_fname):
    if not info['id'].endswith('.PDF'):
        return None

    img2 = pdf2img(pdf_fname, PREVIEWSIZE, info['id'])

    boxes = [ (b, urljoin(TMP_URL, 'preview_%s_%s.jpg' % (b, info['id']))) for b in 'media crop bleed trim art'.split() if info.has_key('box_%s' % b)]
    for box, _ in boxes:
        fname = os.path.join(TMP_DIR, 'preview_%s_%s.jpg' % (box, info['id']))
        r = subrect(info['box_media'], info['box_%s' % box], img2.size)
        img2.copy().crop(r).save(fname)
    return boxes
    
def extractPreviewInfo(image_ref):
    '''
    Extracts information necessary to generate a preview page from a temporary image reference.
    The result is returned as a dictionary.
    '''
    imgfilename = os.path.join(TMP_DIR, os.path.basename(image_ref))
    bytes = open(imgfilename, 'rb').read()
    info = Image.getinfo(bytes)
    
    tags = Tag.objects.order_by('id',)
    tagNames = ([tag.id for tag in tags])
    
    #if size not set, the accept button is hidden.
    if len(info['possible_sizes']) >= 1:
        size = Size.objects.get(id=info['possible_sizes'][0])
    else:
        size = None

    if info['format'] == 'PDF':
        try:
            info['boxes'] = genPreviews(info, imgfilename)
        except ValueError:
            Image.bad(imgfilename)
            raise ImageException("This pdf is currently not supported by this system. This issue is reported and we will try to fix it.")
        info['boxes_js'] = json.dumps(info['boxes'])
        info['preview_image'] = urljoin(TMP_URL, 'preview_media_%s.jpg' % info['id'])
    else:
        info['preview_image'] = urljoin(TMP_URL, image_ref)

    info.update(dict(
            imgfilename = imgfilename,
            size = size,
            TMP_URL = TMP_URL,
            tags = json.dumps(tagNames),
    ))
    return info
    
def submitImage(image_file, image_url):
    '''
    This function is meant to be reused wherever images need to be uploaded.
    Supports direct uploads and url references. Both can be zips containing the actual images.
    The file is checked by imadj using PIL and PageCatcher.
    An ImageException is raised if the image cannot be validated.
    Returns a dictionary containing image information or an actual Image object if the image is
    already present in the database.
    '''
    content = filename = None
    try:
        if image_url:
            f = urllib2.urlopen(image_url)  #raises 404 if not found
            content = f.read()
            filename = image_url.split('/')[-1]
        elif image_file:
            content = image_file.read()
            filename = image_file.name
    except Exception:
        pass # Error handled in next condition
    if not content or not filename:
        raise ImageException("Please include a URL to a valid image, or upload an image file or zip containing images!")

    if filename.lower().endswith('.zip'):
        #this saves it in the imadj-data/tmp directory.
        img_info = Image.new_zip(filename, content)
        raise ValueError("Got a zipfile! %s" % filename)
        
    try:
        buf = StringIO(content)
        img_info = Image.newtmp(buf)
    except Exception, e:
        raise ImageException("Please include a URL to a valid image, or upload an image file or zip containing images:", e)

    if img_info['already_present']:
        return Image.objects.get(id=img_info['id'])
    return img_info
