#include "qrtspthread.h"



#include <QOpenGLTexture>
#include "qgstreamerplayer.h"
//#include "qgstreamerplayer2.h"

#include "mainwindow.h"

#include "common.h"

QRTSPThread::QRTSPThread()
{

    m_bStartRTSP = false;

    m_stop = false;

    m_nCurrentState = -1;

    m_pVideoWidget = NULL;

    m_bTerminate = false;

    m_pPlayer = NULL;

    m_nCaptureIndex = 0;

    SetCameraMode(true);
}

QRTSPThread::~QRTSPThread()
{
    //SAFE_DELETE(m_pPlayer);
}

void QRTSPThread::SetVideoWidget(QVideoWidget* pWidget)
{
    m_pVideoWidget = pWidget;
    //m_pPlayer->SetVideoWidget(pWidget);
}

void QRTSPThread::SaveFile(QString strFilename)
{
    if(m_pPlayer!=NULL)
    {
        m_pPlayer->SetCaptureMode(1);
    }

    //Pause();

    m_strVideoFilename = strFilename;

    m_pPlayer->SaveFile(strFilename);

    //Resume();

    return;
}

void QRTSPThread::SaveEnd()
{
    int nCaptureMode = GetCaptureMode();

    if(nCaptureMode==1)
    {
        m_pPlayer->SaveEnd();

        SetCaptureMode(0);
    }

    CommonData* pCommonData = MainWindow::GetCommonData();
    pCommonData->SetEncodingVideo(false);

    /*
    m_pPlayer->StopRTSP();
    while(m_pPlayer->IsWorkingRTSP()==true)
    {
        usleep(10*1000);
    }
    */

    usleep(100*1000);

    //m_nCurrentState = 0;






    //m_nCurrentState = 0;
}

void QRTSPThread::SetCameraMode(bool bMode)
{
    m_bCameraMode = bMode;
}

void QRTSPThread::SetOpenFilename(QString strFilename)
{
    m_strFilename = strFilename;
}


void QRTSPThread::stop()
{
    qDebug()<<"Thread::stop called from main thread: "<<currentThreadId();

    if(m_nCurrentState==0)
    {
        StopRTSP();

        m_stop=true;

        QMutexLocker locker(&m_mutex);
    }


}

void QRTSPThread::run()
{
    qDebug()<<"From worker thread: "<<currentThreadId();
    usleep(10*1000);
    while (m_stop==false)
    {

        //QMutexLocker locker(&m_mutex);
        if (m_stop) break;

        if(m_nCurrentState==0)
        {
            int nRet = InitRTSP();

            if(m_nCurrentState==0)
            {
                m_nCurrentState = 0;
            }
            else
            {
                int a=0;
            }

            /*
            if(nRet>=0)
            {
                m_nCurrentState = 11;
            }
            else
            {
                //Error
                if(m_nCurrentState==0)
                {
                    m_nCurrentState = 0;
                }

            }
            */
        }
        else if(m_nCurrentState==6)
        {
            //int nRet = InitRTSP_VideoCapture();
            int nRet = InitRTSP();

            if(nRet>=0)
            {
                m_nCurrentState = 11;
            }
            else
            {
                //Error
                if(m_nCurrentState==6)
                {
                    m_nCurrentState = 0;
                }
            }
        }
        else if(m_nCurrentState==1)
        {
            m_nCurrentState = 11;
            StopRTSP();

        }
        else if(m_nCurrentState==2)
        {

        }
        else if(m_nCurrentState==3)
        {
            if(m_pPlayer!=NULL)
            {
                delete m_pPlayer;
                m_pPlayer = NULL;
            }
            m_nCurrentState = 2;
        }
        else if(m_nCurrentState==5)
        {
            m_pPlayer->SetCaptureMode(1);
            qDebug() << m_strParameterMPEG;

            //usleep(1000*1000);
            m_pPlayer->OpenCamera4(m_strParameterMPEG);
            m_pVideoWidget->show();

            m_nCurrentState = 11;
        }
        else if(m_nCurrentState==1000)
        {
            break;
        }
        else
        {
            usleep(100*1000);
        }



    }

    SAFE_DELETE(m_pPlayer);

    qDebug()<<"Stop worker thread: "<<currentThreadId();
    usleep(10*1000);

    m_nCurrentState = -1;
    return;
    qDebug()<<"From worker thread: "<<currentThreadId();
    usleep(10*1000);
    while (m_stop==false)
    {

        //QMutexLocker locker(&m_mutex);
        if (m_stop) break;

        if(m_nCurrentState==0)
        {
            int nRet = InitRTSP();

            if(GetCaptureMode()==1) //Save Moving Picture
            {
                CommonData* pCommonData = MainWindow::GetCommonData();
                pCommonData->SetEncodingVideo(false);
                VideoButtonChange(false);
            }

            if(nRet>=0)
            {
                m_nCurrentState = 11;
                //m_nCurrentState = 0;
            }
            else
            {
                //Error
                //m_nCurrentState = 0;
                m_nCurrentState = 11;
            }
        }
        else if(m_nCurrentState==6)
        {
            int nRet = InitRTSP_VideoCapture();

            if(nRet>=0)
            {
                m_nCurrentState = 11;
            }
            else
            {
                //Error
                m_nCurrentState = 6;
            }
        }
        else if(m_nCurrentState==1)
        {
            m_nCurrentState = 11;
            StopRTSP();

        }
        else if(m_nCurrentState==2)
        {

        }
        else if(m_nCurrentState==3)
        {
            if(m_pPlayer!=NULL)
            {
                delete m_pPlayer;
                m_pPlayer = NULL;
            }
            m_nCurrentState = 2;
        }
        else if(m_nCurrentState==5)
        {
            m_pPlayer->SetCaptureMode(1);
            qDebug() << m_strParameterMPEG;


            //m_pPlayer->OpenCamera(m_strParameterMPEG);
            m_pVideoWidget->show();

            m_nCurrentState = 11;
        }
        else if(m_nCurrentState==7)
        {
            //Stream Pause
            Pause();
        }
        else if(m_nCurrentState==8)
        {
            //Stream Resume
            Resume();
        }
        else if(m_nCurrentState==1000)
        {
            break;
        }
        else
        {
            usleep(100*1000);
        }



    }

    SAFE_DELETE(m_pPlayer);

    qDebug()<<"Stop worker thread: "<<currentThreadId();
    usleep(10*1000);

    m_nCurrentState = -1;
}

