from imagekit.lib import Image
import warnings
from .base import Anchor


class Resize(object):
    """
    Resizes an image to the specified width and height.

    """
    def __init__(self, width, height):
        """
        :param width: The target width, in pixels.
        :param height: The target height, in pixels.

        """
        self.width = width
        self.height = height

    def process(self, img):
        return img.resize((self.width, self.height), Image.ANTIALIAS)


class ResizeToCover(object):
    """
    Resizes the image to the smallest possible size that will entirely cover the
    provided dimensions. You probably won't be using this processor directly,
    but it's used internally by ``ResizeToFill`` and ``SmartResize``.

    """
    def __init__(self, width, height):
        """
        :param width: The target width, in pixels.
        :param height: The target height, in pixels.

        """
        self.width, self.height = width, height

    def process(self, img):
        original_width, original_height = img.size
        ratio = max(float(self.width) / original_width,
                float(self.height) / original_height)
        new_width, new_height = (int(original_width * ratio),
                int(original_height * ratio))
        return Resize(new_width, new_height).process(img)


class ResizeToFill(object):
    """
    Resizes an image, cropping it to the exact specified width and height.

    """

    def __init__(self, width=None, height=None, anchor=None):
        """
        :param width: The target width, in pixels.
        :param height: The target height, in pixels.
        :param anchor: Specifies which part of the image should be retained
            when cropping.
        """
        self.width = width
        self.height = height
        self.anchor = anchor

    def process(self, img):
        from .crop import Crop
        img = ResizeToCover(self.width, self.height).process(img)
        return Crop(self.width, self.height,
                anchor=self.anchor).process(img)


class SmartResize(object):
    """
    The ``SmartResize`` processor is identical to ``ResizeToFill``, except that
    it uses entropy to crop the image instead of a user-specified anchor point.
    Internally, it simply runs the ``ResizeToCover`` and ``SmartCrop``
    processors in series.
    """
    def __init__(self, width, height):
        """
        :param width: The target width, in pixels.
        :param height: The target height, in pixels.

        """
        self.width, self.height = width, height

    def process(self, img):
        from .crop import SmartCrop
        img = ResizeToCover(self.width, self.height).process(img)
        return SmartCrop(self.width, self.height).process(img)


class ResizeCanvas(object):
    """
    Resizes the canvas, using the provided background color if the new size is
    larger than the current image.

    """
    def __init__(self, width, height, color=None, anchor=None, x=None, y=None):
        """
        :param width: The target width, in pixels.
        :param height: The target height, in pixels.
        :param color: The background color to use for padding.
        :param anchor: Specifies the position of the original image on the new
            canvas. Valid values are:

            - Anchor.TOP_LEFT
            - Anchor.TOP
            - Anchor.TOP_RIGHT
            - Anchor.LEFT
            - Anchor.CENTER
            - Anchor.RIGHT
            - Anchor.BOTTOM_LEFT
            - Anchor.BOTTOM
            - Anchor.BOTTOM_RIGHT

            You may also pass a tuple that indicates the position in
            percentages. For example, ``(0, 0)`` corresponds to "top left",
            ``(0.5, 0.5)`` to "center" and ``(1, 1)`` to "bottom right". This is
            basically the same as using percentages in CSS background positions.

        """
        if x is not None or y is not None:
            if anchor:
                raise Exception('You may provide either an anchor or x and y'
                        ' coordinate, but not both.')
            else:
                self.x, self.y = x or 0, y or 0
                self.anchor = None
        else:
            self.anchor = anchor or Anchor.CENTER
            self.x = self.y = None

        self.width = width
        self.height = height
        self.color = color or (255, 255, 255, 0)

    def process(self, img):
        original_width, original_height = img.size

        if self.anchor:
            anchor = Anchor.get_tuple(self.anchor)
            trim_x, trim_y = self.width - original_width, \
                    self.height - original_height
            x = int(float(trim_x) * float(anchor[0]))
            y = int(float(trim_y) * float(anchor[1]))
        else:
            x, y = self.x, self.y

        new_img = Image.new('RGBA', (self.width, self.height), self.color)
        new_img.paste(img, (x, y))
        return new_img


class AddBorder(object):
    """
    Add a border of specific color and size to an image.

    """
    def __init__(self, thickness, color=None):
        """
        :param color: Color to use for the border
        :param thickness: Thickness of the border. Can be either an int or
            a 4-tuple of ints of the form (top, right, bottom, left).
        """
        self.color = color
        if isinstance(thickness, int):
            self.top = self.right = self.bottom = self.left = thickness
        else:
            self.top, self.right, self.bottom, self.left = thickness

    def process(self, img):
        new_width = img.size[0] + self.left + self.right
        new_height = img.size[1] + self.top + self.bottom
        return ResizeCanvas(new_width, new_height, color=self.color,
                x=self.left, y=self.top).process(img)


class ResizeToFit(object):
    """
    Resizes an image to fit within the specified dimensions.

    """

    def __init__(self, width=None, height=None, upscale=None, mat_color=None, anchor=Anchor.CENTER):
        """
        :param width: The maximum width of the desired image.
        :param height: The maximum height of the desired image.
        :param upscale: A boolean value specifying whether the image should
            be enlarged if its dimensions are smaller than the target
            dimensions.
        :param mat_color: If set, the target image size will be enforced and the
            specified color will be used as a background color to pad the image.

        """
        self.width = width
        self.height = height
        self.upscale = upscale
        self.mat_color = mat_color
        self.anchor = anchor

    def process(self, img):
        cur_width, cur_height = img.size
        if not self.width is None and not self.height is None:
            ratio = min(float(self.width) / cur_width,
                    float(self.height) / cur_height)
        else:
            if self.width is None:
                ratio = float(self.height) / cur_height
            else:
                ratio = float(self.width) / cur_width
        new_dimensions = (int(round(cur_width * ratio)),
                          int(round(cur_height * ratio)))
        if (cur_width > new_dimensions[0] or cur_height > new_dimensions[1]) or \
            self.upscale:
                img = Resize(new_dimensions[0],
                        new_dimensions[1]).process(img)
        if self.mat_color:
            img = ResizeCanvas(self.width, self.height, self.mat_color, anchor=self.anchor).process(img)
        return img

@@ -7416,16 +7416,28 @@
 at_color
+ is not None
 :%0A      

Fix bug with black mat_color