#ifndef SUMMVIDEOSELECTOR_H
#define SUMMVIDEOSELECTOR_H

#include <QWidget>
#include <QFileDialog>
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QMessageBox>
#include <QThread>
#include <vector>
#include "../SummarizationFramework/Model/VideoSequence.h"
#include "../SummarizationFramework/Persistence/MatrixCsvDataSource.h"
#include "../SummarizationFramework/TubeFeatures/Features/SimpleSubtractionFeature.h"
#include "../SummarizationFramework/TubeFeatures/Processors/VideoSequenceProcessor.h"

namespace Ui {
class SummVideoSelectorModelItem;
class SummVideoSelectorModel;
class SummVideoSelector;
class SummVideoSelectorPreprocessWorkerThread;
class SummVideoSelectorPreprocessWatcherThread;
}

using namespace SummarizationFramework::Model;
using namespace SummarizationFramework::Persistence;
using namespace SummarizationFramework::TubeFeatures::Processors;
using namespace SummarizationFramework::TubeFeatures::Features;

class SummVideoSelectorModelItem : public QObject
{
    Q_OBJECT

public:
    typedef enum
    {
        Ready,
        PreprocessNeeded,
        Error
    } Status;

private:
    QString filename;
    Status status;
    void *userData;

    Status determineCurrentStatus();
    void setStatus(Status newStatus);
    void updateStatus();

public:
    SummVideoSelectorModelItem(QString filename);
    QString getFilename() const;
    QString getShortFilename() const;
    QString getPreprocessedDataFilename() const;
    bool isPreprocessed() const;
    Status getStatus() const;
    bool deletePreprocessedData();
    void *getUserData() const;
    void setUserData(void *data);

signals:
    void changed(SummVideoSelectorModelItem *item);

friend class SummVideoSelectorPreprocessWorkerThread;
};


class SummVideoSelectorModel : public QObject
{
    Q_OBJECT

public:
    typedef std::vector<SummVideoSelectorModelItem *> Items;

private:
    Items items;

public:
    SummVideoSelectorModel();
    void addItem(SummVideoSelectorModelItem *item);
    void removeItem(int idx);
    void clear();
    Items & getItems();
    static SummVideoSelectorModelItem *create(QString filename);

signals:
    void item_added(SummVideoSelectorModelItem *item);
    void item_changed(SummVideoSelectorModelItem *item);
    void item_removed(int idx);
    void changed();

private slots:
    void on_item_changed(SummVideoSelectorModelItem *item);
};


class SummVideoSelector : public QWidget
{
    Q_OBJECT

public:
    explicit SummVideoSelector(QWidget *parent = 0);
    SummVideoSelectorModelItem *itemgetCurrentItem();
    ~SummVideoSelector();
    void enableExport();

signals:
    void itemSelected(SummVideoSelectorModelItem *item);
    void exportRequested();

private slots:
    void on_model_changed();
    void on_model_item_added(SummVideoSelectorModelItem *item);
    void on_model_item_changed(SummVideoSelectorModelItem *item);
    void on_model_item_removed(int idx);
    void on_list_currentRowChanged(int currentRow);
    void on_btnImport_clicked();
    void on_btnDelete_clicked();
    void on_btnClear_clicked();
    void on_btnDeleteProcessedData_clicked();
    void on_btnProcess_clicked();
    void on_btnCancelProcess_clicked();
    void on_preprocessWorkerThread_preprocessStarted(SummVideoSelectorModelItem *item);
    void on_preprocessWorkerThread_preprocessDone(SummVideoSelectorModelItem *item);
    void on_preprocessWorkerThread_progressChanged(SummVideoSelectorModelItem *item, int progress);
    void on_btnExport_clicked();

private:
    Ui::SummVideoSelector *ui;
    SummVideoSelectorModel *model;
    SummVideoSelectorPreprocessWorkerThread *preprocessWorkerThread;
    bool removeAllMode;

    void setStateEmpty();
    void setState(SummVideoSelectorModelItem *item);
    void setStateReadyItemSelected(SummVideoSelectorModelItem *item);
    void setStateNotReadyItemSelected(SummVideoSelectorModelItem *item);
    void updateState();
    void updateRow(int idx);
    void runPreprocessWorkerThread(SummVideoSelectorModelItem *item);
    void stopPreprocessWorkerThread();
    int findListRow(SummVideoSelectorModelItem *item);
};


class SummVideoSelectorPreprocessWatcherThread : public QThread
{
    Q_OBJECT

private:
    VideoSequence *item;
    int interval;
    int progress;

signals:
    void progressChanged(int progress);

public:
    SummVideoSelectorPreprocessWatcherThread(VideoSequence *item, int interval = 500, QObject *parent = NULL);
    void run();
    void setItem(VideoSequence *item);
    void setInterval(int interval = 500);
};


class SummVideoSelectorPreprocessWorkerThread : public QThread
{
    Q_OBJECT

private:
    SummVideoSelectorModelItem *item;
    SummVideoSelectorPreprocessWatcherThread *watcherThread;

signals:
    void preprocessStarted(SummVideoSelectorModelItem *item);
    void preprocessDone(SummVideoSelectorModelItem *item);
    void progressChanged(SummVideoSelectorModelItem *item, int progress);

private slots:
    void on_watcher_progressChanged(int progress);

public:
    SummVideoSelectorPreprocessWorkerThread(SummVideoSelectorModelItem *item, QObject *parent);
    ~SummVideoSelectorPreprocessWorkerThread();
    void run();
    void terminateWatcherThread();
};

#endif // SUMMVIDEOSELECTOR_H
