#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QDebug>

#include "mycv.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    mActPic = 0;
    mScene = nullptr;
    mGif_anim = nullptr;
    mMovie = nullptr;
    mProxy = nullptr;

    mMyCVClass = new mycv();
    mProcMode = M_ALL_IMAGE_PROC;

    this->setWindowState(Qt::WindowMaximized);
    this->installEventFilter(this);
    this->setFocus();
}

MainWindow::~MainWindow()
{
    delete ui;
    delete mMyCVClass;
}

bool MainWindow::eventFilter(QObject *target, QEvent *event)
{
    if (event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        switch (keyEvent->key())
        {
        case Qt::Key_Left:
            mActPic--;
            showActPict();
            break;
        case Qt::Key_Right:
            mActPic++;
            showActPict();
            break;
        default:
            keyEvent->ignore();
        }
    }
    return QObject::eventFilter(target, event);
}

void MainWindow::on_btnOK_clicked()
{

}

void MainWindow::on_btnBad_clicked()
{

}

void MainWindow::showActPict()
{
    if(mTxtFilesAndDirectories.size() == 0)return;
    if(mActPic >= mTxtFilesAndDirectories.size())mActPic = mTxtFilesAndDirectories.size()-1;
    if(mActPic < 0)mActPic = 0;

    if(mGif_anim != nullptr)
    {
        delete(mGif_anim);
        mGif_anim = nullptr;
    }
    if(mMovie != nullptr)
    {
        delete(mMovie);
        mMovie = nullptr;
    }
//    if(mProxy != nullptr)
//    {
//        delete(mProxy);
//        mProxy = nullptr;
//    }

    mygraphicsview *grv;
    grv = (mygraphicsview*) ui->graphicsView;
    if(grv->scene() != nullptr)grv->scene()->clear();

    if(mTxtFilesAndDirectories[mActPic].contains(".gif")
            || mTxtFilesAndDirectories[mActPic].contains(".GIF"))
    {
        if(mScene != nullptr){delete(mScene);mScene = nullptr;}
        mScene = new QGraphicsScene(this);
        mGif_anim = new QLabel();
        mMovie = new QMovie(mFilesDir + "/" + mTxtFilesAndDirectories[mActPic]);
        mGif_anim->setMovie(mMovie);
        mMovie->start();
        mProxy = mScene->addWidget(mGif_anim);
        grv->setScene(mScene);
        grv->fitInView(mMovie->currentImage().rect(), Qt::KeepAspectRatio);

        // Show filename
        this->setWindowTitle("Elektrometer testing \
                             (" + mTxtFilesAndDirectories[mActPic] + ")");
    }
    else
    {
        if(mScene != nullptr){delete(mScene);mScene = nullptr;}
        mScene = new QGraphicsScene(this);
        QImage im;
            double t = (double)getTickCount();
        mMyCVClass->processImage(mFilesDir + "/", mTxtFilesAndDirectories[mActPic], im, mProcMode);
            t = ((double)getTickCount() - t)/getTickFrequency();
//        QGraphicsPixmapItem *p = mScene->addPixmap(QPixmap(mFilesDir +
//                                                    "/" + mTxtFilesAndDirectories[mActPic]));
        QGraphicsPixmapItem *p = mScene->addPixmap(QPixmap::fromImage(im));
        grv->setScene(mScene);
        grv->fitInView(p, Qt::KeepAspectRatio);
        // Show filename
        this->setWindowTitle("Elektrometer testing (" + mTxtFilesAndDirectories[mActPic] +
                             ") time=" + QString::number(t*1000) + " ms");
    }
}

void MainWindow::on_btnNext_clicked()
{
    mActPic++;
    showActPict();
}

void MainWindow::on_btnBack_clicked()
{
    mActPic--;
    showActPict();
}

void MainWindow::on_actionOpen_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    mFilesDir = fileDial.getExistingDirectory(this);
    // Load all pictures
    QStringList nameFilter("*.jpg");
    nameFilter.append("*.gif");
    QDir directory(mFilesDir);
    mTxtFilesAndDirectories = directory.entryList(nameFilter);

    mActPic = 0;
    mProcMode = M_ALL_IMAGE_PROC;
    showActPict();
}

void MainWindow::on_actionExit_triggered()
{
    this->close();
}



void MainWindow::on_actionSave_triggered()
{
    mygraphicsview *grv;
    grv = (mygraphicsview*) ui->graphicsView;
    QString fileName = mFilesDir + "/savedPicture.png";
//    QPixmap pixMap = QPixmap::grabWidget(grv);
    QPixmap pixMap = grv->grab();
    pixMap.save(fileName);
}

void MainWindow::on_actionSave_frame_triggered()
{
    mMyCVClass->saveFrames();
}

void MainWindow::on_actionSave_digit_triggered()
{
    mMyCVClass->saveDigits();
}

