'''
Wand (>=v0.3.0) engine for Sorl-thumbnail
'''

from wand import exceptions
from wand.image import Image
from wand.version import MAGICK_VERSION_NUMBER

from sorl.thumbnail.engines.base import EngineBase


class Engine(EngineBase):
    def get_image(self, source):
        return Image(blob=source.read())

    def get_image_size(self, image):
        return image.size

    def is_valid_image(self, raw_data):
        '''
        Wand library makes sure when opening any image that is fine, when
        the image is corrupted raises an exception.
        '''

        try:
            Image(blob=raw_data)
            return True
        except (exceptions.CorruptImageError, exceptions.MissingDelegateError):
            return False

    def _orientation(self, image):
        orientation = image.orientation
        if orientation == 'top_right':
            image.flop()
        elif orientation == 'bottom_right':
            image.rotate(degree=180)
        elif orientation == 'bottom_left':
            image.flip()
        elif orientation == 'left_top':
            image.rotate(degree=90)
            image.flop()
        elif orientation == 'right_top':
            image.rotate(degree=90)
        elif orientation == 'right_bottom':
            image.rotate(degree=-90)
            image.flop()
        elif orientation == 'left_bottom':
            image.rotate(degree=-90)
        image.orientation = 'top_left'
        return image

    def _flip_dimensions(self, image):
        return image.orientation in ['left_top', 'right_top', 'right_bottom', 'left_bottom']

    def _colorspace(self, image, colorspace):
        if colorspace == 'RGB':
            if image.alpha_channel:
                if MAGICK_VERSION_NUMBER < 0x700:
                    image.type = 'truecolormatte'
                else:
                    image.type = 'truecoloralpha'
            else:
                image.type = 'truecolor'
        elif colorspace == 'GRAY':
            if image.alpha_channel:
                if MAGICK_VERSION_NUMBER < 0x700:
                    image.type = 'grayscalematte'
                else:
                    image.type = 'grayscalealpha'
            else:
                image.type = 'grayscale'
        else:
            return image
        return image

    def _scale(self, image, width, height):
        image.resize(width, height)
        return image

    def _crop(self, image, width, height, x_offset, y_offset):
        image.crop(left=x_offset, top=y_offset, width=width, height=height)
        return image

    def _cropbox(self, image, x, y, x2, y2):
        image.crop(left=x, top=y, width=x2 - x, height=y2 - y)
        return image

    def _get_raw_data(self, image, format_, quality, image_info=None, progressive=False):
        image.compression_quality = quality
        if format_ == 'JPEG' and progressive:
            image.format = 'pjpeg'
        else:
            image.format = format_
        return image.make_blob()
