#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QShortcut>
#include <QMessageBox>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ///
    /// Keyboard shortcuts
    /// Atajos del teclado

    /// Closes window with cmd + w
    /// Cierra la ventana con cmd + w
    new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this, SLOT(close()));
    ///
    /// Loads a image with cmd + o
    /// Carga una imagen con cmd + o
    new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_O), this, SLOT(on_btnLoadImages_clicked()));
    ///
    /// Removes noise from a image with cmd + r
    /// Remueve el ruido de una imagen con cmd + r
    new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_R), this, SLOT(on_btnRemoveNoise_clicked()));
    ///
    /// Saves an image without noise with cmd + s
    /// Guarda una imagen sin ruido con cmd + s
    new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_S), this, SLOT(on_btnSaveImage_clicked()));

}


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


void MainWindow::loadImages(vector<QImage> & images, QString path){
    QDir dir(path); // Create a QDir with the given path
                    // Crea un QDir con el path recibido

    dir.setFilter(QDir::Files);  // Set a filter so only files are looked for
                                 // Pone un filtro para ver solo archivos
    dir.setSorting(QDir::Name);  // Set sorting by name
                                 // Para ordenar por nombre

    // Get the list of files in the directory
    // Obtiene la lista de los archivos en el directorio
    QFileInfoList list = dir.entryInfoList();


    QFileInfo fileInfo;  // Holds the info of the next file to be checked
                         // Guarda la informacion de el proximo archivo a revisar

    // String to store the path of the current file being checked
    // Cadena para guardar el camino del archivo actual a revisar
    QString filePath;

    // String to store the name of the current file being checked
    // Cadena para guardar el nombre del archivo actual a revisar
    QString fileName;

    for(int i = 0; i < list.size(); i++){
        fileInfo = list.at(i);  // Get the file info at possition i
                                // Obtiene el la informacion del archivo en posicion i
        filePath = fileInfo.filePath(); // Get the file path
                                        // Obtiene el camino al archivo
        fileName = fileInfo.fileName(); // Get the file name
                                        // Obtiene el nombre el archivo

        QImage image(filePath); // Load the file as an image
                                // Carga el archivo como una imagen

        // If the file cant be loaded continue
        // Si no puede cargar el archivo continua al proximo
        if(image.isNull())
            continue;
        // Add the image to the image_value vector
        // Anade la imagen a el vector de imagenes.
        else
            images.push_back(image) ;
    }
}


void MainWindow::on_btnLoadImages_clicked(){

    // Clearing vectors if they are already populated with previous images
    // Limpiando los vectores si han sido llenado con imagenes previas
    images.clear();

    // Display a browse folder dialog. Asign the selected path to directory.
    // Despliega un buscador de carpetas.  Asigna el camino seleccionado a un directorio.
    QString directory = QFileDialog::getExistingDirectory(this, tr("Find Files"), QDir::currentPath());

    // Vector that contains the labels that will hold the images
    // Vector que contiene las etiquetas que desplegaran las imagenes en el GUI.
    QVector<QLabel *> labels;

    // Restricted to a maximum of 9 images in the GUI
    // Restringido a un maximo de 9 imagenes en el GUI
    labels.append(ui->lblImage1);
    labels.append(ui->lblImage2);
    labels.append(ui->lblImage3);
    labels.append(ui->lblImage4);
    labels.append(ui->lblImage5);
    labels.append(ui->lblImage6);
    labels.append(ui->lblImage7);
    labels.append(ui->lblImage8);
    labels.append(ui->lblImage9);

    // Loads the images to the image vector
    // Carga las imagenes al vector de imagenes.
    loadImages(images, directory);

    // Setting the image labels with the orinal images
    // Ajusta la imageen a las etiquetas.

    if(images.empty()){
        QMessageBox::information(this,"title goes here","Directory doesn't contain images");
    }
    else if (images.size() >= 1 && images.size() <= 2){
        images.clear();
        QMessageBox::information(this,"title goes here","ERROR: Directory must contain at least 3 images");
    }
    else{
        if (images.size() <= 9)
            for(unsigned int i = 0; i<images.size(); i++)
                labels[i]->setPixmap(QPixmap::fromImage(images[i]));
        else
            QMessageBox::information(this,"title goes here","ERROR: Directory contains more than 9 images");
    }
}


void MainWindow::on_btnRemoveNoise_clicked(){
    if(!images.empty()){
        finalImage = images[0] ;
        RemoveNoise(images, finalImage) ;
        // Displaying a new image without noise
        ui->lblFinalImage->setPixmap(QPixmap::fromImage(finalImage.scaledToWidth(ui->lblFinalImage->width())));
    }
}


void MainWindow::on_btnSaveImage_clicked(){
    if(!images.empty()){
        QPixmap out = QPixmap::grabWidget(this,361,10,481,481);
        QString fname = QFileDialog::getSaveFileName(this, tr("Save Edited Image"), (""), tr("PNG (*.png)" ));
        finalImage.save(fname, "PNG");
    }
}


void MainWindow::on_actLoad_Images_triggered(){
    on_btnLoadImages_clicked();
}


void MainWindow::on_actRemoveNoise_triggered(){
    on_btnRemoveNoise_clicked();
}


void MainWindow::on_actSaveImage_triggered(){
    on_btnSaveImage_clicked();
}
