/*
 *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
 *  Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
 *
 *  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, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */
#import "ImageManipulationDelegate.h"

#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>

//Qt
#import <QSize>
#import <QBuffer>
#import <QtGui/QColor>
#import <QtGui/QPainter>
#import <QHash>
#import <QtGui/QBitmap>
#import <QtWidgets/QApplication>
#import <QtGui/QImage>
#import <QtMacExtras/qmacfunctions.h>
#import <QtGui/QPalette>

//LRC
#import <api/conversation.h>
#import <api/account.h>
#import <api/contactmodel.h>
#import <api/contact.h>
#import <api/profile.h>

namespace Interfaces {

    // Colors from material.io
    const QColor ImageManipulationDelegate::avatarColors_[] = {
        {"#fff44336"}, //Red
        {"#ffe91e63"}, //Pink
        {"#ff9c27b0"}, //Purple
        {"#ff673ab7"}, //Deep Purple
        {"#ff3f51b5"}, //Indigo
        {"#ff2196f3"}, //Blue
        {"#ff00bcd4"}, //Cyan
        {"#ff009688"}, //Teal
        {"#ff4caf50"}, //Green
        {"#ff8bc34a"}, //Light Green
        {"#ff9e9e9e"}, //Grey
        {"#ffcddc39"}, //Lime
        {"#ffffc107"}, //Amber
        {"#ffff5722"}, //Deep Orange
        {"#ff795548"}, //Brown
        {"#ff607d8b"}  //Blue Grey
    };

    ImageManipulationDelegate::ImageManipulationDelegate() {}

    QPixmap
    ImageManipulationDelegate::crop(QPixmap& photo, const QSize& destSize)
    {
        auto initSize = photo.size();
        float leftDelta = 0;
        float topDelta = 0;

        if (destSize.height() == initSize.height()) {
            leftDelta = (destSize.width() - initSize.width()) / 2;
        } else {
            topDelta = (destSize.height() - initSize.height()) / 2;
        }

        float xScale = (float)destSize.width()  / initSize.width();
        float yScale = (float)destSize.height() / initSize.height();

        QRectF destRect(leftDelta, topDelta,
                            initSize.width() - leftDelta, initSize.height() - topDelta);

        destRect.setLeft(leftDelta * xScale);
        destRect.setTop(topDelta * yScale);

        destRect.setWidth((initSize.width() - leftDelta) * xScale);
        destRect.setHeight((initSize.height() - topDelta) * yScale);

        return photo.copy(destRect.toRect());
    }

    QVariant ImageManipulationDelegate::personPhoto(const QByteArray& data, const QString& type)
    {
        QImage image;
        //For now, ENCODING is only base64 and image type PNG or JPG
        const bool ret = image.loadFromData(QByteArray::fromBase64(data),type.toLatin1());
        if (!ret) {
            qDebug() << "vCard image loading failed";
            return QVariant();
        }

        return QPixmap::fromImage(image);
    }

    char letterForDefaultUserPixmap(const lrc::api::contact::Info& contact)
    {
        if (!contact.profileInfo.alias.empty()) {
            return std::toupper(contact.profileInfo.alias.at(0));
        } else if((contact.profileInfo.type == lrc::api::profile::Type::RING ||
                contact.profileInfo.type == lrc::api::profile::Type::PENDING) &&
                  !contact.registeredName.empty()) {
            return std::toupper(contact.registeredName.at(0));
        } else {
            return std::toupper(contact.profileInfo.uri.at(0));
        }
    }