bool QRTSPThread::IsStartRTSP()
{
    return m_bStartRTSP;
}


void QRTSPThread::StartRTSP()
{
    m_pPlayer->StartRTSP();
    m_bStartRTSP = true;


    return;

}


void QRTSPThread::StopRTSP()
{
    if(m_pPlayer!=NULL)
    {
        //if(IsVideoLink()==true && IsWorkingRTSP()==true)
        if(IsWorkingRTSP()==true)
        {
            //usleep(1000*100);
            m_pPlayer->StopRTSP();
            //m_pPlayer->exitRTSP();
            //usleep(1000*10);
        }

        m_bStartRTSP = false;
    }

    //m_nCurrentState = -1;

    return;
}

int QRTSPThread::GetCaptureIndex()
{
    return m_nCaptureIndex;
}

void QRTSPThread::Restart()
{
    //m_pPlayer->Pause();
    m_pPlayer->StopRTSP();
    while(m_pPlayer->IsWorkingRTSP()==true)
    {
        usleep(1*1000);
    }
    m_nCurrentState = 11;

}

int QRTSPThread::InitRTSP_VideoCapture()
{
    int nRet = 0;
    QString strParameter;

    //m_bStartRTSP = false;



    if(m_pPlayer!=NULL)
    {
        //delete m_pPlayer;

        m_pPlayer->SetCaptureMode(1);

        //nRet = m_pPlayer->OpenCamera2(m_strParameterMPEG);
        if(nRet>=0)
        {
            m_nCurrentState = 11;
        }



        return nRet;
    }


    m_pPlayer = new QGstreamerPlayer;
    //m_pPlayer = new QGstreamerPlayer2;
    QObject::connect(m_pPlayer, SIGNAL(SendFinished()), this, SLOT(ReceivedFinish()));
    m_pPlayer->SetThread(this);
    m_pPlayer->SetVideoWidget(m_pVideoWidget);
    //m_pPlayer->OpenMovieFile("1.mp4");
    //m_pPlayer->OpenMovieFile("/home/birdhead/1.mp4");

    if(m_bCameraMode==true)
    {
        m_pPlayer->SetCaptureMode(1);
        //nRet = m_pPlayer->OpenCamera(m_strParameterMPEG);
    }
    else
    {
        //m_pPlayer->OpenMovieFile(m_strFilename);
    }

    return nRet;
}


