/*******************************************************************************
**
** SPDX-FileCopyrightText: Copyright 2023 Open Mobile Platform LLC <community@omp.ru>
** SPDX-License-Identifier: BSD-3-Clause
** This file is part of the OfficeViewer project.
**
** Redistribution and use in source and binary forms,
** with or without modification, are permitted provided
** that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice,
**   this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
**   this list of conditions and the following disclaimer
**   in the documentation and/or other materials provided with the distribution.
** * Neither the name of the copyright holder nor the names of its contributors
**   may be used to endorse or promote products derived from this software
**   without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
** FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
** OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS;
** OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
** EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/


#include <QQuickWindow>
#include <QSGSimpleTextureNode>

#include "basedocitem.h"

BaseDocItem::BaseDocItem(const QColor &color, const QColor &highlightcolor, QQuickItem *parent, BaseAnnotation *source)
    : QQuickItem(parent)
    , m_needUpdateImage(false)
    , m_source(source)
    , m_highlighted(false)
    , m_color(color)
    , m_highlightcolor(highlightcolor)
{
    setFlag(QQuickItem::ItemHasContents, true);
    setAcceptedMouseButtons(Qt::AllButtons);

    connect(this, &BaseDocItem::xChanged, this, &BaseDocItem::update);
    connect(this, &BaseDocItem::yChanged, this, &BaseDocItem::update);
    connect(this, &BaseDocItem::widthChanged, this, &BaseDocItem::update);
    connect(this, &BaseDocItem::heightChanged, this, &BaseDocItem::update);

    connect(parent, &QQuickItem::yChanged, this, &BaseDocItem::clearHighlight);
    connect(parent, &QQuickItem::xChanged, this, &BaseDocItem::clearHighlight);

    m_paper = QImage(1, 1, QImage::Format_RGBA8888);

    setColor(color);
}

BaseAnnotation *BaseDocItem::source() const
{
    return m_source;
}

QSGNode *BaseDocItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
    if (height() <= 0 || width() <= 0)
        return nullptr;

    auto node = static_cast<QSGSimpleTextureNode *>(oldNode);

    if (node == nullptr) {
        node = new QSGSimpleTextureNode();
        node->setOwnsTexture(true);
    }

    if (m_needUpdateImage || node->texture() == nullptr) {
        if (node->texture() != nullptr)
            node->texture()->deleteLater();

        node->setTexture(window()->createTextureFromImage(m_paper));

        m_needUpdateImage = false;
    }

    node->setRect(boundingRect());

    return node;
}

bool BaseDocItem::event(QEvent *event)
{
    if (opacity() < 1.0f)
        return QQuickItem::event(event);

    switch (event->type()) {
    case QEvent::MouseButtonPress:
        setHighlight(true);
        return true;

    case QEvent::MouseButtonRelease:
        if (source() != nullptr)
            emit triggered(source());
        setHighlight(false);
        break;

    case QEvent::MouseMove:
        setHighlight(false);
        break;

    default:
        break;
    }

    return QQuickItem::event(event);
}

void BaseDocItem::clearHighlight()
{
    setHighlight(false);
}

void BaseDocItem::setHighlight(bool highlight)
{
    if (m_highlighted != highlight) {
        m_highlighted = highlight;
        m_paper.fill(m_highlighted ? m_highlightcolor : m_color);
        m_needUpdateImage = true;
        update();
    }
}

void BaseDocItem::setColor(const QColor &newColor)
{
    m_color = newColor;
    if (!m_highlighted) {
        m_paper.fill(m_color);
        m_needUpdateImage = true;
        update();
    }
}

void BaseDocItem::setHighlightcolor(const QColor &newHighlightcolor)
{
    m_highlightcolor = newHighlightcolor;
    if (!m_highlighted) {
        m_paper.fill(m_highlightcolor);
        m_needUpdateImage = true;
        update();
    }
}

bool BaseDocItem::highlighted() const
{
    return m_highlighted;
}

const QColor &BaseDocItem::highlightcolor() const
{
    return m_highlightcolor;
}

const QColor &BaseDocItem::color() const
{
    return m_color;
}
