# -*- coding: latin-1 -*-
""" 
   Copyright (C) 2005-2011 PimenTech SARL (http://www.pimentech.net)

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  
"""
from Products.PimenTechLibCommon.dbp import DBP
from Products.PimenTechLibCommon.map import Map

import os
import shutil

from OFS.SimpleItem import SimpleItem

class FileUploadManager:
	"""
	Copy a Zope uploaded file to a destination
	"""

	def __init__(self, source, destination_path, destination_name):
		"""
		source : Zope FileUpload
		destination_path : file destination path
		destination_name : file destination name
		"""
		self.source = source
		self.destination_path = destination_path
		self.destination_name = destination_name

	def copy(self):
		try:
			file_content = self.source.read()
			dest_file = open("%s%s%s" %(self.destination_path, os.sep, self.destination_name), "w");
			dest_file.write(file_content)
			dest_file.close()
			return True
		except:
			return False


ACCEPTED_CONTENT_TYPES = ['image/jpeg', 'image/pjpeg',
						  'image/png', 'image/x-png',
						  'image/gif',
						  'application/pdf', 'application/x-download',
						  ]

def set_accepted_content_types(accepted_content_types):
	global ACCEPTED_CONTENT_TYPES
	ACCEPTED_CONTENT_TYPES = accepted_content_types

def upload_image(new_image, destination_path, name, caller = None):
	"""
	"""
	if caller:
		caller.message("in upload_image(%s, %s, %s)" % (new_image.headers['Content-Type'], destination_path, name))
		caller.message(ACCEPTED_CONTENT_TYPES)

	if not new_image.headers['Content-Type'] in ACCEPTED_CONTENT_TYPES:
		return False

	if caller:
		caller.message("%s in ACCEPTED_CONTENT_TYPES" % new_image.headers['Content-Type'])

	if new_image.headers['Content-Type'] in ['image/jpeg', 'image/pjpeg']:
		file_ext = "jpg"
	elif new_image.headers['Content-Type'] in ['image/png', 'image/x-png']:
		file_ext = "png"
	elif new_image.headers['Content-Type'] == 'image/gif':
		file_ext = "gif"
	elif new_image.headers['Content-Type'] in [ 'application/pdf', 'application/x-download' ]:
		file_ext = "pdf"
	else:
		return False

	filename = '%s.%s' % (name, file_ext)

	if caller:
		caller.message("trying upload %s" % filename)

	fum = FileUploadManager(new_image, destination_path, filename)

	if caller:
		caller.message("uploaded %s" % filename)	

	if (fum.copy()):
		return filename
	else:
		return False
		