int QRTSPThread::InitRTSP()
{
    int nRet = 0;
    QString strParameter;

    //m_bStartRTSP = false;

    m_nCaptureIndex++;

    CommonData* pCommonData = MainWindow::GetCommonData();
    int nVideoWidth = pCommonData->GetVideoWidth();
    int nVideoHeight = pCommonData->GetVideoHeight();

#ifdef __x86_64
    //return 0;
    //strParameter = QString("videotestsrc name=test_src%1 ! video/x-raw,format=(string)UYVY,width=%2,height=%3,framerate=(fraction)60/1 ! timeoverlay xpad=500 ! queue name=queue_src ! videoconvert ! video/x-raw,format=(string)UYVY,width=%2,height=%3,framerate=(fraction)60/1 ! videobalance hue=0.0 name=test_VideoBalance ! queue name=queue_sink ! appsink name=test_sink").arg(QString::number(m_nCaptureIndex)).arg(QString::number(nVideoWidth)).arg(QString::number(nVideoHeight));
    strParameter = QString("v4l2src name=test_src%1 ! video/x-raw,format=(string)YUY2,width=1280,height=720,framerate=(fraction)10/1 ! queue ! videobalance hue=0.0 name=test_VideoBalance ! queue name=queue_src ! videorate ! video/x-raw,framerate=(fraction)60/1 ! queue ! videoscale ! video/x-raw,width=%2,height=%3 ! queue ! videoconvert ! video/x-raw,format=(string)UYVY ! queue name=queue_sink ! appsink name=test_sink").arg(QString::number(m_nCaptureIndex)).arg(QString::number(nVideoWidth)).arg(QString::number(nVideoHeight));
    //strParameter = QString("v4l2src name=test_src%1 ! video/x-raw,format=(string)YUY2,width=1920,height=1080,framerate=(fraction)60/1 ! queue name=queue_src ! videoconvert ! video/x-raw,format=(string)UYVY ! videobalance hue=0.0 name=test_VideoBalance ! queue name=queue_sink ! appsink name=test_sink").arg(QString::number(m_nCaptureIndex));

#else
//    strParameter = QString("nvv4l2camerasrc name=test_src%1 ! video/x-raw(memory:NVMM),format=(string)UYVY,width=1920,height=1080,framerate=(fraction)60/1 ! nvvidconv ! video/x-raw,format=(string)UYVY ! appsink name=test_sink sync=false").arg(QString::number(m_nCaptureIndex));


    //strParameter = QString("nvv4l2camerasrc name=test_src%1 ! video/x-raw(memory:NVMM),format=(string)UYVY,width=1920,height=1080,framerate=(fraction)60/1 ! nvvidconv ! video/x-raw,format=(string)RGBA ! appsink name=test_sink sync=false").arg(QString::number(m_nCaptureIndex));

    //strParameter = QString("nvv4l2camerasrc name=test_src%1 ! video/x-raw(memory:NVMM),format=(string)UYVY,width=1920,height=1080,framerate=(fraction)60/1 ! queue name=queue_src ! nvvidconv ! video/x-raw, format=(string)UYVY ! videobalance hue=0.0 name=test_VideoBalance ! queue name=queue_sink ! appsink name=test_sink sync=false").arg(QString::number(m_nCaptureIndex));

    //strParameter = QString("nvv4l2camerasrc name=test_src%1 ! video/x-raw(memory:NVMM),format=(string)UYVY,width=1920,height=1080,framerate=(fraction)60/1 ! queue name=queue_src ! nvvidconv ! video/x-raw, format=(string)UYVY ! videobalance hue=0.0 name=test_VideoBalance ! queue name=queue_sink ! appsink name=test_sink sync=false").arg(QString::number(m_nCaptureIndex));

    //Working!!
    strParameter = QString("nvv4l2camerasrc name=test_src%1 cap-buffers=10 ! video/x-raw(memory:NVMM),format=(string)UYVY,width=%2,height=%3,framerate=(fraction)60/1 ! queue name=queue_src ! nvvidconv ! video/x-raw, format=(string)UYVY ! videobalance hue=0.0 name=test_VideoBalance ! queue name=queue_sink ! appsink name=test_sink sync=false").arg(QString::number(m_nCaptureIndex)).arg(QString::number(nVideoWidth)).arg(QString::number(nVideoHeight));


    //strParameter = QString("v4l2src name=test_src%1 ! video/x-raw,format=(string)UYVY,width=1920,height=1080,framerate=(fraction)60/1 ! queue name=queue_src ! nvvidconv ! video/x-raw, format=(string)UYVY ! queue name=queue_sink ! appsink name=test_sink sync=false").arg(QString::number(m_nCaptureIndex));

#endif

    if(m_pPlayer!=NULL)
    {
        //delete m_pPlayer;

        m_pPlayer->SetCaptureMode(0);

        nRet = m_pPlayer->OpenCamera4(strParameter);
        if(nRet>=0)
        {
            //m_nCurrentState = 11;
        }



        return nRet;
    }


    m_pPlayer = new QGstreamerPlayer;
    //m_pPlayer = new QGstreamerPlayer2;
    QObject::connect(m_pPlayer, SIGNAL(SendFinished()), this, SLOT(ReceivedFinish()));
    m_pPlayer->SetThread(this);
    m_pPlayer->SetVideoWidget(m_pVideoWidget);
    //m_pPlayer->OpenMovieFile("1.mp4");
    //m_pPlayer->OpenMovieFile("/home/birdhead/1.mp4");

    if(m_bCameraMode==true)
    {
        m_pPlayer->SetCaptureMode(0);
        nRet = m_pPlayer->OpenCamera4(strParameter);
    }
    else
    {
        //m_pPlayer->OpenMovieFile(m_strFilename);
    }

    //QObject::disconnect(m_pPlayer, SIGNAL(SendFinished()), this, SLOT(ReceivedFinish()));
    //SAFE_DELETE(m_pPlayer);

    return nRet;
}

