from PIL import Image, ImageChops


def apply_mask(layer, image, bbox=None):
    """
    Apply raster mask to the image.

    This might change the size and offset of the image. Resulting offset wrt
    the psd viewport is kept in `image.info['offset']` field.

    :param layer: `~psd_tools.api.layers.Layer`
    :param image: PIL.Image
    :return: PIL.Image
    """

    offset = image.info.get('offset', layer.offset)
    image.info['offset'] = offset
    if layer.has_mask() and not layer.mask.disabled:
        mask_bbox = layer.mask.bbox
        if mask_bbox != (0, 0, 0, 0):
            color = layer.mask.background_color
            if bbox:
                pass
            elif color == 0:
                bbox = mask_bbox
            else:
                bbox = layer._psd.viewbox
            size = (bbox[2] - bbox[0], bbox[3] - bbox[1])
            image_ = Image.new(image.mode, size)
            image_.paste(image, (offset[0] - bbox[0], offset[1] - bbox[1]))
            mask = Image.new('L', size, color=color)
            mask_image = layer.mask.topil()
            if mask_image:
                mask.paste(
                    mask_image,
                    (mask_bbox[0] - bbox[0], mask_bbox[1] - bbox[1])
                )
            if image_.mode.endswith('A'):
                mask = ImageChops.darker(image_.getchannel('A'), mask)
            image_.putalpha(mask)
            image_.info['offset'] = (bbox[0], bbox[1])
            return image_
    return image