# Phatch - Photo Batch Processor
# Copyright (C) 2007-2008 www.stani.be
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see http://www.gnu.org/licenses/
#
# Phatch recommends SPE (http://pythonide.stani.be) for editing python files.
#
# Follows PEP8

# Embedded icon is taken from www.openclipart.org (public domain)

from core import models
from lib.reverse_translation import _t
from lib.imtools import has_transparency, paste

#---PIL


def init():
    global Image, ImageOps, imtools
    import Image
    import ImageOps
    from lib import imtools
    global HTMLColorToRGBA
    from lib.colors import HTMLColorToRGBA


def put_border(image, size, offset, contour_color, fill_color, opacity,
        include_image):
    if opacity < 100:
        fill_color = HTMLColorToRGBA(fill_color, (255 * opacity) / 100)

    if not include_image:
        w, h = image.size
        image = Image.new('RGBA', (w + 2 * offset, h + 2 * offset), fill_color)
    else:
        image = image.convert('RGBA')
        image = ImageOps.expand(image, border=offset, fill=fill_color)
    image = ImageOps.expand(image, border=size, fill=contour_color)
    return image


def put_contour(image, size=1, offset=0, contour_color=0, fill_color=0,
        opacity=100, include_image=True):
    if not has_transparency(image):
        return put_border(
                    image, size, offset, contour_color, fill_color,
                    opacity, include_image)
    image = image.convert('RGBA')
    mask = imtools.get_alpha(image)

    w, h = image.size
    outer_mask = mask.resize(
        (w + 2 * (size + offset), h + 2 * (size + offset)),
        Image.ANTIALIAS)

    inner_mask = mask.resize(
        (w + 2 * offset, h + 2 * offset),
        Image.ANTIALIAS)
    inner_mask = ImageOps.expand(inner_mask, border=size, fill=0)
    paste(outer_mask, (255 * opacity) / 100, mask=inner_mask)
    if include_image:
        image = ImageOps.expand(image, border=size + offset, fill=(0, 0, 0, 0))
        mask = ImageOps.expand(mask, border=size + offset, fill=0)
        paste(outer_mask, 255, mask=mask)

    contour = ImageOps.colorize(outer_mask, (255, 255, 255), contour_color)
    paste(contour, fill_color, mask=inner_mask)
    if include_image:
        paste(contour, image, mask=image)
    contour.putalpha(outer_mask)
    return contour

#---Phatch


class Action(models.Action):
    label = _t('Contour')
    author = 'Nadia Alramli'
    email = 'mail@nadiana.com'
    init = staticmethod(init)
    pil = staticmethod(put_contour)
    version = '0.1'
    tags = [_t('filter')]
    __doc__ = _t('Draw a contour around image edges')

    def interface(self, fields):
        fields[_t('Size')] = self.PixelField('1px', choices=['1', '2', '5'])
        fields[_t('Offset')] = self.PixelField('0px', choices=['0', '1', '2'])
        fields[_t('Contour Color')] = self.ColorField('#000000')
        fields[_t('Fill Color')] = self.ColorField('#FFFFFF')
        fields[_t('Opacity')] = self.SliderField(100, 0, 100)
        fields[_t('Include image')] = self.BooleanField(True)

    def values(self, info):
        #pixel fields
        x0, y0 = info['size']
        dim = (x0 + y0) / 2
        return super(Action, self).values(info, pixel_fields={
            'Size': dim,
            'Offset': dim})

    icon = \
