from PIL import Image
from common import handle_uploaded_file, generate_random_string, force_make_dir
from exception import UploadedImgFileError
from cStringIO import StringIO
from django.core.files.base import ContentFile

import os
import settings

# resize the image at given path to given size (ratio preserved : optional)
# size : (width, height)
def imageResize(src, size, ratioPreserved = True, reduction = True, expand = True):
	img = Image.open(src)
	imgSize = img.size
	imgType = img.format
	widthRatio = float(imgSize[0]) / size[0]
	heightRatio = float(imgSize[1]) / size[1]
	
	if reduction and (widthRatio > 1 or heightRatio > 1):
		if ratioPreserved:
			widthRatio = heightRatio = max(widthRatio, heightRatio)
		width = int(imgSize[0] / widthRatio)
		height = int(imgSize[1] / heightRatio)
		
		# resize the image
		img = img.resize([width, height])
		
		# save the image
		img.save(src, imgType)
		
	elif expand and (widthRatio < 1 or heightRatio < 1):
		if ratioPreserved:
			widthRatio = heightRatio = min(widthRatio, heightRatio)
		width = int(imgSize[0] / widthRatio)
		height = int(imgSize[1] / heightRatio)
		
		# resize the image
		img = img.resize([width, height])
		
		# save the image
		img.save(src, imgType)
		
	return img.size
	
# Handle uploaded image file
def handleUploadedImg(request, filekey, file_dir, imgSizeLimit):
	# condition variables
	IMGFILE_SIZE_LIMIT = 10 * 1024 * 1024 # in bytes
	allowedExt = ['jpg', 'jpeg', 'png', 'gif', 'bmp'] # allowed extension list
	exceptionalExt = ['tif', 'tiff']
	
	# get imgfile
	imgfile = request.FILES[filekey]
	
	# if file size exceeded
	if imgfile.size >= IMGFILE_SIZE_LIMIT:
		raise UploadedImgFileError('FileSizeExceeded')
		return
	
	# if file extension is not one of image files'
	ext = os.path.splitext(imgfile.name)[1] # get extension of file
	if not (ext) or not (ext.split('.')[1].lower() in allowedExt):
		if ext.split('.')[1].lower() in exceptionalExt:
			imgObj = Image.open(ContentFile(imgfile.read()))
			
			temp_handle = StringIO()
			imgObj.save(temp_handle, 'jpeg')
			temp_handle.seek(0)
			
			imgfile = ContentFile(temp_handle.read())
			ext = 'jpg'
		else:
			raise UploadedImgFileError('NotAllowedExtension')
			return
		
	# create temporary file path
	force_make_dir(os.path.join(settings.MEDIA_ROOT, file_dir))
	
	while True:
		# create random filename until file does not exist
		file_name = generate_random_string(32)
		file_path = file_dir + file_name + ext
		if not os.path.isfile(os.path.join(settings.MEDIA_ROOT, file_path)):
			break
	
	# move to temporary directory and return the path of uploaded file
	handle_uploaded_file(imgfile, os.path.join(settings.MEDIA_ROOT, file_path))
	
	# set modified size
	imgSize = imageResize(os.path.join(settings.MEDIA_ROOT, file_path), imgSizeLimit, expand = False)
	
	return {'path': file_path, 'size': imgSize}
	
# Make small image
def createSmallImage(src, size=(320, 320), expand = False):
	srcImage = Image.open(src)
	imgSize = srcImage.size
	widthRatio = float(imgSize[0]) / size[0]
	heightRatio = float(imgSize[1]) / size[1]
	dest = os.path.splitext(src)[0] + str(size[0]) + 'x' + str(size[1]) + os.path.splitext(src)[1]
	
	if widthRatio > 1 or heightRatio > 1:
		widthRatio = heightRatio = max(widthRatio, heightRatio)
		
	elif expand and (widthRatio < 1 or heightRatio < 1):
		widthRatio = heightRatio = min(widthRatio, heightRatio)
		
	width = int(imgSize[0] / widthRatio)
	height = int(imgSize[1] / heightRatio)
		
	# resize the image
	srcImage = srcImage.resize([width, height])
	
	# save the image
	srcImage.save(dest)
		
	return srcImage.size