#include "q_video_widget.h"
#include <qpainter>
#include <ShlObj.h>

#include "multi_ipnc_demo.h"
#include "nss_common.h"


int CALLBACK MediaStreamCallBack(NsstChannel* nsst_channel,
                                 int data_type,
                                 char* buffer,
                                 int buffer_size,
                                 int user_data)
{
    return 0;
}


QVideoWidget::QVideoWidget(QWidget *parent, const NsstChannel& nsst_channel)
    : QWidget(parent),
      nsst_channel_(nsst_channel),
      recording_(false),
      pixmap_alarm_on_(":/multi_ipnc_demo/Resources/btn_red_ball.png"),
      pixmap_alarm_off_(":/multi_ipnc_demo/Resources/btn_green_ball.png")
{
    video_form_.setupUi(this);

    border_ = new QBorderLabel(this);
    border_->setFrameShape(QFrame::NoFrame);

    video_form_.gridLayout->addWidget(border_);
    video_panel_label_ = new QVideoPanelLabel(border_,nsst_channel); 

    video_panel_label_->setFrameShape(QFrame::NoFrame);
    video_panel_label_->setMidLineWidth(0);

    QObject::connect(border_,
        SIGNAL(resize(QBorderLabel*)),
        this,
        SLOT(OnVideoBorderResize(QBorderLabel*)));

    SetRecordIcon(false);
    QObject::connect(video_form_.btnRecord,SIGNAL(clicked()),this,SLOT(OnRecordClick()));

    video_form_.btnCapture->setToolTip("Capture");
    QObject::connect(video_form_.btnCapture,SIGNAL(clicked()),this,SLOT(OnCaptureClick()));

    timer_alarm_status_ = new QTimer(this);
    QObject::connect(timer_alarm_status_,SIGNAL(timeout()),this,SLOT(OnTimerAlarmStatus()));

    timer_check_record_ = new QTimer(this);
    QObject::connect(timer_check_record_,SIGNAL(timeout()),this,SLOT(OnTimerCheckRecord()));

    video_form_.lblMotionAlarmStatus->setToolTip("Motion Alarm");
    video_form_.lblMaskAlarmStatus->setToolTip("Mask Alarm");
    video_form_.lblPortInAlarmStatus->setToolTip("Port Alarm");

    setFocusPolicy(Qt::StrongFocus);
}

QVideoWidget::~QVideoWidget()
{

}

void QVideoWidget::OnVideoBorderResize( QBorderLabel* border )
{
    video_panel_label_->setGeometry(border_->geometry().x()+1,
        border_->geometry().y()+1,
        border_->geometry().width()-2,
        border_->geometry().height()-2);
    video_form_.widgetStatus->setGeometry(video_form_.widgetStatus->geometry().x(),
        video_form_.widgetStatus->geometry().y(),
        border_->geometry().width()-2,
        border_->geometry().height());

    video_form_.lblMotionAlarmStatus->move(video_form_.widgetStatus->geometry().width()-18,
        video_form_.lblMotionAlarmStatus->pos().y());
    video_form_.lblMaskAlarmStatus->move(video_form_.widgetStatus->geometry().width()-40,
        video_form_.lblMaskAlarmStatus->pos().y());
    video_form_.lblPortInAlarmStatus->move(video_form_.widgetStatus->geometry().width()-62,
        video_form_.lblPortInAlarmStatus->pos().y());
}

void QVideoWidget::SetPanelActive()
{
    border_->SetActive(true);
}

void QVideoWidget::SetPanelNoActive()
{
    border_->SetActive(false);
}

void QVideoWidget::SetRecordIcon( bool recording )
{
    if (recording)
    {
        video_form_.btnRecord->setIcon(QIcon(":/multi_ipnc_demo/Resources/btn_record_on.png"));
        video_form_.btnRecord->setToolTip("Stop Record");
    }
    else
    {
        video_form_.btnRecord->setIcon(QIcon(":/multi_ipnc_demo/Resources/btn_record_off.png"));
        video_form_.btnRecord->setToolTip("Start Record");
    }
}

void QVideoWidget::OnRecordClick()
{
    recording_ = !recording_;
    if (recording_)
    {
        StartRecord();   
        timer_check_record_->start(5*1000);
    }
    else
    {
        StopRecord();
    }
}

void QVideoWidget::keyPressEvent( QKeyEvent *ev )
{
    emit keypress(ev->key());
}

void QVideoWidget::OnCaptureClick()
{
    QString path;
    if (GetAppDataPath(&path))
    {
        SYSTEMTIME now;
        GetLocalTime(&now); 
        char buffer[MAX_PATH];
        memset(buffer,0,MAX_PATH);
        sprintf_s(buffer,MAX_PATH,
            "\\%04d-%02d-%02d\\%s_%02d_%02d_%04d%02d%02d%02d%02d%02d%03d.jpg",
            now.wYear,
            now.wMonth,
            now.wDay,
            multi_ipnc_demo::instance()->device_info()->device_ip.toUtf8().data(),
            nsst_channel_.channel,
            nsst_channel_.stream,
            now.wYear,
            now.wMonth,
            now.wDay,
            now.wHour,
            now.wMinute,
            now.wSecond,
            now.wMilliseconds
            );
        path.append(buffer);
        int rv = NSSTLocalCapture(&nsst_channel_,path.toUtf8().data());
        if (rv != NSST_SUCCESS)
        {
            multi_ipnc_demo::instance()->ShowStatus(STATUS_LOG_ERROR,"Capture Failed!");
        }
        else
        {
            multi_ipnc_demo::instance()->ShowStatus(STATUS_LOG_NORMAL,path);
        }
    }
}

