#ifndef IMAGEPROCESSING_H
#define IMAGEPROCESSING_H

#include <QImage>
#include <QObject>

#include "DocumentStore.h"
#include "ExtractorConfig.h"

/**
 * Qt Object that acts as an interface to the Image Processing.
 */
class ImageProcessing : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool isAnyImage READ isAnyImage NOTIFY isAnyImageChanged)
    Q_PROPERTY(bool isAnyDocument READ isAnyDocument NOTIFY isAnyDocChanged)
    Q_PROPERTY(bool colorMode READ colorMode NOTIFY colorModeChanged)
    Q_PROPERTY(bool filterMode READ filterMode NOTIFY filterModeChanged)
    Q_PROPERTY(float colorThr READ colorThr NOTIFY colorThrChanged)
    Q_PROPERTY(float colorGain READ colorGain NOTIFY colorGainChanged)
    Q_PROPERTY(float colorBias READ colorBias NOTIFY colorBiasChanged)

public:
    ImageProcessing();
    ~ImageProcessing() = default;

    /** Load cached images from disk and add them */
    Q_INVOKABLE void restoreCache();
    /** Add an image and cache it on disk */
    Q_INVOKABLE void addImage(const QString &imageURL);
    /** Reprocess a existing image on disk */
    Q_INVOKABLE void reprocessImage(const QString &id, bool colorMode, bool filterMode, int colorThr, float colorGain, float colorBias);
    /** Remove the specified image and delete it from cache */
    Q_INVOKABLE void removeImage(const QString &id);
    /** Remove all images and clear the cache */
    Q_INVOKABLE void removeAll();
    /** Export one image as PDF and return URL to PDF file */
    Q_INVOKABLE QString exportAsPdf(const QString &id) const;
    /** Export all images as PDF and return URL to PDF file */
    Q_INVOKABLE QString exportAllAsPdf() const;
    /** Export one image and return URL to image file */
    Q_INVOKABLE QString exportAsImage(const QString &id) const;
    /** Export all images and return list of URLs to image files */
    Q_INVOKABLE QStringList exportAllAsImages() const;
    /** Load image settings for selected image */
    Q_INVOKABLE void loadSingleImageSettings(const QString &id);

    /** Return true if a document has been found in the specified image */
    Q_INVOKABLE bool isDocument(const QString &id) const;
    /** Return true if there is at least one image in the current session */
    bool isAnyImage() const;
    /** Return true if a processed document has been found in the current session */
    bool isAnyDocument() const;
    /** Return true if filter mode is set for the current image */
    bool isFilterModeOn() const;
    /** Return true if color mode is set for the current image */
    bool isColorModeOn() const;

    /** Image settings */
    bool colorMode() const;
    bool filterMode() const;
    float colorThr() const;
    float colorGain() const;
    float colorBias() const;

private:
    void validateIsAnyFlags();

signals:
    void isAnyImageChanged();
    void isAnyDocChanged();
    void imageAdded(const QString &id);
    void imageUpdated(const QString &id);
    void imageRemoved(const QString &id);
    void userInfo(const QString msg);
    void colorModeChanged();
    void filterModeChanged();
    void colorThrChanged();
    void colorGainChanged();
    void colorBiasChanged();

private:
    DocumentScanner::DocumentStore &m_store;
    DocumentScanner::ExtractorConfig m_extractorConfig;
    std::map<QString, QVariant> m_params;
    bool m_isAnyDocument = false;
    bool m_isAnyImage = false;
    bool m_colorMode;
    bool m_filterMode;
    float m_colorThr;
    float m_colorGain;
    float m_colorBias;
};

#endif