class SQLFSStoredImage(SimpleItem, DBP):
	"""
	Store one image
	"""

	meta_type = "SQLFSStoredImage"
	
	def __init__(self, path, http_path, table, table_ref, uid_ref, type_image, format_image, numero, connection_id = None):
		"""
		path      : where is stored the image
		http_path : path to access image via http
		table     : row describing image is stored this table
		"""
		self.path         = path
		self.http_path    = http_path
		self.table        = table
		self.table_ref    = table_ref
		self.uid_ref      = uid_ref
		self.format_image = format_image
		self.type_image   = type_image
		self.numero       = numero
		DBP.__init__(self, self.getShortName(), connection_id)
		self.exists       = False

	def manage_afterAdd(self, id, container):
		self.updateFromSQL()

	def updateFromSQL(self):
		query = '''SELECT uid, source, ref_object FROM %s
WHERE %s = %s AND ref_type_image = %s AND ref_format_image = %s AND numero = %s
''' % (self.table, self.table_ref, self.uid_ref, self.type_image, self.format_image, self.numero)
		self.message(query)
		res = self.fetchoneof(query)
		self.uid = 0
		self.ref_object = 0
		self.exists = False
		if len(res):
			(uid, source, ref_object) = res
			self.uid        = uid
			self.ref_object = ref_object
			self.source     = source
			self.exists     = True
		else:
			self.message("SQLFSStoredImage - image %s - image non trouvée" %(self.getShortName()))

	def fileExists(self):
		return self.exists
			
	def uploadFromFile(self, new_image):
		"""
		new_image : source image (Zope FileUpload Object)
		"""
		if self.fileExists():
			self.remove()

		self.message("SQLFSStoredImage.uploadFromFile - trying uploading %s to %s%s%s" % (new_image.headers['Content-Type'], 
																						  self.path, os.sep,  self.getShortName()))
			
		source = upload_image(new_image, self.path, self.getShortName(), self)
		if source:
			self.exec_sql("""
			INSERT INTO %s (source, ref_type_image, ref_format_image, numero, %s, ref_object)
			VALUES ('%s', '%s', '%s', '%s', '%s', %s);
			""" % (self.table, self.table_ref, source, self.type_image, self.format_image, self.numero, self.uid_ref, self.ref_object))
			self.source = source
			self.ref_object = 0
			self.exists = True
		else:
			self.message("SQLFSStoredImage.uploadFromFile - Failed uploading %s to %s%s%s" %(new_image, self.path, os.sep,  self.getShortName()))


	def getUrl(self):
		if self.fileExists:
			return "%s/%s" %(self.http_path, self.source)
		else:
			return False
	def getPath(self):
		if self.fileExists:
			return "%s/%s" %(self.path, self.source)
		else:
			return False
		
	def getShortName(self):
		"""
		Builds image name without extension
		"""
		return "%s_%s_%s_%s" %(self.uid_ref, self.type_image, self.format_image, self.numero)

	def remove(self):
		
		if self.fileExists():

			self.exists       = False
			try:
				self.exec_sql('''
				DELETE FROM %s
				WHERE %s = %s AND ref_type_image = %s AND ref_format_image = %s AND numero = %s ;
				''' % (self.table, self.table_ref, self.uid_ref, self.type_image, self.format_image, self.numero))
			except:
				pass
			try:
				os.remove("%s%s%s" %(self.path, os.sep, self.source))
			except:
				pass
			return True
		return False

	def copy(self, new_uid_ref):
		if not self.fileExists() or not self.uid_ref:
			return False

		new_source = "%s%s" %(new_uid_ref, self.source[(len(str(self.uid_ref))):])
		uid_copy = self.aq_parent._get_next_uid()
		if self.exec_sql("""
		INSERT INTO %s (uid, source, ref_type_image, ref_format_image, numero, %s, frozen, ref_object)
		VALUES ('%s', '%s', '%s', '%s', '%s', '%s', 1, (SELECT ref_object FROM %s WHERE source = '%s' AND frozen = 0 ORDER BY datemodif LIMIT 1));
		""" % (self.table, self.table_ref, uid_copy, new_source, self.type_image, self.format_image, self.numero, new_uid_ref, self.table, self.source)):
			self.exec_sql("UPDATE %s SET ref_object = '%s' WHERE source = '%s' AND frozen = 0" %(self.table, uid_copy, self.source))
			self.ref_object = uid_copy # on met à jour la ref de l'image vers la dernière copie
			shutil.copyfile("%s%s%s" %(self.path, os.sep, self.source), "%s%s%s" %(self.path, os.sep, new_source))
			return True
		else:
			return False

class SQLFSStoredImageManager(Map):
	"""
	"""

	def __init__(self, id, connection_id = None):
		Map.__init__(self, id)
		if connection_id:
			self.connection_id = connection_id

	def manageImage(self, path, http_path, table, table_ref, uid, type_image, format_image, numero):
		stored_image = SQLFSStoredImage(path, http_path, table, table_ref, uid, type_image, format_image, numero, self.connection_id)
		image_id = stored_image.getShortName()
		self[image_id] = stored_image
		return image_id

	def getImage(self, image_id):
		try:
			return self[image_id]
		except:
			return False

	def deleteImage(self, image_id):
		try:
			self.getImage(image_id).remove()
			del self[image_id]
			return True
		except:
			return False

	def __len__(self):
		return len(images)

	def updateImagesFromSQL(self):
		for object in self.aq_inner.values():
			if object.meta_type == "SQLFSStoredImage":
				object.updateFromSQL()

