/*
* Copyright (C) 2025, 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 "shadow-data.h"
namespace UkuiQuick {

ShadowData::ShadowData(QObject* parent): QObject(parent)
{
}

ShadowData::~ShadowData()
{
    if(m_childShadow) {
        delete m_childShadow;
        m_childShadow = nullptr;
    }
}

ShadowData::ShadowData(int x, int y, int blurRadius, int spread, const QColor&color, bool isMulti, ShadowData* child,
                       QObject* parent)
    : QObject(parent)
      , m_xOffset(x)
      , m_yOffset(y)
      , m_blurRadius(blurRadius)
      , m_spread(spread)
      , m_color(color)
      , m_isMultiShadow(isMulti)
{
    setChildShadow(child);
}

ShadowData::ShadowData(const ShadowData &shadow)
{
    m_xOffset = shadow.xOffset();
    m_yOffset = shadow.yOffset();
    m_blurRadius = shadow.blurRadius();
    m_spread = shadow.spread();
    m_color = shadow.shadowColor();
    m_isMultiShadow = shadow.isMultiShadow();
    setChildShadow(shadow.childShadow());
}

ShadowData &ShadowData::operator=(const ShadowData &shadow)
{
    m_xOffset = shadow.xOffset();
    m_yOffset = shadow.yOffset();
    m_blurRadius = shadow.blurRadius();
    m_spread = shadow.spread();
    m_color = shadow.shadowColor();
    m_isMultiShadow = shadow.isMultiShadow();
    setChildShadow(shadow.childShadow());
    return *this;
}

bool ShadowData::operator!=(const ShadowData &shadow)
{
    if(m_xOffset == shadow.xOffset() &&
        m_yOffset == shadow.yOffset()&&
        m_blurRadius == shadow.blurRadius() &&
        m_spread == shadow.spread() &&
        m_color == shadow.shadowColor() &&
        m_isMultiShadow == shadow.isMultiShadow()) {
        if (m_isMultiShadow && m_childShadow && shadow.childShadow()){
            return *m_childShadow != *shadow.childShadow();
        }
        return false;
    }
    return true;
}

void ShadowData::setXOffset(int x)
{
    if(m_xOffset != x) {
        m_xOffset = x;
        Q_EMIT xOffsetChanged();
    }
}

void ShadowData::setYOffset(int y)
{
    if(m_yOffset != y) {
        m_yOffset = y;
        Q_EMIT yOffsetChanged();
    }
}

void ShadowData::setBlurRadius(int radius)
{
    if(m_blurRadius != radius) {
        m_blurRadius = radius;
        Q_EMIT blurRadiusChanged();
    }
}

void ShadowData::setSpread(int spread)
{
    if(m_spread != spread) {
        m_spread = spread;
        Q_EMIT spreadChanged();
    }
}

void ShadowData::setShadowColor(const QColor &color)
{
    if(m_color != color) {
        m_color = color;
        Q_EMIT shadowColorChanged();
    }
}

void ShadowData::setIsMultiShadow(bool isMultiShadow)
{
    if(m_isMultiShadow != isMultiShadow) {
        m_isMultiShadow = isMultiShadow;
        Q_EMIT isMultiShadowChanged();
    }
}

void ShadowData::setChildShadow(ShadowData *child)
{
    if(child && m_childShadow && child != m_childShadow) {
        m_childShadow->setXOffset(child->xOffset());
        m_childShadow->setYOffset(child->yOffset());
        m_childShadow->setBlurRadius(child->blurRadius());
        m_childShadow->setSpread(child->spread());
        m_childShadow->setShadowColor(child->shadowColor());
        m_childShadow->setIsMultiShadow(child->isMultiShadow());
        Q_EMIT childShadowChanged();
    } else if (child && !m_childShadow) {
        m_childShadow = new ShadowData(child->xOffset(),
                                       child->yOffset(),
                                       child->blurRadius(),
                                       child->spread(),
                                       child->shadowColor());
        setIsMultiShadow(true);
        Q_EMIT childShadowChanged();
    } else if (!child && m_childShadow) {
        setIsMultiShadow(false);
        delete m_childShadow;
        m_childShadow = nullptr;
        Q_EMIT childShadowChanged();
    }
    if (child) {
        connect(child, &ShadowData::xOffsetChanged, m_childShadow, [child, this]() {
            m_childShadow->setXOffset(child->xOffset());
        });
        connect(child, &ShadowData::yOffsetChanged, m_childShadow, [child, this]() {
            m_childShadow->setYOffset(child->yOffset());
        });
        connect(child, &ShadowData::blurRadiusChanged, m_childShadow, [child, this]() {
            m_childShadow->setBlurRadius(child->blurRadius());
        });
        connect(child, &ShadowData::spreadChanged, m_childShadow, [child, this]() {
            m_childShadow->setSpread(child->spread());
        });
        connect(child, &ShadowData::shadowColorChanged, m_childShadow, [child, this]() {
            m_childShadow->setShadowColor(child->shadowColor());
        });
    }
}

int ShadowData::xOffset() const
{
    return m_xOffset;
}

int ShadowData::yOffset() const
{
    return m_yOffset;
}

int ShadowData::blurRadius() const
{
    return m_blurRadius;
}

int ShadowData::spread() const
{
    return m_spread;
}

QColor ShadowData::shadowColor() const
{
    return m_color;
}

bool ShadowData::isMultiShadow() const
{
    return m_isMultiShadow;
}

ShadowData *ShadowData::childShadow() const
{
    return m_childShadow;
}

}
