/***
   This file is part of fly-ocr.

   Copyright (C) 2016-2020 Sandro Mani <manisandro@gmail.com>
   Copyright (C) 2021 LLC "RusBITech-Astra" (https://astralinux.ru)

    Based on gImageReader source code by Sandro Mani under the GNU
    General Public License (GPL) version 3 or later

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

#ifndef RECOGNIZER_HPP
#define RECOGNIZER_HPP

#include <memory>
#include <QToolButton>
#include <fly-ocr/ocrenginefactory.h>
#include "configdialog.h"
#include "outputeditor.h"
#include "ui_pagerangedialog.h"
#include "ui_batchmodedialog.h"

class QActionGroup;
class MainWindowUi;
class OcrEngine;

class Recognizer : public QObject
{
    Q_OBJECT
public:
    enum class OutputDestination { Buffer, Clipboard };
    enum OutputMode { PlainText, FormattedText };

    Recognizer(const MainWindowUi* _ui);

    bool exportAs(OcrEngineFactory::Format format, const QString& path);

    OcrEngine* engine() const;
    void removePage(int page);
    void enqueueFiles(const QStringList& filePaths);
    OutputMode outputMode() const;

signals:
    void outputModeChanged();

public slots:
    void destroyEngine();
    void recognizeImage(const QImage& image, OutputDestination dest);
    void setRecognizeMode(const QString& mode);

private slots:
    void clearLineEditPageRangeStyle();
    void recognizeButtonClicked();
    void recognizeSelectedPages();
    void recognizeMultiplePages();
    void recognizeBatch();

private:
    struct PageData {
        QList<QImage> ocrAreas;
        OutputEditor::PageInfo pageInfo;
        bool success = false;
    };

    QList<int> selectPages(bool& autodetectLayout);
    bool setupEngine();
    void recognize(const QList<int>& pages, bool autodetectLayout = false);
    void showRecognitionErrorsDialog(const QStringList& errors);
    Q_INVOKABLE PageData setPage(int page, bool autodetectLayout);

    class ProgressMonitor;
    enum class PageArea { EntirePage, Autodetect };
    enum BatchExistingBehaviour { BatchOverwriteOutput, BatchSkipSource };

    const MainWindowUi* m_ui;
    OcrEngine* m_engine = nullptr;
    QMenu* m_menuPages = nullptr;
    QActionGroup* m_ocrModeActionGroup;
    QDialog* m_pagesDialog;
    Ui::PageRangeDialog m_pagesDialogUi;
    QDialog* m_batchDialog;
    Ui::BatchModeDialog m_batchDialogUi;
    QString m_modeLabel;
    QString m_langLabel;
    bool m_isRecognizing = false;
    QList<int> m_queuedPages;
};

#endif // RECOGNIZER_HPP
