from base64 import b64encode
from cStringIO import StringIO

import requests
from PIL import Image, ImageSequence, ImageDraw, ImageFont

from ... import config
from ..base import CommandBridle
from ...utils.images2gif import GifWriter


class GifReact(CommandBridle):

    class Meta(CommandBridle.Meta):
        command = 'gif'
        description = 'Get an animated reaction from giphy.com'
        help_text = ['Usage: `/horse gif <query>`']

    def search(self, operands):
        response = requests.get(
            'http://api.giphy.com/v1/gifs/search?q={0}&api_key={1}'.format(
                "+".join(operands),
                config.GIPHY_API_TOKEN
            )
        )

        results = response.json()
        return results

    def get_image(self, results, operands):
        return results['data'][0]['images']['fixed_height']['url']

    def execute(self, user, channel, operands):

        if len(operands) == 0:
            return 'Can\'t search for nothing, mate'

        results = self.search(operands)
        if len(results['data']) > 0:
            self.message(
                channel,
                self.get_image(results, operands),
                username=user.real_name if user.real_name else user.name,
                icon_url=user.image
            )
        else:
            return 'Sorry, found nothing :('


class MemeReact(GifReact):

    class Meta(CommandBridle.Meta):
        command = 'meme'
        description = 'Make a meme using images from giphy.com'
        help_text = ['Usage: `/horse meme <caption>`']

    def get_image(self, results, operands):
        orig = results['data'][0]['images']['fixed_height']['url']
        return self.make_meme(orig, " ".join(operands))

    def make_meme(self, original_image, caption, shrink=1):
        response = requests.get(original_image)
        pil_img = Image.open(StringIO(response.content))
        duration = pil_img.info['duration'] / 1000.0

        frames = []
        for frame in ImageSequence.Iterator(pil_img):
            frames.append(frame.copy())

        gf = GifWriter()
        images = gf.convertImagesToPIL(frames, False, 0)

        durations = []
        xys = []
        disposes = []
        for im in images:
            durations.append(duration)
            xys.append((0, 0))
            disposes.append(2)

            width, height = im.size
            if shrink != 1:
                im.thumbnail(
                    (width * shrink, height * shrink),
                    Image.ANTIALIAS
                )
                width, height = im.size
            draw = ImageDraw.Draw(im)

            text_width = 99999
            font_size = 33
            while text_width > width * 0.8:
                font_size -= 1
                font = ImageFont.truetype('assets/fonts/impact.ttf', font_size)
                text_width, text_height = draw.textsize(
                    caption.upper(),
                    font=font
                )

            # horrible outline hack
            draw.text(
                ((width - text_width) / 2 + 2, height - text_height * 1.6),
                caption.upper(),
                font=font,
                fill=255
            )
            draw.text(
                ((width - text_width) / 2 - 2, height - text_height * 1.6),
                caption.upper(),
                font=font,
                fill=255
            )
            draw.text(
                ((width - text_width) / 2, height - text_height * 1.6 + 2),
                caption.upper(),
                font=font,
                fill=255
            )
            draw.text(
                ((width - text_width) / 2, height - text_height * 1.6 - 2),
                caption.upper(),
                font=font,
                fill=255
            )
            draw.text(
                ((width - text_width) / 2, height - text_height * 1.6),
                caption.upper(),
                font=font
            )

        fp = StringIO()
        gf.writeGifToFile(fp, images, durations, 0, xys, disposes)
        filesize = fp.tell()
        if filesize > 2097152:
            return self.make_meme(original_image, caption, shrink * 0.8)

        fp.seek(0)
        image = b64encode(fp.read())
        payload = {
            'album_id': None,
            'image': image,
            'title': "Autogenerated Giphy Meme \"{0}\"".format(caption),
            'description': None
        }

        resp = requests.post(
            "https://api.imgur.com/3/image",
            data=payload,
            headers={
                "Authorization": "Client-ID c3bb952a0a07527"
            }
        )
        return resp.json()['data']['link']
