#include "qgvideorecorder.h"

#include <QProcess>
#include <QSettings>
#include <QDateTime>
#include <QMessageBox>
#include <QFileInfo>
#include <QUrl>
#include <QDesktopServices>

#include "qglogger.h"

/*Record via pipe to ffmpeg (python code)
app = QtGui.QApplication([])
win    = QtGui.QWidget()
layout = QtGui.QGridLayout()
win.setLayout(layout)

#picture frame
scene = QtGui.QGraphicsScene()
canvas  = QtGui.QGraphicsView(scene)
layout.addWidget(canvas,0,0)

# start button
def run():
    # set pen
    pen = QtGui.QPen(QtCore.Qt.red)
    size = canvas.size()

    # start seperate process
    process = QtCore.QProcess(app)
    process.setProcessChannelMode(process.ForwardedChannels)
    #process.setOpenMode(process.WriteOnly)
    process.start('ffmpeg',['-y', '-vcodec', 'png', '-i', '-', '-vcodec', 'mpeg4', '-qscale', '5', '-r', '24', 'video.avi',"-loglevel", "debug"])
    for i in range(100):
        x = random.randint(1, size.width()-1)
        y = random.randint(1, size.height()-1)
        scene.addLine(x,y,x,y, pen=pen)
        QtGui.QPixmap.grabWidget(win).save(process, "png")
    process.closeWriteChannel()
    process.terminate()
but_run = QtGui.QPushButton("Go!")
but_run.clicked.connect(run)
layout.addWidget(but_run,1,0)

win.show()
app.exec_()
*/
#include "AviFile.h"

static AviFile avi;
static bool use_internal;

QgVideoRecorder::QgVideoRecorder(QObject *parent) : QObject(parent)
{
    this->proc=new QProcess(this);
    this->log=new QgLogger("VCR", this);

    proc->setProcessChannelMode(QProcess::ForwardedChannels);

    connect(proc, &QProcess::errorOccurred, this, procErrorOccurred);
    //connect(proc, &QProcess::finished, this, procFinished);
    //connect(proc, &QProcess::readyReadStandardError, this, procReadyReadStandardError);
    //connect(proc, &QProcess::readyReadStandardOutput, this, procReadyReadStandardOutput);
    connect(proc, &QProcess::started, this, procStarted);
    connect(proc, &QProcess::stateChanged, this, procStateChanged);
}


void QgVideoRecorder::recStart()
{
    QSettings s("./gs_ffmpeg.ini", QSettings::IniFormat);
    s.beginGroup("FFMPEG");

    QString fbase=s.value("fname", QString("rdr_video")).toString();
    QString tfmt=s.value("time_format", QString("")).toString();

    QString out_file=fbase+QDateTime::currentDateTime().toString(tfmt)+".avi";
    s.endGroup();

    use_internal=s.value("FFMPEG").toBool() ? false : true;

    if (use_internal)
    {
        if (avi.isOpen())
        {
            avi.close();
        }
        avi.open(out_file.toLatin1().constData());
        avi.openVideoStream(25, 640, 512, 0, -1);

        return;
    }

    static const char default_cmd[]=
            ".\\ffmpeg -y -vcodec png -i - -c:v mpeg4 -qscale:v 6 -r 24 -filter:v \"crop=512:512:0:0\"";

    //FNAME="-f tee -map 0:v -map 0:v \"[f=mpegts]udp://127.0.0.1:23000|r_video\"" -> stream on file and on network (VLC for example)

    if (proc->state()==QProcess::NotRunning)
    {
        QSettings s("./gs_ffmpeg.ini", QSettings::IniFormat);
        s.beginGroup("FFMPEG");
        QString fbase=s.value("fname", QString("rdr_video")).toString();
        QString tfmt=s.value("time_format", QString("")).toString();

        QString out_file=fbase+QDateTime::currentDateTime().toString(tfmt)+".avi";

        QFileInfo finfo(out_file);
        fileName=finfo.absoluteFilePath();

        QString cmd_opt=s.value("ffmpeg",
                            QString(default_cmd)).toString(); //".\\ffmpeg -y -vcodec png -i - -vcodec mpeg4 -r 24 -filter:v \"crop=512:512:0:0\" ")).toString();
        QString cmd=cmd_opt+" "+out_file;
        log->info(cmd);
        //QStringList args;
        proc->start(cmd);//".\\ffmpeg -y -vcodec png -i - -vcodec mpeg4 -r 24 -filter:v \"crop=512:512:0:0\" video.avi -loglevel debug");
    }
}

void QgVideoRecorder::recStop()
{
    if (use_internal)
    {
        avi.close();
        return;
    }
    proc->closeWriteChannel();
    proc->terminate();
}

void QgVideoRecorder::recClose()
{
    if (use_internal)
    {
        avi.close();
        return;
    }
}


void QgVideoRecorder::addFrame(const QImage& img)
{
    if (use_internal)
    {
        if (avi.isOpen())
            avi.addVideoFrame(img.bits());
        return;
    }

    if (proc->state()==QProcess::Running)
    {
        img.save(proc, "png");
    }
}

void QgVideoRecorder::procErrorOccurred(QProcess::ProcessError error)
{
    log->info(QString("Error: %1").arg(error));
}

void QgVideoRecorder::procFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
}

void QgVideoRecorder::procReadyReadStandardError()
{
    QByteArray d=proc->readAllStandardError();
    log->info(QString(d));
}

void QgVideoRecorder::procReadyReadStandardOutput()
{
    QByteArray d=proc->readAllStandardOutput();
    log->info(QString(d));
}

void QgVideoRecorder::procStarted()
{
    log->info(QString("started"));
}

void QgVideoRecorder::procStateChanged(QProcess::ProcessState newState)
{
    log->info(QString("newState: %1").arg(newState));
    if (newState==QProcess::QProcess::NotRunning)
    {
        Q_EMIT vcrTerminated();

        //QMessageBox::information(0, "Grifo VCR", QString("<p>Video Recorder teminated:</p><b>%1</b>").arg(fileName));

        QMessageBox mb("Grifo Video VCR",
                                 QString("<p>Video Recorder teminated:</p><b>%1</b>").arg(fileName),
                                 QMessageBox::Information,
                                 QMessageBox::Ok | QMessageBox::Default |QMessageBox::Escape,
                                 QMessageBox::Reset,
                                 QMessageBox::NoButton);
                  mb.setButtonText(QMessageBox::Reset, "Open folder");
                  if (mb.exec() == QMessageBox::Reset)
                  {
                      QFileInfo finfo(fileName);
                      QDesktopServices::openUrl(QUrl(QString("file:///")+finfo.canonicalPath()));
                  }
    }
}