void QRTSPThread::ChangeState(int nState)
{
    if(m_nCurrentState!=nState)
    {
        if(nState==0 && m_pPlayer!=NULL)
        {

            //m_pPlayer->Resume();
        }

        if(nState==3)
        {

        }
    }
    m_nCurrentState = nState;


}


int QRTSPThread::GetState()
{
    return m_nCurrentState;
}

void QRTSPThread::ReceivedFinish()
{
    m_nCurrentState = 2;
    SendFinish();
}

void QRTSPThread::Seek(gint64 nPos)
{
    if(m_pPlayer==NULL)
    {
        return;
    }
    m_pPlayer->Seek(nPos);
}

void QRTSPThread::Pause()
{
    m_pPlayer->Pause();
}

void QRTSPThread::Resume()
{
    m_pPlayer->Resume();
}

gint64 QRTSPThread::GetSeekPos()
{
    if(m_pPlayer==NULL)
    {
        return 0;
    }
    return m_pPlayer->GetSeekPos();
}

void QRTSPThread::exitRTSP()
{
    m_nCurrentState = 1000;

    if(m_pPlayer!=NULL)
    {
        m_pPlayer->exitRTSP();
        m_bStartRTSP = false;
    }

}

bool QRTSPThread::IsWorkingRTSP()
{
    if(m_pPlayer==NULL)
    {
        return false;
    }
    return m_pPlayer->IsWorkingRTSP();
}

bool QRTSPThread::IsVideoLink()
{
    if(m_pPlayer==NULL)
    {
        return false;
    }
    return m_pPlayer->IsVideoLink();
}

void QRTSPThread::CaptureImage()
{
    if(m_pPlayer!=NULL)
    {
        m_pPlayer->CaptureImage();
    }

}

QGstreamerPlayer* QRTSPThread::GetGstreamerPlayer()
{
    return m_pPlayer;
}


void QRTSPThread::SetCaptureMode(int nMode)
{
    //0: Display
    //1: Video Encoding

    if(m_pPlayer!=NULL)
    {
        m_pPlayer->SetCaptureMode(nMode);
    }

}

gint64 QRTSPThread::GetVideoLinkTime()
{
    if(m_pPlayer==NULL)
    {
        return 0;
    }
    return m_pPlayer->GetVideoLinkTime();
}

int QRTSPThread::GetCaptureMode()
{
    if(m_pPlayer==NULL)
    {
        return 2;
    }
    return m_pPlayer->GetCaptuerMode();
}

void QRTSPThread::ExitThread()
{
    if(m_nCurrentState==0)
    {
        StopRTSP();
    }
    m_stop = true;
    while(m_nCurrentState!=-1 && m_nCurrentState!=1000)
    {
        usleep(1000*10);
    }
    SAFE_DELETE(m_pPlayer);
}


void QRTSPThread::SetVideoFilename(QString strFilename)
{
    m_strVideoFilename = strFilename;
}

QString QRTSPThread::GetVideoFilename()
{
    return m_strVideoFilename;
}

bool QRTSPThread::IsError()
{
    if(m_pPlayer==NULL)
    {
        return true;
    }
    return m_pPlayer->IsError();
}