'x\xda\x01\x19\n\xe6\xf5\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\
\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\x00\x00\x00\x04sBIT\x08\x08\x08\
\x08|\x08d\x88\x00\x00\t\xd0IDATh\x81\xcd\xda{pT\xd5\x1d\x07\xf0\xef9\xe7n\
\xd8\x90\r\t\x01\x02bSh*\xa0R\x0cjx$\x18\x1e!<\xb2Q\xe4)\xad"\xbeZ[E\xb0N\
\x9d>\x10\x1d\xa6\xd3q\x9cqFK_S@Q\t\xa0\x16_\x9d)\x1b\x14\xadC AA\xd4)J\x08\
\x06A\x0cJ\x08\x9b\xc7n\xc2\xee\xbd\xf7\x9c\xdf\xaf\x7fl\x12\x92\x90H\x02\
\x84xf2\xe7\x9f\xdc\x99\xcf\xefw\xbe\xe7\xdc\xb3;\x0b|O\x86G)\x0b\x00f\x8e\
\x1a\x95y\xe6\xd9gO5<\xfdt\xed[\xf7\xdd\xb7q\xe2\xb0a\xa3\x9b\xfeEJ!D\xfb\
\xe7\xd4eUv2,)-M\xa4oJO\xbf\xee\xf5\xfb\xef\xffO\xbcRCHk\xef\xe8\xc1\x833\
\x16\x8f\x1d\xbb$1.\x8ev\x1d=\xba\xdb\x10A\n!\x19\xe0\xe6g{\xbd\x00K)K\x13\
\xe9\x9c\xf4\xf4\x8c\xed\xcb\x96\xbd\xe7\xf3x\x06Gl\x9b\x88Y4F\xa3\xc6\x18\
\x13?}\xc4\x88\x19\x13\xd2\xd2nx\xf7\xf0\xe1m\r\x8ec\xb7.\xe2\x9c%\xb9\xecxc\
tNzzF`\xd9\xb2\x1d\xf1R\x0e\x8a\xd8\xb6af\xa5\x8d\x811\x06\x9a\x88\xa3\x8e\
\xa3\x93\xbc^OyU\xd5\xde\x9f\xbd\xfc\xb2\xffXmmP\n!\x89\x99do\xe1\x95\x941|Z\
\xda\xd8\xc0C\x0f\xed\xf0*u\x0e\xde\x10\xc1\x18#\xa4\x10\x9e\xeap\xd8\xfdar\
\xf2\xf8\x17\x16,(\x1a\x10\x1f\xef#fH!D\xaf\x14 \xa5\xb4\x0c\x91\xce\xcb\x9b\
>\xee\xdf\xeb\xfe\xf9n\xbc\xd6\x83\xa2\xd1\xa8a \x86\'\x82!\x826\xa6\xe5O\
\x08\xe1\t66\xba\xc3SR\xc6\xfd\xb5\xa0`\x8bGJ\x82\x10\xaa7\xf6\x80%\x95\xd2\
\xfd\x93\x92\xc6\x8f\xbez\xd4;y?\xbf7%\xe28\xc6\xf3\xf5\xd7\xca\x08\xd9\xdcu\
\xb4[\x05h"0\xb3\nE\xa3\xee\x88\x81\x03\xaf!c\xc2\x1fTV\x96\\\xd6\x02\xa4\
\x94\x96eYZk\x9d\xb9\xfa\x89UE{\xf7}\x94B\xda\x98\xdc\xbb\xeeV\r\xb6\rSQ\x01\
\x92\x12\xba\x15\xba\xcdl\x0c\x88H6\xd86\x8fNM\xcd)9~|\xebe+@)a\x11\xb1\xee\
\x1b\x1f\x9f\xf9\xa7?\xae.\xfa\xc7\xdau\x03\xb7l\xdel~<b\xa4\xaa(?\x8c\xab\
\xa6\xe7"\xaa]\xd8\x87\xca;.\xe2l\xb4\x84\xab5\xc5I\xd9\'\xd9\xeb\xedwY\n\
\xb0,i\x19\xc3z\xea\xd4\x82\xeb32F\xed\xd8\xb7\xef\xa3\x01[6o6\xd5\xc1Zu\xe5\
\xd0!\xa8\xa88\x82\x03\x9f|\x82\xeb\xe7\xde\x8a\xa8\xe3 z\xe8\x10H\xa9s\xf0\
\xcd\xb1"f\x11q\x1cNMHH\xef\xf1\x02,\x0b\x96\xd6BO\xceD\xf6\xd6\x8dwn\x9f\
\xe5\x7f<\xc5\xdb7\xce\xa4\r\x1b\xae\xae\x1c:\x04\xef\xec\xd8\x81\x8c\xeb\
\xc6\xe0\xb3\x83\x07QZ\\\x8c\xa9K\x97 \xea\xb8\x88\x94\xb5+\xa2i6Dp\xb4f\x01\
H\xdbu\xeb{\xb4\x80\x18\x1e:\'\xd3\x93\x1d(\x14E\xfd\xad\xf7\x92e\xc2\xcd\
\x945e\x91*?\xf49\xbe\xfc\xf2\x182\xc6\x8c\xc1\xa6-/#w\xcad|\xb4\x7f?\xde\
\x0e\x14a\xce\xb2\x07\x10q\x1c4\x1e,\x03+\xd5fC;Z\x93`\x96\x9a(\xf8TI\xc9\
\xdc\x1e;F\x9b\xf1\x933=Y\x81B\x0e\xf8\xfa\xe8~\xe4[i\x12\x12-\x19\r}\x86\
\xac\xaci\x88F\x1b\xf1\xde\xfb\xefc\xce\xcd~<\xb3f\r\xf2\xa6\xe7\xe2\xe4\xc9\
*\xdc\xf9\xd3\xdb1\xd8?\x1b\xbe\x19\xd3a\x87\xc2-\xc7\xaa\xa3\xb5\x01\xb3\
\x04s\xdd\xea\x9d;\xf3\x8b\x8f\x1f/\xed\x91\x02Zu>k[!\x8a|qn\x12%\xfc\x81d\
\xf2m\n\xeeI\xf4\xb1w\xc2\x84>\xc4\xbcyw\xc0\xb5#x\xe3\xcd\xb7\xf0\x8b{\xef\
\xc1\xefW\xae\xc2\x82y\xb7\xe2dU\x15\xe6\xdf2\x17isnA\xf2\xec\x99\xb0\xc3a8\
\xc6\x180+0\xd7>\xb1s\xe7\xac=\x95\x95\xfb\x94\x94V\x8f\xe0\x01 \'\xd3\x93\
\x15.\xf3\xd4\xf1\x11\xb0\xa9Zi\xd8\xfe\x949\xf4\n\xf3\xa9u\xcc\x95O2\x1d]\
\xce\x8d\'\xb6\xf1\x993\x86\x7f\xbdb\x19\xdf\xb6h!\xffk\xcbf\xee\xdf?\x99_|~\
=ggM\xe4\x19\xb9\xd3\xb81\x12\xe6O7\xbeh\xb6/X\xc0\xef.YR\x93\x9d\x966\x1e\
\x00\x94\x10=\x8e\xaf\xe7/\xdb\xe3\xd72W>\xc9\xfc\xd5\xa3\xcc\x15\xf70\x95\
\xcd\xe4P\xf9K\xdc\xd0`x\xd1\x82[\xf9\xa6I\xd9\xfc\xd2\x86\xf5\x9c\xe8\xf3\
\xf1\xc6\r\xcfqv\xd6D\xce\x9b6U7F\xc2\xfc\xbfM\x85u\x13\x86\x0e\x8d\xe1[u\
\xfe\x92]\xe6Z\xc7&P\x88\xed\xbe8\xb7\x1f\xf9V\x92L\xbaM\xc29\x04D\xeb\x01\'\
\x08\x98 \xe0\xd6\x00\\\x03T\x07\xc1\xdf|\x85\xd0\xb0\x87\x81Q+\xb0x\xfe,\
\xd4\x87\x1b\xb1\xecW\xbf\xc4\x03\xcb\x1f\xc6\xdf\xd6<K\xeb\x9f\x7fA\x0e\xbf\
bHX\x03\xb3_}\xfd\x8d\xd2\xe6\x0b\xe0\xa5r\xb7\xe0\x01 \'\xd3\x93\x1d.\xf3\
\xd4\xb7\xc4&\xda\xae\xf3\xc7~\xc3\\q\x0f\xf3\xe19\xcc%\x93\x98\xdf\xbc\x96\
\xf9\xd5T\xa6\r\xe0\xda=\xab\xb9\xbeA\xf3\xac\xbci<q\xc2x\xde\xb8\xe19=`@\n\
\xff\xfd/\x7f\xaeM\x1b<x\x12\xd0\xb6\xf3\xcd\xe3\xa2W\xa0\xa5\xf37z\xb2\x03\
\x9bPt\xde\xceS\x10\xa8\x0e\x02U5\x80\x1b\x04\xec:\x00\x1a\xdcH\xa8\x1b\xb9\
\x1aj\xe2*,\x9a3\xc3\xd4\x85\xc2\xea\xee\xa5w\xd6=\xf2\xe8o\xfd\x0c\xec\xd1\
\xaek\x11\xd19\x9d\xbf\xa8\xf7@\x9bs~\x13\x8a|}\xdc~\xe4{\x8cdr;\xbc\x0e\x02\
\xba#|\r\x00\x17\xd0\x80\xa8W\xf0\x1e{\x1f\x11HZ\xf4\xe8:\xb5\xaftg]\xe1\x96\
W\xf2\xc3\xe1\xf0\x07\xae\xebZ\xcc\xdcal.x\'\xb7:\xe7\xb3\xb7\x156\xe1\x13V\
\x92L^(aw\x15\xaf\x01\x17@\r\x03L`\x8f\xa4\xe4\x0fVK;\xdeSoT\xdf\x99\x95\x95\
\x95\xfbd,6\x9df\xfe\x82"t\xb6\xf3Vv\xa0P4\xe1\x1f#\x99\xb4P\xc2)\xef&\x1e\
\x00\x01\x0c\x10\x03R$\xc65,~\xd1\xf1o\xdd\x8b]J\t\xcb\x98\x8e;\xdf<\xba\xfd\
"\xeb\x14\x9f\xdc\x15\xfc\xe9\x0e\xf1\xd4\x8c\xf7\x89\xf0\xe2\xcd\xf0o\xdd+w\
YJ\x9e\x17\x0fts\x05\xce\xc6\xc6\x9a\xb4\xadP\x04b\x1b\xb6\to_X\xe7\t ) \xb9\
\x19_\xc2\xbb-\x05K\x9b\xcecsA\x05\xb4\xc27e^\x9f\xed\xfc\xf9\xf0\xfa4\x10\
\xad\xed\x18\xaf #R\x84\x97\xbe\x06\xffk\xa5\xdd\xc3w\xb9\x80V\xb1\x99\xd4\
\x14\x9b\xc4\xce\xf1A\x80j\xba\x86\xb7 \x1b\xb4\x08\x17\xac\x87\xbf\xb8\x82w\
{$,\x97\xba\x8e\x07\xbap\x8c\xb6\xc5#\xd0\xd2\xf9\x0e7l;\xbc{\x1a\xb0\xbf\
\x03oD\xd8\xbf\x0e\xfe]Gx\xb7Gu\x1f\x0f\x9cg\x05\xda\xe1\x8b|}t"%\xac"\x99\
\xb4\xe0<\xf8`S\xe6\xbf\x1b_\xb0\x16\xf9\xc5G\xb8\xc4\x92\xb0\xf4\x05\xe0\
\x81\xefX\x81\x0b\xc7\xd7t\t\xef_\x8b\xfc]\x17\x89\x07:9F/\x0e\xdfIl\xf8\xd2\
\xe3\x81\x0eV\xc0\xb2D\xc7\xf8\xe4\x8b\x8c\x8d\xe7\xd2\xe3\x81v{@IHC\xa0\xc9\
\x99jR\xec\xa84\x89\x94\xf08\xc9\xe4\xf9\xe79m\xba\x96y\xffZ\x91\xbf\xeb\x08\
]2|\x9b\x02\xa4\x84$\x02\xe7\x8c\xf3d\x07^B\xc0\xe7\xd5\xfd\xa8\xef\xefZ\xbd\
a\x1b\xda\xe1\x83@uM\xaf\xe2\xdb\x14 \x04\x84ey\xb8\xfc\xc0\xdb\x9f\xfch\xd4\
\xa0\xb1:\x14\xd2\x96w\xb8\x05\x13\x02"\x9f\x03\x912@\xd7\xc7\xce\xf5\xef\t\
\x1eh\xba\x8dJ)%\x11\xd1\x98\x9f\x8cN\x1f>r\xda\xb5\xe4F\xd9\x8aw\x14L\x1d \
\xfa\x01,\x01\xf7\x14`\x1a\xbb\x8b\x0f\xf9\xd7\n\x7fO\xe1\xcf) /oZ\xae\x10\
\x1cg\x9cj-\x15Y \'\x863\xe1\x18\x16\x8d\xed\xf05\x00L\xa7\xf8\x82\x1e\xc6\
\xb7\x14@D\x0c\x00\xb3fL\x9d\rD `\x006\x00;\x00\x14@Q\x80k\x81\xe0\x19\xe0T\
\x1d\xa0\xeb\x00\xa7\xfe\xbc\xf8\xe2\x1e\xc6\x03\x80%\x85\x10DdRS\x07%\x8e\
\xbfqL\x0et\x1d\xa4\xd0\n\xe4\x02d\x03\x88\x03\xa8\x11\xf8\xe6(p\xea\x0c\xe0\
V\x03v$\xb6{\xb8c|S\xe6K{\x1a\x1f+@JI\xc6\x98iS\xb2\'\xf8RRRM\xb8\x8a\x944\
\x12\xe4\x00\xacc\xab\xa0~\x00\x0c\x98\x07$\x85b\xb1a\r\xd4\x1f\x07\x0e|\x08\
\xe0\x9c\xce_6<\x00X\x10\xb1\x93(\x7f\xe6\x94\xd9\x80\x06\x93C\x80\x91`\x07 \
\x17`\x1b\xf0$\x03i\xb9\x00\xbb\x80\xb1\x01K\x01\'>\x06>\xfd\x10$\x05I\x8b/{\
\xe7[\n\xd0\xda\x18\x8f\xc7\x12S&]?\x03\xa6\x1eR\xb8\x12\xac\x11[\x01;6\x93\
\r\xb8vl\xa6(\xe0J\xc0\x84\x9b:\xcf\xbd\xd2\xf9\xe6!\x01\xf0\x84q\x19#\x86_s\
\xd5hj\xa8c\tW\xb6\xc5;\xb1\xce\xb3\x06\xa0c\x9b\x1b\x9a\r\x91\x8e]\x0fd\xa8\
`\xad\xc8/\xee\x05<\x00H)\x85\xa8<qr\xe6\xe7\x1f\x7f\xac\x10\x07\xa3\x9dh,\
\xf7-\xf8\xd8\xccd\x93qm\xa3\xdd\xa8ac\x0b\x95\xa8\xac\x06\x96\xa1\xd8\x95\
\xb8w\xf0\x00 \x85\x10|\xaa\xbav\xf6\xc1/\x1a!\x95WX\xf1\x00\xb9\x11\x80\x1d\
&c\x93v#\xda\xe8(\t\xa9\xa5JT\xcaJ\x89S\x02v\xe4`\xc5\xe9=\x05\xebd\x0c\xafz\
\x07\x0f\x00\x9614\xd0\xef\x9f=\xf1\xa6)\xd3\xb1\xe2\x91\'\xc4\xd2yW\x9b\xcc\
)\x19l\xaaOY\xaa\xaf\x142\xae\x8f\x84f\x84\xbe\xad;\xb1g\xff\xe1\xdd\xef\xec\
,{\xfb\xbf%_\x14\x1f(\xab:b\x88\xa0\x04dw>\xc3^\xf2\x11\x1f\xef\x9d\x1f\x08\
\x04\xcc\x8a\xe5\xcb5\x00N\x1d\x98\xc4\x9f\x95\xaea\x0e\xbf\xee\x96\x97>\xb5\
o\xfd3w=\xb5\xf0\x96\x1br\xaf\x18\x9c\x94\xd8\xeeQ!E\xf7\xbf\x96\xb9\xe4c\
\xc9\x1d\xb7\xbf\xf2\xe0\x83\x0f2\x00N\xf4\xc5\x7f\xeb\xf5z\xde\x1cv\xe5\x80\
\x07\xc6\xddx\xd5H\xcbj\xeb\x93R(KIKJ!\xcf\xfd\xddH/\x8d97\xe7\xef\x8f\xf3\
\xa8\x17\xfa%\xf6\x9d\x1b\xef\x8d\x1b\xe8\xf1\xb4\xfd\x8cc)iYJ\xaa\x8e~\xea\
\xf2}\x18\xff\x07\x143\xd2\x14\xd0v\x9e\xc4\x00\x00\x00\x00IEND\xaeB`\x82\
\x88b\xd9\xe8'
