from django.conf import settings
import fstools
import logging
import mimetypes
import media
from ..models import get_item_type, TYPE_IMAGE, TYPE_VIDEO
import os
import pygal

logger = logging.getLogger(settings.ROOT_LOGGER_NAME).getChild(__name__)


def get_image_class(full_path):
    return {
        TYPE_IMAGE: image,
        TYPE_VIDEO: video,
    }.get(get_item_type(full_path), other)


def get_image_instance(full_path, request):
    return get_image_class(full_path)(full_path, request)


class base_item(object):
    MIME_TYPES = {
        '.ada': 'text/x/adasrc',
        '.hex': 'text/x/hex',
        '.jpg': 'image/x/generic',
        '.jpeg': 'image/x/generic',
        '.jpe': 'image/x/generic',
        '.png': 'image/x/generic',
        '.tif': 'image/x/generic',
        '.tiff': 'image/x/generic',
        '.gif': 'image/x/generic',
        '.avi': 'video/x/generic',
        '.mpg': 'video/x/generic',
        '.mpeg': 'video/x/generic',
        '.mpe': 'video/x/generic',
        '.mov': 'video/x/generic',
        '.qt': 'video/x/generic',
        '.mp4': 'video/x/generic',
        '.webm': 'video/x/generic',
        '.ogv': 'video/x/generic',
        '.flv': 'video/x/generic',
        '.3gp': 'video/x/generic',
    }

    def __init__(self, full_path, request):
        self.full_path = full_path
        self.request = request
        self.rel_path = pygal.get_rel_path(full_path)
        #
        ext = os.path.splitext(self.full_path)[1].lower()
        self.mime_type = self.MIME_TYPES.get(ext, mimetypes.types_map.get(ext, 'unknown'))

    def __cache_image_folder__(self, rel_path):
        return os.path.join(settings.XNAIL_ROOT, rel_path.replace('_', '__').replace('/', '_'))

    def __cache_image_name__(self, max_size):
        filename = '%04d_%02x_%s.jpg' % (max_size, self.XNAIL_VERSION_NUMBER, fstools.uid(self.full_path, None))
        return os.path.join(self.__cache_image_folder__(self.rel_path), filename)

    def __delete_cache_image__(self, max_size):
        folder = self.__cache_image_folder__(self.rel_path)
        if os.path.isdir(folder):
            for fn in fstools.filelist(folder, '%04d*' % max_size):
                try:
                    os.remove(fn)
                except OSError:
                    pass    # possibly file is already removed by another process


class image(base_item):
    XNAIL_VERSION_NUMBER = 1

    def __init__(self, *args, **kwargs):
        base_item.__init__(self, *args, **kwargs)
        self.mime_type_xnails = mimetypes.types_map.get('.jpg', 'unknown')

    def get_resized_image_data(self, max_size):
        cache_filename = self.__cache_image_name__(max_size)
        if not os.path.exists(cache_filename):
            logger.info('Creating xnail-%d for %s', max_size, self.rel_path)
            self.__delete_cache_image__(max_size)
            im = media.image(self.full_path)
            im.resize(max_size)
            im.rotate_by_orientation()
            #
            # create cache file
            #
            fstools.mkdir(os.path.dirname(cache_filename))
            im.save(cache_filename)
            return im.image_data()
        return open(cache_filename, 'rb').read()

    def thumbnail_picture(self):
        return self.get_resized_image_data(pygal.get_thumbnail_max_size(self.request))

    def webnail_picture(self):
        return self.get_resized_image_data(pygal.get_webnail_size(self.request))


class video(image):
    def get_resized_image_data(self, max_size):
        cache_filename = self.__cache_image_name__(max_size)
        if not os.path.exists(cache_filename):
            logger.info('Creating xnail-%d for %s', max_size, self.rel_path)
            self.__delete_cache_image__(max_size)
            im = media.image(self.full_path)
            im.resize(max_size)
            im.join(os.path.join(os.path.dirname(__file__), 'video.png'))
            #
            # create cache file
            #
            fstools.mkdir(os.path.dirname(cache_filename))
            im.save(cache_filename)
            return im.image_data()
        return open(cache_filename, 'rb').read()


class other(base_item):
    def __init__(self, *args, **kwargs):
        base_item.__init__(self, *args, **kwargs)
        self.mime_type_xnails = mimetypes.types_map.get('.png', 'unknown')

    def thumbnail_picture(self):
        fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'mimetype_icons', '%s.png' % (self.mime_type).replace('/', '-'))
        if not os.path.exists(fn):
            fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'mimetype_icons', 'unknown.png')
        return open(fn, 'rb').read()

    def webnail_picture(self):
        return self.thumbnail_picture()