void MainWindow::on_actionOpen_frame_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    mFilesDir = fileDial.getExistingDirectory(this);
    // Load all pictures
    QStringList nameFilter("*.jpg");
    nameFilter.append("*.gif");
    nameFilter.append("*.bmp");
    nameFilter.append("*.png");
    QDir directory(mFilesDir);
    mTxtFilesAndDirectories = directory.entryList(nameFilter);

    mActPic = 0;
    mProcMode = M_FRAME_PROC;
    showActPict();
}

void MainWindow::on_actionLoad_patterns_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    QString name = fileDial.getOpenFileName(this);
    mMyCVClass->mycvLoadPatternNumbers(name, 0);
}

void MainWindow::on_actionLoad_test_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    QString name = fileDial.getOpenFileName(this);
    mMyCVClass->mycvLoadPatternNumbers(name, 1);
}

void MainWindow::on_actionLoad_pattern_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    QString name = fileDial.getOpenFileName(this);
    mMyCVClass->mycvLoadPatternNumbers2(name, 0);
}

void MainWindow::on_actionLoad_test_2_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    QString name = fileDial.getOpenFileName(this);
    mMyCVClass->mycvLoadPatternNumbers2(name, 1);
}

// ANN
// names of subdirectories with training data
QString strANNDirs[] = {"/0", "/1", "/2", "/3", "/4", "/5", "/6", "/7", "/8", "/9",
"/0_5", "/1_5", "/2_5", "/3_5", "/4_5", "/5_5", "/6_5", "/7_5", "/8_5", "/9_5"};
int numOfANNDirs = 20;
void MainWindow::on_actionTrain_triggered()
{
    // File filter
    QStringList nameFilter("*.jpg");
    nameFilter.append("*.bmp");
    nameFilter.append("*.png");

    QFileDialog fileDial(this);
    // Choose input dir
    QString filesDir = fileDial.getExistingDirectory(this, tr("Select ANN training set path"));

    // Clear prev. data
    mMyCVClass->clearTrainingDataANN();

    // Load each training set
    for(int i = 0 ; i < numOfANNDirs ; i++)
    {
        // Load all pictures
        QDir directory(filesDir + strANNDirs[i]);
        QStringList fileList = directory.entryList(nameFilter);
        if(fileList.size() > 0)
        {
            // Train each picture from current dataset
            for(int j = 0 ; j < fileList.size() ; j++)
                mMyCVClass->addTrainingDataANN(filesDir + strANNDirs[i] + "/" + fileList[j], i);
        }
        qDebug() << "ANN dataset[" << i << "] loaded." << endl;
    }
    // Train ANN
    qDebug() << "ANN training started..." << endl;
    mMyCVClass->trainANN();
    qDebug() << "ANN trained!" << endl;
}

void MainWindow::on_actionLoad_xml_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    QString name = fileDial.getOpenFileName(this, "Load trained ANN", QString(), "Trained ANN(*.xml)");
    mMyCVClass->loadXMLANN(name);
}

void MainWindow::on_actionSave_xml_triggered()
{
    QFileDialog fileDial(this);
    // Choose output dir
    QString name = fileDial.getSaveFileName(this, "Save trained ANN", QString(), "Trained ANN(*.xml)");
    mMyCVClass->saveXMLANN(name);
}

void MainWindow::on_actionPredict_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    QString name = fileDial.getOpenFileName(this);
    mMyCVClass->predictANN(name);
}

// Haar cascades
void MainWindow::on_actionLoad_patterns_2_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    QString name = fileDial.getOpenFileName(this);
    mMyCVClass->LoadXMLFrameHaar(name);
}

void MainWindow::on_actionSave_noFrame_triggered()
{
    mMyCVClass->mycvSaveNoFrameImg();
}

void MainWindow::on_actionEqualize_folder_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    QString filesDir = fileDial.getExistingDirectory(this, "Load folder with images to equalize");
    // Load all pictures
    QStringList nameFilter("*.jpg");
    nameFilter.append("*.bmp");
    nameFilter.append("*.png");
    QDir directory(filesDir);
    QStringList fileList = directory.entryList(nameFilter);

    for(int i = 0 ; i < fileList.size() ; i++)
        mMyCVClass->processImageSimple(filesDir + "/", fileList[i], 0);
}


void MainWindow::on_actionNormalize_digits_triggered()
{
    QFileDialog fileDial(this);
    // Choose input dir
    QString filesDir = fileDial.getExistingDirectory(this, "Load folder with images to normalize");
    // Load all pictures
    QStringList nameFilter("*.jpg");
    nameFilter.append("*.bmp");
    nameFilter.append("*.png");
    QDir directory(filesDir);
    QStringList fileList = directory.entryList(nameFilter);
    for(int i = 0 ; i < fileList.size() ; i++)
        mMyCVClass->processImageSimple(filesDir + "/", fileList[i], 1);
}
