/*
* Copyright (C) 2024, KylinSoft Co., Ltd.
 *
 * 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 <https://www.gnu.org/licenses/>.
 *
 * Authors: amingamingaming <wangyiming01@kylinos.cn>
 *
 */

#include "gradient-color.h"
#include <QtMath>
#include <QPoint>
namespace UkuiQuick {

GradientColor::GradientColor()
{
    m_gradientDeg = 0;
    m_gradientStart = QColor(0,0,0,0);
    m_gradientEnd = QColor(0,0,0,0);
    m_gradientBacrground = QColor(0,0,0,0);
    m_pureColor = QColor(0,0,0,0);
    m_colorType = DtColorType::Type::Pure;
}

GradientColor::GradientColor(QColor pure)
{
    m_gradientDeg = 0;
    m_gradientStart = QColor(0,0,0,0);
    m_gradientEnd = QColor(0,0,0,0);
    m_gradientBacrground = QColor(0,0,0,0);
    m_pureColor = pure;
    m_colorType = DtColorType::Type::Pure;
}

GradientColor::GradientColor(int deg, QColor start, QColor end, QColor background)
{
    m_gradientDeg = deg;
    m_gradientStart = start;
    m_gradientEnd = end;
    m_gradientBacrground = background;
    m_colorType = DtColorType::Type::Gradient;
}

GradientColor::GradientColor(const GradientColor &color)
{
    m_gradientDeg = color.gradientDeg();
    m_gradientStart = color.gradientStart();
    m_gradientEnd = color.gradientEnd();
    m_gradientBacrground = color.gradientBackground();
    m_pureColor = color.pureColor();
    m_colorType = color.colorType();
}

GradientColor &GradientColor::operator= (const GradientColor &color)
{
    m_gradientDeg = color.gradientDeg();
    m_gradientStart = color.gradientStart();
    m_gradientEnd = color.gradientEnd();
    m_gradientBacrground = color.gradientBackground();
    m_pureColor = color.pureColor();
    m_colorType = color.colorType();
    return *this;
}

bool GradientColor::operator!= (GradientColor *color)
{
    if(color == nullptr) {
        return true;
    }
    if(m_colorType != color->colorType()) {
        return true;
    }
    if(m_colorType == DtColorType::Pure && m_pureColor == color->pureColor()) {
        return false;
    }
    if(m_colorType == DtColorType::Gradient && m_gradientDeg == color->gradientDeg() && m_gradientStart == color->gradientStart() &&
       m_gradientEnd == color->gradientEnd() && m_gradientBacrground == color->gradientBackground()) {
        return false;
    }
    return true;
}

bool GradientColor::operator!= (QColor color)
{
    if(m_colorType == DtColorType::Gradient) {
        return true;
    }
    if(m_pureColor == color) {
        return false;
    }
    return true;
}

QColor GradientColor::gradientStart() const
{
    return m_gradientStart;
};

QColor GradientColor::gradientEnd() const
{
    return m_gradientEnd;
};

QColor GradientColor::gradientBackground() const
{
    return m_gradientBacrground;
};

int GradientColor::gradientDeg() const
{
    return m_gradientDeg;
};

QColor GradientColor::pureColor() const
{
    return m_pureColor;
}

DtColorType::Type GradientColor::colorType() const
{
    return m_colorType;
}

void GradientColor::setGradientStart(QColor start)
{
    if(m_gradientStart != start) {
        m_gradientStart = start;
        Q_EMIT gradientStartChanged();
    }
}

void GradientColor::setGradientEnd(QColor end)
{
    if(m_gradientEnd != end) {
        m_gradientEnd = end;
        Q_EMIT gradientEndChanged();
    }
}

void GradientColor::setGradientBackground(QColor background)
{
    if(m_gradientBacrground != background) {
        m_gradientBacrground = background;
        Q_EMIT gradientBackgroundChanged();
    }
}

void GradientColor::setGradientDeg(int deg)
{
    if(m_gradientDeg != deg) {
        m_gradientDeg = deg;
        Q_EMIT gradientDegChanged();
    }
}

void GradientColor::setPureColor(QColor color)
{
    if(m_pureColor != color) {
        m_pureColor = color;
        Q_EMIT pureColorChanged();
    }
}

void GradientColor::setColorType(UkuiQuick::DtColorType::Type type)
{
    if(m_colorType != type) {
        m_colorType = type;
        Q_EMIT colorTypeChanged();
    }
}

QColor GradientColor::setAlphaF(QColor color, qreal alpha)
{
    color.setAlphaF(color.alphaF() * alpha > 1? 1 : color.alphaF() * alpha);
    return color;
}

QColor GradientColor::mixBackGroundColor(const QColor &color, const QColor &back, const qreal &alpha)
{
    if(color.alpha() == 0) {
        return back;
    }
    if(back.alpha() == 0) {
        return color;
    }

    qreal a = color.alphaF() + (1 - color.alphaF()) * back.alphaF();
    if(a == 0) {
        return QColor(0, 0, 0, 0);
    }
    qreal r = (color.red() * color.alphaF() * (1 - back.alphaF()) + back.red() * back.alphaF()) / a;
    qreal g = (color.green() * color.alphaF() * (1 - back.alphaF()) + back.green() * back.alphaF()) / a;
    qreal b = (color.blue() * color.alphaF() * (1 - back.alphaF()) + back.blue() * back.alphaF()) / a;
    a = a * alpha;
    return QColor(qRound(r), qRound(g), qRound(b), qRound(a > 1 ? 255 : a * 255));
}

QPoint GradientColor::getGradientStartPoint(int deg, int width, int height)
{
    int x = (0.5 - 0.5 * qCos(deg * M_PI / 180)) * width;
    int y = (0.5 - 0.5 * qSin(deg * M_PI / 180)) * height;
    return QPoint(x, y);
}

QPoint GradientColor::getGradientEndPoint(int deg, int width, int height)
{
    int x = (0.5 + 0.5 * qCos(deg * M_PI / 180)) * width;
    int y = (0.5 + 0.5 * qSin(deg * M_PI / 180)) * height;
    return QPoint(x, y);
}
}
