#include "exportwindow.h"
#include "ui_exportwindow.h"

ExportWindow::ExportWindow(QString inputFile, QString outputFile, SummarizationFramework::Model::TubeCollectionPtr tubes, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ExportWindow)
{
    ui->setupUi(this);
    ui->outputVideoNameLabel->setText(outputFile);

    worker = new ExportWindowWorkerThread(inputFile, outputFile, tubes, this);
    connect(worker, SIGNAL(started(ExportWindowWorkerThread*)), SLOT(on_worker_started(ExportWindowWorkerThread*)));
    connect(worker, SIGNAL(finished(ExportWindowWorkerThread*)), SLOT(on_worker_finished(ExportWindowWorkerThread*)));
    connect(worker, SIGNAL(progressChanged(ExportWindowWorkerThread*,QImage,int)), SLOT(on_worker_progressChanged(ExportWindowWorkerThread*,QImage,int)));
    worker->start();
}

ExportWindow::~ExportWindow()
{
    delete ui;
    delete worker;
}

void ExportWindow::terminateWorker()
{
    if(worker != NULL && worker->isRunning())
    {
        while(worker->isRunning()) {worker->terminate();}
        worker = NULL;
    }
}

void ExportWindow::on_cancelButton_clicked()
{
    close();
}

void ExportWindow::on_ExportWindow_finished(int result)
{
    Q_UNUSED(result);
    terminateWorker();
}

void ExportWindow::on_worker_started(ExportWindowWorkerThread *thread)
{
    Q_UNUSED(thread);
}

void ExportWindow::on_worker_finished(ExportWindowWorkerThread *thread)
{
    Q_UNUSED(thread);

    ui->progressBar->setValue(100);
    terminateWorker();
    close();
}

void ExportWindow::on_worker_progressChanged(ExportWindowWorkerThread *thread, QImage frame, int progress)
{
    Q_UNUSED(thread);
    Q_UNUSED(frame);

    ui->progressBar->setValue(progress);

    this->frame = frame;
    ui->frameWidget->setAlignment(Qt::AlignCenter);
    ui->frameWidget->setPixmap(QPixmap::fromImage(this->frame).scaled(ui->frameWidget->size(), Qt::KeepAspectRatio, Qt::FastTransformation));
}

void ExportWindow::resizeEvent(QResizeEvent *e)
{
    Q_UNUSED(e);

    ui->frameWidget->setAlignment(Qt::AlignCenter);
    ui->frameWidget->setPixmap(QPixmap::fromImage(this->frame).scaled(ui->frameWidget->size(), Qt::KeepAspectRatio, Qt::FastTransformation));
}

ExportWindowWorkerThread::ExportWindowWorkerThread(QString inputFile, QString outputFile, SummarizationFramework::Model::TubeCollectionPtr tubes, QObject *parent) : QThread(parent)
{
    assert(tubes != NULL);
    assert(tubes->Count() > 0);
    assert(!inputFile.isEmpty());
    assert(!outputFile.isEmpty());

    this->inputFile = inputFile;
    this->outputFile = outputFile;
    this->tubes = tubes;
}

void ExportWindowWorkerThread::run()
{
    emit started(this);

    try
    {
        SummarizationFramework::Optimization::ScenarioSolver::StaticScenarioSolverPtr scenarioSolver = new SummarizationFramework::Optimization::ScenarioSolver::StaticScenarioSolver(tubes);
        //scenarioSolver->SetMaxTubeLength(segmentLength);
        scenarioSolver->Execute();
        SummarizationFramework::Model::ScenarioPtr scenario = scenarioSolver->GetScenario();

        // get empty background video
        SummarizationFramework::Model::VideoSequencePtr videoSequence = new SummarizationFramework::Model::VideoSequence(inputFile.toStdString());
        SummarizationFramework::Model::IVideoSourcePtr background = new SummarizationFramework::Model::NullVideoSequence(videoSequence);

        // render output video
        SummarizationFramework::Presentation::IRenderer::Params rendererParams;
        rendererParams.fourcc = -1;
        rendererParams.fps = videoSequence->GetFps();

        SummarizationFramework::Presentation::StaticRendererPtr renderer = new SummarizationFramework::Presentation::StaticRenderer(rendererParams);
        renderer->SetFrameCreatedCallback(new FrameCreatedCallback(this));
        renderer->Render(scenario, background, outputFile.toStdString());
    }
    catch(...)
    {
        // TODO chyba
    }

    emit finished(this);
}

void ExportWindowWorkerThread::emitProgressChanged(QImage frame, int progress)
{
    emit progressChanged(this, frame, progress);
}

FrameCreatedCallback::FrameCreatedCallback(ExportWindowWorkerThread *worker)
{
    this->worker = worker;
}

void FrameCreatedCallback::OnFrameCreated(SummarizationFramework::Frame & frame, int no, int length)
{
    int progress = (int)((double)no/length*100.0);
    QImage frameQImage = CvVideoPlayer::matToQimage(frame);
    worker->emitProgressChanged(frameQImage, progress);
}