    QVariant ImageManipulationDelegate::conversationPhoto(const lrc::api::conversation::Info& conversation,
                                                          const lrc::api::account::Info& accountInfo,
                                                          const QSize& size,
                                                          bool displayPresence)
    {
        Q_UNUSED(displayPresence)

        try {
            auto contact = accountInfo.contactModel->getContact(conversation.participants[0]);
            auto& avatar = contact.profileInfo.avatar;
            if (!avatar.empty()) {
                QPixmap pxm;
                const int radius = size.height() / 2;

                /*
                 * we could not now clear cache and image coul be outdated
                 * so do not use cache now
                // Check cache
                auto index = QStringLiteral("%1%2%3").arg(size.width())
                .arg(size.height())
                .arg(QString::fromStdString(conversation.uid));

                if (convPixmCache.contains(index)) {
                    return convPixmCache.value(index);
                }
                */

                auto contactPhoto = qvariant_cast<QPixmap>(personPhoto(QByteArray::fromStdString(avatar)));
                contactPhoto = contactPhoto.scaled(size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);

                QPixmap finalImg;
                // We crop the avatar if picture is not squared as scaled() keep ratio of original picture
                if (contactPhoto.size() != size) {
                    finalImg = crop(contactPhoto, size);
                } else
                    finalImg = contactPhoto;

                // Creating clean QPixmap
                pxm = QPixmap(size);
                pxm.fill(Qt::transparent);

                //Add corner radius to the Pixmap
                QPainter painter(&pxm);
                painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
                painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
                QRect pxRect = finalImg.rect();
                QBitmap mask(pxRect.size());
                QPainter customPainter(&mask);
                customPainter.setRenderHints (QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
                customPainter.fillRect       (pxRect                , Qt::white );
                customPainter.setBackground  (Qt::black                         );
                customPainter.setBrush       (Qt::black                         );
                customPainter.drawRoundedRect(pxRect,radius,radius              );
                finalImg.setMask             (mask                              );
                painter.drawPixmap           (0,0,finalImg                      );
                painter.setBrush             (Qt::NoBrush                       );
                painter.setPen               (Qt::transparent                   );
                painter.setCompositionMode   (QPainter::CompositionMode_SourceIn);
                painter.drawRoundedRect(0,0,pxm.height(),pxm.height(),radius,radius);

                // Save in cache
                //convPixmCache.insert(index, pxm);

                return pxm;
            } else {
                char color = contact.profileInfo.uri.at(0);
                contact.profileInfo.alias.erase(std::remove(contact.profileInfo.alias.begin(), contact.profileInfo.alias.end(), '\n'), contact.profileInfo.alias.end());
                contact.profileInfo.alias.erase(std::remove(contact.profileInfo.alias.begin(), contact.profileInfo.alias.end(), ' '), contact.profileInfo.alias.end());
                contact.profileInfo.alias.erase(std::remove(contact.profileInfo.alias.begin(), contact.profileInfo.alias.end(), '\r'), contact.profileInfo.alias.end());

                if (!contact.profileInfo.alias.empty()) {
                    return drawDefaultUserPixmap(size, color, std::toupper(contact.profileInfo.alias.at(0)));
                } else if((contact.profileInfo.type == lrc::api::profile::Type::RING ||
                           contact.profileInfo.type == lrc::api::profile::Type::PENDING) &&
                          !contact.registeredName.empty()) {
                    contact.registeredName.erase(std::remove(contact.registeredName.begin(), contact.registeredName.end(), '\n'), contact.registeredName.end());
                    contact.registeredName.erase(std::remove(contact.registeredName.begin(), contact.registeredName.end(), ' '), contact.registeredName.end());
                    contact.registeredName.erase(std::remove(contact.registeredName.begin(), contact.registeredName.end(), '\r'), contact.registeredName.end());
                    if(!contact.registeredName.empty()) {
                        return drawDefaultUserPixmap(size, color, std::toupper(contact.registeredName.at(0)));
                    } else {
                        return drawDefaultUserPixmapUriOnly(size, color);
                    }
                } else {
                    return drawDefaultUserPixmapUriOnly(size, color);
                }
            }
        } catch (const std::out_of_range& e) {
            return QVariant();
        }
    }

    QByteArray ImageManipulationDelegate::toByteArray(const QVariant& pxm)
    {
        //Preparation of our QPixmap
        QByteArray bArray;
        QBuffer buffer(&bArray);
        buffer.open(QIODevice::WriteOnly);

        //PNG ?
        (qvariant_cast<QPixmap>(pxm)).scaled({100,100}).save(&buffer, "PNG");
        buffer.close();

        return bArray;
    }

    QPixmap ImageManipulationDelegate::drawDefaultUserPixmap(const QSize& size,  const char color, const char letter) {
        // We start with a transparent avatar
        QPixmap avatar(size);
        avatar.fill(Qt::transparent);

        // We pick a color based on the passed character
        QColor avColor = ImageManipulationDelegate::avatarColors_[color % 16];

        // We draw a circle with this color
        QPainter painter(&avatar);
        painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
        painter.setPen(Qt::transparent);
        painter.setBrush(avColor);
        painter.drawEllipse(avatar.rect());

        // Then we paint a letter in the circle
        auto font = painter.font();
        font.setPointSize(avatar.height()/2);
        painter.setFont(font);
        painter.setPen(Qt::white);
        QRect textRect = avatar.rect();
        painter.drawText(textRect, QString(letter), QTextOption(Qt::AlignCenter));

        return avatar;
    }

    QPixmap ImageManipulationDelegate::drawDefaultUserPixmapUriOnly(const QSize& size,  const char color) {
        // We start with a transparent avatar
        QPixmap avatar(size);
        avatar.fill(Qt::transparent);

        // We pick a color based on the passed character
        QColor avColor = ImageManipulationDelegate::avatarColors_[color % 16];

        // We draw a circle with this color
        QPainter painter(&avatar);
        painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
        painter.setPen(Qt::transparent);
        painter.setBrush(avColor);
        painter.drawEllipse(avatar.rect());

        // Then we paint the avatar in the circle
        QRect textRect = avatar.rect();
        QImage defaultAvatarImage;
        QRect rect = QRect(0, 0, size.width(), size.height());
        NSURL *bundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
        NSString *imagePath = [bundleURL.absoluteString stringByAppendingString:@"Contents/Resources/default_avatar_overlay.png"];
        if (defaultAvatarImage.load(QString::fromNSString(imagePath).mid(7))) {
            painter.drawImage(avatar.rect(), defaultAvatarImage);
        } else {
            painter.drawText(avatar.rect(), QString('?'), QTextOption(Qt::AlignCenter));
        }

        return avatar;
    }

    CGImageRef ImageManipulationDelegate::resizeCGImage(CGImageRef image, const QSize& size) {
        // create context, keeping original image properties
        CGContextRef context = CGBitmapContextCreate(NULL, size.width(), size.height(),
                                                     CGImageGetBitsPerComponent(image),
                                                     CGImageGetBytesPerRow(image),
                                                     CGImageGetColorSpace(image),
                                                     kCGImageAlphaPremultipliedLast);

        if(context == NULL)
            return nil;

        // draw image to context (resizing it)
        CGContextDrawImage(context, CGRectMake(0, 0, size.width(), size.height()), image);
        // extract resulting image from context
        CGImageRef imgRef = CGBitmapContextCreateImage(context);
        CGContextRelease(context);

        return imgRef;
    }

    QVariant
    ImageManipulationDelegate::numberCategoryIcon(const QVariant& p, const QSize& size, bool displayPresence, bool isPresent)
    {
        Q_UNUSED(p)
        Q_UNUSED(size)
        Q_UNUSED(displayPresence)
        Q_UNUSED(isPresent)
        return QVariant();
    }

    QVariant
    ImageManipulationDelegate::userActionIcon(const UserActionElement& state) const
    {
        Q_UNUSED(state)
        return QVariant();
    }

    QVariant ImageManipulationDelegate::decorationRole(const QModelIndex& index)
    {
        Q_UNUSED(index)
        return QVariant();
    }
} // namespace Interfaces
