/*******************************************************************************
**
** 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 <QObject>
#include <QThread>
#include <QRect>

#include "documentproviderglobal.h"

class DOCUMENTPROVIDER_EXPORT BaseDocumentProvider : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
    Q_PROPERTY(QString fileName READ fileName WRITE setFileName NOTIFY fileNameChanged)
    Q_PROPERTY(bool loaded READ loaded WRITE setLoaded NOTIFY loadedChanged)
    Q_PROPERTY(bool initialized READ initialized WRITE setInitialized NOTIFY initializedChanged)
    Q_PROPERTY(bool processing READ processing WRITE setProcessing NOTIFY processingChanged)
    Q_PROPERTY(int pageCount READ pageCount WRITE setPageCount NOTIFY pageCountChanged)
    Q_PROPERTY(QList<QString> pageNames READ pageNames WRITE setPageNames NOTIFY pageNamesChanged)
    Q_PROPERTY(int loadProgress READ loadProgress WRITE setLoadProgress NOTIFY loadProgressChanged)
    Q_PROPERTY(int error READ error WRITE setError NOTIFY errorChanged)
    Q_PROPERTY(DocumentType documentType READ documentType NOTIFY documentTypeChanged)
    Q_PROPERTY(QString selectedHyperlink READ selectedHyperlink WRITE setSelectedHyperlink NOTIFY selectedHyperlinkChanged)

public:
    enum DocumentType
    {
        Text,
        Spreadsheet,
        Presentation,
        Drawing,
        Other
    };
    Q_ENUM(DocumentType)

    enum ErrorType
    {
        NoError,
        EmptyUrl,
        FileNotFound,
        UnsupportedFileType,
        CorruptedDocument,
        ProviderContextError,
        ProviderLoaderError,
        ProviderProcessError,
        UnknownError = 99
    };
    Q_ENUM(ErrorType)

    BaseDocumentProvider(QObject *parent = nullptr);

    virtual void load(const QUrl &filePath) = 0;
    virtual void clearDocument() = 0;
    virtual QSize pageSize(int pageNumber) const = 0;
    virtual QRect pageRect(int pageNumber) const = 0;

    virtual void resetQueue() = 0;

    virtual bool supportsTiledRendering() const = 0;
    virtual void renderPage(int pageNumber, const QSize &canvasSize, qreal zoom) = 0;
    virtual void renderToImage(int pageNumber, const QRect &documentRect, const QSize &canvasSize, const QSize &pageSize, qreal zoom, bool forceUpdate = false) = 0;
    virtual int tileSize() const = 0;
    virtual void stopRenderImage(int pageNumber, const QRect &renderRect, qreal zoom) = 0;
    virtual void sendUnoCommand(const QByteArray &command, const QByteArray &arguments, bool notifyWhenFinished = true) = 0;
    virtual void sendKeyEvent(int type, int charCode, int keyCode) = 0;
    virtual void sendMouseEvent(int type, qreal x, qreal y, int count, int buttons, int modifier, int pageIndex, qreal zoom) = 0;
    virtual void sendSelectEvent(int type, qreal x, qreal y, int pageIndex, qreal zoom) = 0;
    virtual void setPartIndex(int partIndex) = 0;
    virtual void saveDocumentAs(const QString &path, const QString &format) = 0;
    virtual void getUnoCommandValues(const QByteArray &command) = 0;
    virtual void getTextSelection(const QString &mimeType = QStringLiteral("text/plain;charset=utf-8")) = 0;

    QString path() const;
    void setPath(const QString &newPath);

    QString fileName() const;
    void setFileName(const QString &newFileName);

    bool loaded() const;
    void setLoaded(bool newLoaded);

    bool initialized() const;
    void setInitialized(bool newInitialized);

    int pageCount() const;
    void setPageCount(int pageCount);

    QList<QString> pageNames() const;
    void setPageNames(const QList<QString> &pageNames);

    int loadProgress() const;
    void setLoadProgress(int newLoadProgress);

    int error() const;
    void setError(const int error);

    DocumentType documentType() const;
    void setDocumentType(DocumentType type);

    bool processing() const;
    void setProcessing(bool processing);

    QString selectedHyperlink() const;
    void setSelectedHyperlink(const QString &selectedHyperlink);

signals:
    void pathChanged();
    void fileNameChanged();
    void loadedChanged();
    void initializedChanged();
    void pageCountChanged();
    void pageNamesChanged();
    void loadProgressChanged();
    void errorChanged(int error);
    void documentTypeChanged();
    void libreofficeAnswer(int type, const QByteArray &data);
    void unoAnswer(const QByteArray &command, const QByteArray &data);
    void textSelectionAnswer(const QString text);
    void pageRendered(int pageNumber, const QImage &image, qreal zoom) const;
    void tileRendered(int pageNumber, const QImage &image, const QRect &documentTileRect, qreal zoom);
    void closed();
    void processingChanged(bool processing);
    void selectedHyperlinkChanged(QString selectedHyperlink);
    void saveAsStatusChanged(const QString &path, const QString &format, bool status);

protected:
    bool m_isLoaded;
    bool m_isInitialized;
    bool m_processing;
    int m_pageCount;
    QList<QString> m_pageNames;
    int m_loadProgress;
    int m_error;
    DocumentType m_documentType;
    QString m_path;
    QString m_fileName;
    QString m_selectedHyperlink;
};
