// Copyright 2017 Alejandro Sirgo Rica
//
// This file is part of Flameshot.
//
//     Flameshot 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.
//
//     Flameshot 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 Flameshot.  If not, see .
#include "capturebutton.h"
#include "src/capture/widget/capturewidget.h"
#include "src/utils/confighandler.h"
#include "src/capture/tools/capturetool.h"
#include "src/capture/tools/toolfactory.h"
#include 
#include 
#include 
#include 
#include 
// Button represents a single button of the capture widget, it can enable
// multiple functionality.
namespace {
const int BUTTON_SIZE = 30;
qreal getColorLuma(const QColor &c) {
    return 0.30 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF();
}
QColor getContrastColor(const QColor &c) {
    bool isWhite = CaptureButton::iconIsWhiteByColor(c);
    int change = isWhite ? 30 : -45;
    return QColor(qBound(0, c.red() + change, 255),
                  qBound(0, c.green() + change, 255),
                  qBound(0, c.blue() + change, 255));
}
} // unnamed namespace
CaptureButton::CaptureButton(const ButtonType t, QWidget *parent) : QPushButton(parent),
    m_buttonType(t)
{
    initButton();
    if (t == TYPE_SELECTIONINDICATOR) {
        QFont f = this->font();
        setFont(QFont(f.family(), 7, QFont::Bold));
    } else {
        setIcon(icon());
    }
    setCursor(Qt::ArrowCursor);
}
void CaptureButton::initButton() {
    m_tool = ToolFactory().CreateTool(m_buttonType, this);
    connect(this, &CaptureButton::pressed, m_tool, &CaptureTool::onPressed);
    setFocusPolicy(Qt::NoFocus);
    resize(BUTTON_SIZE, BUTTON_SIZE);
    setMask(QRegion(QRect(-1,-1,BUTTON_SIZE+2, BUTTON_SIZE+2), QRegion::Ellipse));
    setToolTip(m_tool->description());
    m_emergeAnimation = new  QPropertyAnimation(this, "size", this);
    m_emergeAnimation->setEasingCurve(QEasingCurve::InOutQuad);
    m_emergeAnimation->setDuration(80);
    m_emergeAnimation->setStartValue(QSize(0, 0));
    m_emergeAnimation->setEndValue(QSize(BUTTON_SIZE, BUTTON_SIZE));
    auto dsEffect = new QGraphicsDropShadowEffect(this);
    dsEffect->setBlurRadius(5);
    dsEffect->setOffset(0);
    dsEffect->setColor(QColor(Qt::black));
    setGraphicsEffect(dsEffect);
}
QVector CaptureButton::getIterableButtonTypes() {
    return iterableButtonTypes;
}
QString CaptureButton::globalStyleSheet() {
    QColor mainColor = ConfigHandler().uiMainColorValue();
    QString baseSheet = "CaptureButton { border-radius: %3;"
                        "background-color: %1; color: %4 }"
                        "CaptureButton:hover { background-color: %2; }"
                        "CaptureButton:pressed:!hover { "
                        "background-color: %1; }";
    // define color when mouse is hovering
    QColor contrast = getContrastColor(m_mainColor);
    // foreground color
    QString color = iconIsWhiteByColor(mainColor) ? "white" : "black";
    return baseSheet.arg(mainColor.name()).arg(contrast.name())
            .arg(BUTTON_SIZE/2).arg(color);
}
QString CaptureButton::styleSheet() const {
    QString baseSheet = "CaptureButton { border-radius: %3;"
                        "background-color: %1; color: %4 }"
                        "CaptureButton:hover { background-color: %2; }"
                        "CaptureButton:pressed:!hover { "
                        "background-color: %1; }";
    // define color when mouse is hovering
    QColor contrast = getContrastColor(m_mainColor);
    // foreground color
    QString color = iconIsWhiteByColor(m_mainColor) ? "white" : "black";
    return baseSheet.arg(m_mainColor.name()).arg(contrast.name())
            .arg(BUTTON_SIZE/2).arg(color);
}
// get icon returns the icon for the type of button
QIcon CaptureButton::icon() const {
    QString color(iconIsWhiteByColor(m_mainColor) ? "White" : "Black");
    QString iconPath = QString(":/img/buttonIcons%1/%2")
            .arg(color).arg(m_tool->iconName());
    return QIcon(iconPath);
}
void CaptureButton::mousePressEvent(QMouseEvent *e) {
    if (e->button() == Qt::LeftButton) {
        Q_EMIT pressedButton(this);
        Q_EMIT pressed();
    }
}
void CaptureButton::animatedShow() {
    if(!isVisible()) {
        show();
        m_emergeAnimation->start();
        connect(m_emergeAnimation, &QPropertyAnimation::finished, this, [this](){
        });
    }
}
CaptureButton::ButtonType CaptureButton::buttonType() const {
    return m_buttonType;
}
CaptureTool *CaptureButton::tool() const {
    return m_tool;
}
void CaptureButton::setColor(const QColor &c) {
    m_mainColor = c;
    setStyleSheet(styleSheet());
    setIcon(icon());
}
// getButtonBaseSize returns the base size of the buttons
size_t CaptureButton::buttonBaseSize() {
    return BUTTON_SIZE;
}
bool CaptureButton::iconIsWhiteByColor(const QColor &c) {
    bool isWhite = false;
    if (getColorLuma(c) <= 0.60) {
        isWhite = true;
    }
    return isWhite;
}
QColor CaptureButton::m_mainColor = ConfigHandler().uiMainColorValue();
QVector CaptureButton::iterableButtonTypes = {
    CaptureButton::TYPE_PENCIL,
    CaptureButton::TYPE_LINE,
    CaptureButton::TYPE_ARROW,
    CaptureButton::TYPE_SELECTION,
    CaptureButton::TYPE_RECTANGLE,
    CaptureButton::TYPE_CIRCLE,
    CaptureButton::TYPE_MARKER,
    CaptureButton::TYPE_SELECTIONINDICATOR,
    CaptureButton::TYPE_MOVESELECTION,
    CaptureButton::TYPE_UNDO,
    CaptureButton::TYPE_COPY,
    CaptureButton::TYPE_SAVE,
    CaptureButton::TYPE_EXIT,
    CaptureButton::TYPE_IMAGEUPLOADER,
};