#include "qtmaterialavatar.h"
#include "qtmaterialavatar_p.h"
#include <QPainter>
#include <QPainterPath>
#include "lib/qtmaterialstyle.h"

/*!
 *  \class QtMaterialAvatarPrivate
 *  \internal
 */

/*!
 *  \internal
 */
QtMaterialAvatarPrivate::QtMaterialAvatarPrivate(QtMaterialAvatar *q)
    : q_ptr(q)
{
}

/*!
 *  \internal
 */
QtMaterialAvatarPrivate::~QtMaterialAvatarPrivate()
{
}

/*!
 *  \internal
 */
void QtMaterialAvatarPrivate::init()
{
    Q_Q(QtMaterialAvatar);

    size           = 40;
    type           = Material::LetterAvatar;
    useThemeColors = true;

    QFont font(q->font());
    font.setPointSizeF(16);
    q->setFont(font);

    QSizePolicy policy(QSizePolicy::MinimumExpanding,
                       QSizePolicy::MinimumExpanding);
    q->setSizePolicy(policy);
}

/*!
 *  \class QtMaterialAvatar
 */

QtMaterialAvatar::QtMaterialAvatar(QWidget *parent)
    : QWidget(parent),
      d_ptr(new QtMaterialAvatarPrivate(this))
{
    d_func()->init();
}

QtMaterialAvatar::QtMaterialAvatar(const QIcon &icon, QWidget *parent)
    : QWidget(parent),
      d_ptr(new QtMaterialAvatarPrivate(this))
{
    d_func()->init();

    setIcon(icon);
}

QtMaterialAvatar::QtMaterialAvatar(const QChar &letter, QWidget *parent)
    : QWidget(parent),
      d_ptr(new QtMaterialAvatarPrivate(this))
{
    d_func()->init();

    setLetter(letter);
}

QtMaterialAvatar::QtMaterialAvatar(const QImage &image, QWidget *parent)
    : QWidget(parent),
      d_ptr(new QtMaterialAvatarPrivate(this))
{
    d_func()->init();

    setImage(image);
}

QtMaterialAvatar::~QtMaterialAvatar()
{
}

void QtMaterialAvatar::setUseThemeColors(bool value)
{
    Q_D(QtMaterialAvatar);

    if (d->useThemeColors == value) {
        return;
    }

    d->useThemeColors = value;
    update();
}

bool QtMaterialAvatar::useThemeColors() const
{
    Q_D(const QtMaterialAvatar);

    return d->useThemeColors;
}

void QtMaterialAvatar::setTextColor(const QColor &color)
{
    Q_D(QtMaterialAvatar);

    d->textColor = color;

    MATERIAL_DISABLE_THEME_COLORS
    update();
}

QColor QtMaterialAvatar::textColor() const
{
    Q_D(const QtMaterialAvatar);

    if (d->useThemeColors || !d->textColor.isValid()) {
        return QtMaterialStyle::instance().themeColor("canvas");
    } else {
        return d->textColor;
    }
}

void QtMaterialAvatar::setBackgroundColor(const QColor &color)
{
    Q_D(QtMaterialAvatar);

    d->backgroundColor = color;
    
    MATERIAL_DISABLE_THEME_COLORS
    update();
}

QColor QtMaterialAvatar::backgroundColor() const
{
    Q_D(const QtMaterialAvatar);

    if (d->useThemeColors || !d->backgroundColor.isValid()) {
        return QtMaterialStyle::instance().themeColor("primary1");
    } else {
        return d->backgroundColor;
    }
}

/*!
 *  \reimp
 */
QSize QtMaterialAvatar::sizeHint() const
{
    Q_D(const QtMaterialAvatar);

    return QSize(d->size+2, d->size+2);
}

void QtMaterialAvatar::setSize(int size)
{
    Q_D(QtMaterialAvatar);

    d->size = size;

    if (!d->image.isNull()) {
        d->pixmap = QPixmap::fromImage(d->image.scaled(d->size, d->size,
                                                       Qt::IgnoreAspectRatio,
                                                       Qt::SmoothTransformation));
    }

    QFont f(font());
    f.setPointSizeF(size*16/40);
    setFont(f);

    update();
}

int QtMaterialAvatar::size() const
{
    Q_D(const QtMaterialAvatar);

    return d->size;
}

void QtMaterialAvatar::setLetter(const QChar &letter)
{
    Q_D(QtMaterialAvatar);

    d->letter = letter;
    d->type = Material::LetterAvatar;
    update();
}

void QtMaterialAvatar::setImage(const QImage &image)
{
    Q_D(QtMaterialAvatar);

    d->image = image;
    d->type = Material::ImageAvatar;

    d->pixmap = QPixmap::fromImage(image.scaled(d->size, d->size,
                                                Qt::IgnoreAspectRatio,
                                                Qt::SmoothTransformation));
    update();
}

void QtMaterialAvatar::setIcon(const QIcon &icon)
{
    Q_D(QtMaterialAvatar);

    d->icon = icon;
    d->type = Material::IconAvatar;
    update();
}

Material::AvatarType QtMaterialAvatar::type() const
{
    Q_D(const QtMaterialAvatar);

    return d->type;
}

/*!
 *  \reimp
 */
void QtMaterialAvatar::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    Q_D(QtMaterialAvatar);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    QRect r = rect();
    const qreal hs = d->size/2;

    if (!isEnabled())
    {
        QBrush brush;
        brush.setStyle(Qt::SolidPattern);
        brush.setColor(QtMaterialStyle::instance().themeColor("disabled"));
        painter.setPen(Qt::NoPen);
        painter.setBrush(brush);
        painter.drawEllipse(QRectF((width()-d->size)/2, (height()-d->size)/2,
                                   d->size, d->size));
        return;
    }

    if (Material::ImageAvatar != d->type)
    {
        QBrush brush;
        brush.setStyle(Qt::SolidPattern);
        brush.setColor(backgroundColor());
        painter.setPen(Qt::NoPen);
        painter.setBrush(brush);
        painter.drawEllipse(QRectF((width()-d->size)/2, (height()-d->size)/2,
                                   d->size, d->size));
    }

    switch (d->type)
    {
    case Material::ImageAvatar:
    {
        QPainterPath path;
        path.addEllipse(width()/2-hs, height()/2-hs, d->size, d->size);
        painter.setClipPath(path);

        painter.drawPixmap(QRect(width()/2-hs, height()/2-hs, d->size, d->size),
                           d->pixmap);
        break;
    }
    case Material::IconAvatar:
    {
        QRect iconGeometry((width()-hs)/2, (height()-hs)/2, hs, hs);
        QPixmap pixmap = d->icon.pixmap(hs, hs);
        QPainter icon(&pixmap);
        icon.setCompositionMode(QPainter::CompositionMode_SourceIn);
        icon.fillRect(pixmap.rect(), textColor());
        painter.drawPixmap(iconGeometry, pixmap);
        break;
    }
    case Material::LetterAvatar:
    {
        painter.setPen(textColor());
        painter.setBrush(Qt::NoBrush);
        painter.drawText(r, Qt::AlignCenter, QString(d->letter));
        break;
    }
    default:
        break;
    }
}
