#ifndef PQIMAGE_H
#define PQIMAGE_H

#include <QImage>
#include <pqobject.h>
#include "pqpixmap.h"

class PQImage;
class PQImage : public PQObject, public QImage
{
    Q_OBJECT
    PQ_OBJECT_EX(QImage)

    Q_PROPERTY(bool isNull READ isNull)
    Q_PROPERTY(bool detached READ isDetached)
    Q_PROPERTY(int format READ format)
    Q_PROPERTY(int width READ width)
    Q_PROPERTY(int height READ height)
    Q_PROPERTY(QSize size READ size)
    Q_PROPERTY(QRect rect READ rect)
    Q_PROPERTY(int depth READ depth)
    Q_PROPERTY(int colorCount READ colorCount)
    Q_PROPERTY(int bitPlaneCount READ bitPlaneCount)
    Q_PROPERTY(bool allGray READ allGray)
    Q_PROPERTY(bool isGrayscale READ isGrayscale)
    Q_PROPERTY(int byteCount READ byteCount)
    Q_PROPERTY(int bytesPerLine READ bytesPerLine)
    Q_PROPERTY(double devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio)
    Q_PROPERTY(bool hasAlphaChannel READ hasAlphaChannel)

public:
    Q_INVOKABLE explicit PQImage();
    Q_INVOKABLE explicit PQImage(int width, int height, int format);
    Q_INVOKABLE explicit PQImage(const QString &fileName, const char *format = Q_NULLPTR);
    Q_INVOKABLE explicit PQImage(const QImage &image);
    ~PQImage();

    Q_INVOKABLE bool isNull() const;
    Q_INVOKABLE void detach();
    Q_INVOKABLE bool isDetached() const;

    Q_INVOKABLE PQImage *copy(int x, int y, int w, int h);

    Q_INVOKABLE int format() const;

    Q_INVOKABLE PQImage *convertToFormat(int f, int flags = Qt::AutoColor);

    Q_INVOKABLE int width() const;
    Q_INVOKABLE int height() const;
    Q_INVOKABLE QSize size() const;
    Q_INVOKABLE QRect rect() const;

    Q_INVOKABLE int depth() const;
    Q_INVOKABLE int colorCount() const;
    Q_INVOKABLE int bitPlaneCount() const;

    Q_INVOKABLE uint color(int i) const;
    Q_INVOKABLE void setColor(int i, uint c);
    Q_INVOKABLE void setColorCount(int c);

    Q_INVOKABLE bool allGray() const;
    Q_INVOKABLE bool isGrayscale() const;

    //uchar *bits();
    //const uchar *bits() const;
    //const uchar *constBits() const;

    Q_INVOKABLE int byteCount() const;

    //uchar *scanLine(int);
    //const uchar *scanLine(int) const;
    //const uchar *constScanLine(int) const;
    Q_INVOKABLE int bytesPerLine() const;

    Q_INVOKABLE bool valid(int x, int y) const;

    Q_INVOKABLE int pixelIndex(int x, int y) const;

    Q_INVOKABLE uint pixel(int x, int y) const;

    Q_INVOKABLE void setPixel(int x, int y, uint index_or_rgb);

    Q_INVOKABLE QString pixelColor(int x, int y) const;
    Q_INVOKABLE void setPixelColor(int x, int y, const QString &c);

    Q_INVOKABLE double devicePixelRatio() const;
    Q_INVOKABLE void setDevicePixelRatio(double scaleFactor);

    Q_INVOKABLE void fill(uint pixel);
    Q_INVOKABLE void fill(const QString &color);

    Q_INVOKABLE bool hasAlphaChannel() const;
    Q_INVOKABLE bool setAlphaChannel(PQObject *pqimage);

    Q_INVOKABLE PQImage *alphaChannel();
    Q_INVOKABLE PQImage *createAlphaMask(int flags = Qt::AutoColor);
    Q_INVOKABLE PQImage *createMaskFromColor(uint color, int mode = Qt::MaskInColor);

    Q_INVOKABLE PQImage *scaled(int w, int h,
                                int aspectMode = Qt::IgnoreAspectRatio,
                                int mode = Qt::FastTransformation);

    Q_INVOKABLE PQImage *scaledToWidth(int w, int mode = Qt::FastTransformation);
    Q_INVOKABLE PQImage *scaledToHeight(int h, int mode = Qt::FastTransformation);
    Q_INVOKABLE PQImage *rotated(double angle, int axis = Qt::ZAxis, int mode = Qt::FastTransformation);
    Q_INVOKABLE PQImage *rotatedRadians(double angle, int axis = Qt::ZAxis, int mode = Qt::FastTransformation);
    Q_INVOKABLE PQImage *translated(double dx, double dy, int mode = Qt::FastTransformation);

    Q_INVOKABLE PQImage * mirrored(bool horizontally = false, bool vertically = true);
    Q_INVOKABLE PQImage * rgbSwapped();

    void invertPixels(int mode = InvertRgb);

    bool load(const QString &fileName, const char *format = Q_NULLPTR);
    bool loadFromData(const QByteArray &data, const char *aformat = Q_NULLPTR);

    bool save(const QString &fileName, const char *format = Q_NULLPTR, int quality = -1) const;

    QStringList textKeys() const;
    QString text(const QString &key = QString()) const;
    void setText(const QString &key, const QString &value);

    //QPixelFormat pixelFormat() const Q_DECL_NOTHROW;
    //static QPixelFormat toPixelFormat(QImage::Format format) Q_DECL_NOTHROW;
    //static QImage::Format toImageFormat(QPixelFormat format) Q_DECL_NOTHROW;
};

Q_DECLARE_METATYPE(QImage*)
Q_DECLARE_METATYPE(PQImage*)

#endif // PQIMAGE_H
