/*******************************************************************************
**
** 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 <QSharedPointer>
#include <QHash>
#include <QSet>
#include <QVector>
#include <QPair>

#include <basedocument.h>

class LoDocumentProvider;
class LoDocument : public BaseDocument
{
    Q_OBJECT

public:
    explicit LoDocument(QObject *parent = nullptr);
    ~LoDocument();

    QThreadPool *threadPool() const override;
    QString path() const override;
    QString fileName() const override;
    QSizeF pageSize(int pageNumber) const override;
    int count() const override;
    int error() const override;
    BaseDocumentProvider::DocumentType documentType() const override;
    QList<QString> pageNames() const override;
    QSharedPointer<BasePage> loadPage(int pageIndex) override;
    void startLoadBookmarks() const override;
    QVector<BaseBookmark *> bookmarks() const override;
    int fileVersion() const override;
    bool saveDocumentAs(const QString &path, const QString &format) const override;
    void mousePress(const InternalPosition &internaPos) override;
    void mouseRelease(const InternalPosition &internaPos) override;
    void mouseDoubleClick(const InternalPosition &internaPos) override;
    void startSelectText(const InternalPosition &internaPos) override;
    void endSelectText(const InternalPosition &internaPos) override;
    void resetSelectText() override;
    void sendUnoCommand(const QString &command, const QString &arguments, bool notifyWhenFinished = true) override;
    void getUnoCommandValues(const QString &command) override;
    void startSearch(const QString &string, SearchDirection direction, const QPointF &startPosition) override;
    void stopSearch() override;
    void goToCell(const QString &adressCell) override;
    QList<QRect> currentHighlightedSearch(int pageIndex) const override;
    QList<QRect> allHighlightedSearch(int pageIndex) const override;
    QList<QPair<QString, QRect>> cellSelected(int pageIndex) const override;
    QList<QRect> highlightedTextArea(int pageIndex) const override;
    QString slsectionText() const override;
    QList<QPair<CommentData, QRect>> comments(int pageIndex) const override;
    QPair<Marker, Marker> selectionMarkers() const override;
    QPair<int, QRect> cursor() const override;

public slots:
    void setPath(const QString &path) override;
    // Part (page) for Calc
    void setPartIndex(int partIndex);

private slots:
    void _libreofficeAnswer(int type, const QByteArray &data);
    void _unoAnswer(const QByteArray &command, const QByteArray &result);
    void _textSelectionAnswer(const QString &text);
    void _comments(const QByteArray &data);
    void _searchResult(const QByteArray &data);
    void _searchNotFound(const QByteArray &data);
    void _unoCommandResult(const QByteArray &data);
    void _textSelection(const QByteArray &data);
    void _textSelectionStart(const QByteArray &data);
    void _textSelectionEnd(const QByteArray &data);
    void _invalidateTiles(const QByteArray &data);
    void _invalidateVisibleCursor(const QByteArray &data);
    void _cellCursor(const QByteArray &data);
    void _cellFormula(const QByteArray &data);
    void _cellAdress(const QByteArray &data);
    void _callbackStateChanged(const QByteArray &data);
    int _pageIndexFromTwipY(int y);

private:
    QSharedPointer<LoDocumentProvider> m_loProvider;
    QHash<int, QSizeF> m_pageSizes;
    QHash<int, QSharedPointer<BasePage>> m_loadedPages;
    QSet<int> m_pagesInProcess;
    int m_lastLoadedPage;
    QVector<BaseBookmark *> m_baseBookmarks;
    QPoint m_searchStartPoint;
    QHash<int, QList<QRect>> m_allHighlighted;
    QHash<int, QList<QRect>> m_currentHighlighted;
    QHash<int, QList<QPair<QString, QRect>>> m_cellSelected;
    QHash<int, QList<QRect>> m_textSelected;
    QHash<int, QList<QPair<CommentData, QRect>>> m_comments;
    QString m_currentCellAdress;
    QString m_currentCellFormula;
    QString m_currentCellContent;
    QString m_selectionText;
    QString m_searchString;
    QPair<int, QRect> m_cursor;
    QPair<Marker, Marker> m_selectionMarkers;
    QThreadPool *m_innerThreadPool;
    // Part (page) for Calc
    int m_partIndex;
};

struct CommentData
{
    QString author;
    QString dateTime;
    QString text;
};