void QVideoWidget::wheelEvent( QWheelEvent * ev)
{
//    OUTPUT_DEBUG("wheelEvent : " << this << " | " << ev->delta());
    emit wheel(nsst_channel_.channel,ev->delta());
}

void QVideoWidget::OnAlarm( int type,int status )
{
    QPixmap& ic = (status == 0) ? pixmap_alarm_off_ : pixmap_alarm_on_;
    if (type == NS_ALARM_MOTION)
    {
        video_form_.lblMotionAlarmStatus->setPixmap(ic);
    }
    else if (type == NS_ALARM_MASK)
    {
        video_form_.lblMaskAlarmStatus->setPixmap(ic);
    }
    else if (type == NS_ALARM_PORTIN)
    {
        video_form_.lblPortInAlarmStatus->setPixmap(ic);
    }
    alarmtick[type] = GetTickCount();
}

void QVideoWidget::OnTimerAlarmStatus()
{
    for (unsigned i = 0;i < NS_ALARM_TYPE_COUNT;++i)
    {
        DWORD delta = GetTickCount() - alarmtick[i];
        if (delta >= 3 * 1000)
        {
            OnAlarm(i,0);
        }
    }
}

bool QVideoWidget::GetAppDataPath( QString* path )
{
//     wchar_t system_buffer[MAX_PATH];
//     system_buffer[0] = 0;

//     if (FAILED(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
//         system_buffer)))
//         return false;

// 

//     *path = QString::fromWCharArray(system_buffer);

//     path->append("\\nssdemo");

    *path = QCoreApplication::applicationDirPath();
    path->replace('/','\\');
    path->append("\\Media");
    return true;
}

void QVideoWidget::OnTimerCheckRecord()
{
    __int64 filesize;
    WIN32_FILE_ATTRIBUTE_DATA attr;
    if (!GetFileAttributesExA(record_path_.toUtf8().data(),
        GetFileExInfoStandard, &attr)) {
            return;
    }

    ULARGE_INTEGER size;
    size.HighPart = attr.nFileSizeHigh;
    size.LowPart = attr.nFileSizeLow;

    if (size.QuadPart >= 1024*1024*(100))
    {
        StartRecord();
    }
}

void QVideoWidget::StartRecord()
{
    if (GetAppDataPath(&record_path_))
    {
        SYSTEMTIME now;
        GetLocalTime(&now); 
        char buffer[MAX_PATH];
        memset(buffer,0,MAX_PATH);
        sprintf_s(buffer,MAX_PATH,
            "\\%04d-%02d-%02d\\%s_%02d_%02d_%04d%02d%02d%02d%02d%02d%03d.mp4",
            now.wYear,
            now.wMonth,
            now.wDay,
            multi_ipnc_demo::instance()->device_info()->device_ip.toUtf8().data(),
            nsst_channel_.channel,
            nsst_channel_.stream,
            now.wYear,
            now.wMonth,
            now.wDay,
            now.wHour,
            now.wMinute,
            now.wSecond,
            now.wMilliseconds
            );
        record_path_.append(buffer);
        NSSTStartRecord(&nsst_channel_,record_path_.toUtf8().data());
        multi_ipnc_demo::instance()->ShowStatus(STATUS_LOG_NORMAL,record_path_);
    }
    SetRecordIcon(recording_);
}

void QVideoWidget::StopRecord()
{
    NSSTStopRecord(&nsst_channel_);
    timer_check_record_->stop();
    SetRecordIcon(recording_);
}

void QVideoWidget::PlayVideo()
{
    DrawParams params;
    params.draw_wnd = video_panel_label_->winId();
    params.width = video_panel_label_->width();
    params.height = video_panel_label_->height();

    CloseVideo();
    if (nsst_channel_.dev_id >= 0)
    {
        NSSTStartTransport(&nsst_channel_,NSST_TCP,&params,video_form_.spbDelayLevel->value());   
        NSSTStartPlay(&nsst_channel_);
        NSSTSetMediaStreamCallback(&nsst_channel_,MediaStreamCallBack,(int)this);
        video_panel_label_->update();
    }
}

void QVideoWidget::CloseVideo()
{
    video_panel_label_->StopDrawText(0);
    video_panel_label_->StopDrawText(1);
    video_panel_label_->StopDrawText(2);

    if (nsst_channel_.dev_id >= 0)
    {
        NSSTStopPlay(&nsst_channel_);
        NSSTStopTransport(&nsst_channel_); 
    }

    StopRecord();
    video_panel_label_->update();
}

void QVideoWidget::ResetDeviceId( DEVICE_ID id )
{
    nsst_channel_.dev_id = id;
    video_panel_label_->ResetDeviceId(id);
}

void QVideoWidget::ShowFps()
{
    NSSTShowFPSOverlay(&nsst_channel_,true);
}

void QVideoWidget::CloseFps()
{
    NSSTShowFPSOverlay(&nsst_channel_,false);
}

void QVideoWidget::StartDrawText( int index,POINT* start,const QString& text )
{
    video_panel_label_->StartDrawText(index,start,text);
}

void QVideoWidget::StopDrawText(int index)
{
    video_panel_label_->StopDrawText(index);
}

void QVideoWidget::ShowAlarmGrid()
{
    video_panel_label_->ShowAlarmGrid();
}

void QVideoWidget::StopDrawAlarmGrid()
{
    video_panel_label_->StopDrawAlarmGrid();
}

void QVideoWidget::SetAllAlarmGrid( int* area )
{
    video_panel_label_->SetAllAlarmGrid(area);
}

void QVideoWidget::ClearDrawAlarmGrid()
{
    video_panel_label_->ClearDrawAlarmGrid();
}
