/*
   Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   1. Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
   2. 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.

   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/


#ifndef KP_AI_DRAWINGBAR_H
#define KP_AI_DRAWINGBAR_H

#include <QDockWidget>
#include <QWidget>
#include <QPushButton>
#include <QButtonGroup>
#include <QLabel>
#include <QCheckBox>
#include <QVBoxLayout>
#include <QDialog>
#include <QPixmap>
#include <QStackedWidget>
#include <QScrollArea>
#include <QScrollBar>
#include <QPair>
#include <QList>
#include <QComboBox>
#include <QThread>
#include <QMouseEvent>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDir>
#include <QGSettings>
#include <ai-base/modelconfig.h>
#include <ai-base/vision.h>
#include <kylin-ai/config.h>

#define LOADING_IMAGE   "/usr/share/kolourpaint/pics/loading.gif"
#define BG_IMAGE        "/usr/share/kolourpaint/pics/bg@2x.png"
#define SLOGO_IMAGE     "/usr/share/kolourpaint/pics/slogo-Drawing.svg"
#define DRAWING_IMAGE   "/usr/share/kolourpaint/pics/AI-Drawing@2x.png"
#define KYLIN_AI_DBUS   "com.kylin.aiassistant"
#define KYLIN_AI_PATH   "/com/kylin/aiassistant"
#define AI_GSETTINGS    "org.kylin.aiassistant.settings"
#define AI_KEY          "isVisionSetup"


/**
 * @brief The AIModeDataThread class
 * 线程类，用于跑AI的服务
 */
class AIModeDataThread : public QObject
{
    Q_OBJECT

public:
    AIModeDataThread();
    ~AIModeDataThread();

    bool setSessionStatus();
    VisionSession getVisionSession(){
        return session;
    }
    bool someFunctionInThread();

    void setAIData (QString str, QSize size, int quantity, VisionImageStyle Style){
        textBox = str;
        AIImageSize = size;
        quantityNum = quantity;
        ImageStyle = Style;
    }

signals:
    void finishedSignal(bool flag, QPixmap pixmap, int imageIndex, int imageSum, int errorCode);

private:
    void sendErrorSignal(int ret){
        emit finishedSignal(false, QPixmap(), 0, 1, ret);
        for(int i = 0; i < quantityNum; i++)
            emit finishedSignal(true, QPixmap(), i, quantityNum, ret);
    }
    static void generateImageCallback(VisionImageData imageData, void* userData);

private:
    QPixmap pixmap;
    int     quantityNum = 1; //数量按钮
    QSize       AIImageSize;
    QString     textBox;
    VisionImageStyle ImageStyle;
    bool          m_sessionFlag = false;
    VisionSession session;
};

/**
 * @brief The imageClickableLabel class
 * QLabel点击事件类，用于对图片做处理传输
 */
class imageClickableLabel : public QLabel
{
    Q_OBJECT

signals:
    void labelClicked(const QPixmap &pixmap);

public:
    imageClickableLabel(const QPixmap &pixmap, QWidget *parent = nullptr) : QLabel(parent), pixmap(pixmap){}

protected:
    void mousePressEvent(QMouseEvent *event) override
    {
        Q_UNUSED(event);
        emit labelClicked(pixmap);
    }

private:
    QPixmap pixmap;
};


class kpAIDrawingBar : public QDockWidget
{
    Q_OBJECT

signals:
    void imageClicked(const QPixmap &pixmap);

public:
    kpAIDrawingBar(QWidget *parent);
    ~kpAIDrawingBar();

public:
    void  initUI();
    bool  getConfigStatus();
    void  getconfigVersionData();
    void  loginConfigurationPage();
    void  setAiPixmap(QPixmap pixmap,int imageIndex, QGridLayout *pageLayout);
    void  updatePageLabel();

    QSize getImageLabelSize();

    bool eventFilter(QObject *watched, QEvent *event);
    void handleLabelClicked(QObject *clickedObject);

    QPixmap createPixmapWithText(const QString &text);
    QPixmap AIGeneratesErrorHandling(int errorCode);

private slots:
    void onConfigButtonClicked();     //配置按钮回调函数
    void onConfigSettingsChange(const QString &key);     //AI配置成功后回调
    void onGenerateButtonClicked();     //生成按钮回调函数
    void handleInputTextChanged();      //文字变化回调函数

    void showPreviousPage();    //显示上一页
    void showNextPage();        //显示下一页
    void deleteCurrentPage();
    void setEnabledDeleteButton();
    void handleLabelClick(const QPixmap &pixmap);

    void addPageAndStoreImages();
    void onStyleMoreButtonClick();

    void startThread() {
        if (m_AiMode->setSessionStatus()){
            m_AiMode->setAIData(textBox, AIImageSize, quantityNum, ImageStyle);
            m_AiMode->someFunctionInThread();
        }
    }
    void onThreadFinished(bool flag, QPixmap pixmap, int imageIndex, int imageSum, int errorCode);

private:
    void updateImageGrid();
    void updateResultGrid();
    void deleteImageGridWidget();

    void addResolutionComboBox();
    void addQuantityComboBox();

    QJsonArray readResolutionsFromJson(QString key);
    int  readNumFromJson(QString key);
    QWidget *addAllStyleLabel(QString iconPath, QString labelText, int line);
    QWidget *addStyleLabel(QString iconPath, QString labelText, int line);

    void addStyleWidget();
    void addStyleGrid(QWidget *widget, int line);

private:
    int     imageColumn = 2;//显示列表列数
    int     quantityNum = 1; //数量按钮
    int     show_quantityNum = 1; //数量按钮
    int     currentPageIndx = -1;//切换页第几页

    bool        styleFlag;   //风格标志位，用于判断按下哪一个风格
    bool        deleteButtonFlag = true;
    bool        buildButtonFlag;

    QGSettings  *AiSettings;    //监听配置信息
    QSize       AIImageSize;    //图片大小
    QSize       showAIImageSize;
    QMovie      *movie = nullptr;//生成等待图标
    QLabel      *resultLabel;   //生成结果 label
    QLabel      *pageLabel;     //第几页面label

    QLabel      *selectedIconLabel;//风格图片选择Label
    QLabel      *selectedTextLabel;//风格文字选择Label

    QWidget     *configWidget;      //立即配置页面
    QWidget     *widget_low_poly;   //多边形风格

    QString     textBox;    //图像描述文字
    QString     colorfulButtonStyle; //立即生成按钮渐变色
    QString     colorGrayButtonStyle;//立即生成按钮置灰

    QBoxLayout  *vbox;  //页面布局
    QHBoxLayout *resultGrid; //生成结果布局
    QGridLayout *styleGrid;  //风格布局
    QPushButton *moreButton; //更多按钮

    QScrollArea  *scrollArea;  //滚动窗口
    QPushButton  *buildButton; //立即生成按钮
    QPushButton  *deleteButton; //删除按钮

    QComboBox    *resolutionComboBox;  //图像分辨率
    QComboBox    *quantityComboBox;    //生成数量

    QStackedWidget   *stackedWidget; //生成结果的换页窗口
    QVector<QVector<QPixmap>> imagesVector; //生成图像数据集成

    VisionSession     mSession = nullptr;
    VisionImageStyle  ImageStyle; //风格样式
    AIModeDataThread  *m_AiMode;  //AI生成程序

};
#endif
