/***
   This file is part of the Tesseract plugin for fly-ocr.

   Copyright (C) 2021 LLC "RusBITech-Astra" (https://astralinux.ru)

   Foobar 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.

   Foobar 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 the Tesseract plugin for fly-ocr. If not, see
   <https://www.gnu.org/licenses/>.
***/

#ifndef TESSERACTENGINE_H
#define TESSERACTENGINE_H

#include <atomic>
#include <QObject>
#include <QMap>
#define USE_STD_NAMESPACE
#include <tesseract/ocrclass.h>
#undef USE_STD_NAMESPACE
#include <fly-ocr/ocrengine.h>


namespace tesseract
{
class TessBaseAPI;
}

class TesseractEngine : public OcrEngine
{
    Q_OBJECT
public:
    explicit TesseractEngine(QObject* parent = nullptr);
    ~TesseractEngine();

    bool initialize(const QStringList& langs = QStringList(), bool analyseOnly = false) override;
    void setPageSegmentationMode(int mode) override;
    void setAutomaticPageSegmentation() override;
    void setCharacterWhitelist(const QString& characters) override;
    void setCharacterBlacklist(const QString& characters) override;
    int pageCount() const override;
    bool recognize(const QImage& image, int resolution, int page) override;
    bool isRecognized(int page) override;
    QByteArray getPageData(int page, OcrEngineFactory::Format format) const override;
    void setPageData(int page, OcrEngineFactory::Format format, const QByteArray& data) override;
    void cancel() override;
    int progress() const override;
    QList<QRectF> analyseLayout(const QImage& image, double* avgDeskew) override;
    bool exportAs(OcrEngineFactory::Format format, const QString& path) override;
    void removePage(int page) override;

    QList<FlyOcr::Lang> availableLanguages() const;
    bool hasOsd() const;

private:
    static bool cancelCallback(void* instance, int /*words*/);

    tesseract::TessBaseAPI* m_api = nullptr;
    std::atomic_bool m_canceled = ATOMIC_VAR_INIT(false);
    struct TessLang {
        QString code;
        const char* name;
    };

    struct Page {
        QByteArray hocrText;
        QByteArray plainText;
        bool recognized = false;
        int resolution = 0;
    };

    QMap<int, Page> m_pages;

    static const QHash<QString, TesseractEngine::TessLang> m_tessLangs;

#if TESSERACT_MAJOR_VERSION < 5
    ETEXT_DESC m_monitor;
#else
    tesseract::ETEXT_DESC m_monitor;
#endif
};

#endif // TESSERACTENGINE_H
