/*******************************************************************************
**
** 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.
**
*******************************************************************************/



#pragma once

#include <QtGlobal>
#include <QDebug>
#include <QRectF>
#include <QImage>

struct PageGeometry
{
    PageGeometry()
    {  }
    PageGeometry(qreal sX, qreal sY, qreal eX, qreal eY) :
        startX(sX),
        startY(sY),
        endX(eX),
        endY(eY)
    {  }
    PageGeometry(const PageGeometry &other) :
        startX(other.startX),
        startY(other.startY),
        endX(other.endX),
        endY(other.endY)
    {  }
    PageGeometry(PageGeometry &&other) :
        startX(qMove(other.startX)),
        startY(qMove(other.startY)),
        endX(qMove(other.endX)),
        endY(qMove(other.endY))
    {  }
    PageGeometry &operator=(const PageGeometry &other)
    {
        startX = other.startX;
        startY = other.startY;
        endX = other.endX;
        endY = other.endY;

        return *this;
    }
    PageGeometry &operator=(PageGeometry &&other)
    {
        qSwap(startX, other.startX);
        qSwap(startY, other.startY);
        qSwap(endX, other.endX);
        qSwap(endY, other.endY);

        return *this;
    }

    bool containX(qreal x) const
    {
        return x >= startX && x < endX;
    }

    bool containY(qreal y) const
    {
        return y >= startY && y < endY;
    }
    qreal width() const
    {
        return qAbs(startX - endX);
    }
    qreal height() const
    {
        return qAbs(startY - endY);
    }
    qreal heightToWidthRatio() const
    {
        return height() / width();
    }

    qreal startX{0.0};
    qreal startY{0.0};
    qreal endX{0.0};
    qreal endY{0.0};
};

struct PagesMap
{
    int pageOnX(qreal x) const
    {
        for (int i = 0; i < pages.size(); ++i)
            if (pages.at(i).containX(x))
                return i;

        return -1;
    }
    int pageOnY(qreal y) const
    {
        for (int i = 0; i < pages.size(); ++i)
            if (pages.at(i).containY(y))
                return i;

        return -1;
    }
    QVector<PageGeometry> pages;
};

struct PagePosition
{
    bool belong(qreal coord, qreal scale = 1.0) const {
        return (coord >= start * scale) && (coord < end * scale);
    }

    qreal start {0.0};
    qreal end {0.0};
};

struct CachedPage
{
    QImage pageImage;
    qreal scale;
};

struct CachedAnnotation
{
    QRect annotationRect;
    QString url;
    QPoint coordinate;
    int linkToPage{-1};
};

inline QDebug operator<<(QDebug d, const PageGeometry &g) {
    d << "[" << g.startX << ":" << g.startY << "::" << g.width() << ":" << g.height() << "]";
    return d;
}

inline QDebug operator<<(QDebug d, const PagePosition &g) {
    d << "[" << g.start << ":" << g.end << "]";
    return d;
}

inline QDebug operator<<(QDebug d, const CachedPage &g) {
    d << "[" << g.scale << ":" << g.pageImage.size() << "]";
    return d;
}
