#include <QPainter>
#include <QPixmap>
#include <unistd.h>
#include <QDebug>

#include "VideoDisplay.h"
#include "VideoCapture.h"
#include "VideoDecoder.h"
#include "VideoEncoder.h"
#include "CCycleBuffer.h"
#include "V4l2Capture.h"
#include "AudioCapture.h"
#include "kylinlogger_cpp.h"

VideoDisplay::VideoDisplay(QWidget *parent, KylinCameraInfo *device) : QWidget(parent)
{

    //rgb_fp = fopen("test.txt", "wb");
    m_encoder_buf = new CCycleBuffer(64*1024*1024);
    m_audio_buf = new CCycleBuffer(64*1024);
    videoCapture = new VideoCapture(m_capture_buf, device);
	if(videoCapture->v4l2Capture == NULL)
    {
        delete m_encoder_buf;
        delete m_audio_buf;
        return;
    }

    m_rgb_buf = new char[videoCapture->m_width*videoCapture->m_height*3];
    connect(videoCapture, SIGNAL(readout()), this, SIGNAL(readout()));
    videoCapture->start(QThread::HighPriority);

    videoEncoder = new VideoEncoder(m_encoder_buf, m_audio_buf, videoCapture->m_width, videoCapture->m_height, videoCapture->m_fps);
    //videoEncoder->encoder_audio_init(16000, 1, 16);
    videoEncoder->start();

    videoDecoder = new VideoDecoder(videoCapture->v4l2Capture->m_capture_buf, m_encoder_buf, videoCapture->m_width,
                                    videoCapture->m_height, videoCapture->m_buf_size,
                                    videoCapture->m_format);

    connect(videoDecoder, SIGNAL(frameReceived()), this, SLOT(update()));
    videoDecoder->start(QThread::HighestPriority);

    audioCapture = new AudioCapture(m_audio_buf);

    src_w_h_ratio = static_cast<double>(videoCapture->m_width) / static_cast<double>(videoCapture->m_height);

    m_camera_mode = photo;
    m_start_status = 1;
}

VideoDisplay::~VideoDisplay()
{
    if(videoCapture->v4l2Capture)
    {
        videoCapture->quit();
        videoDecoder->quit();

        m_encoder_buf->Empty();
        m_audio_buf->Empty();
        videoDecoder->m_quit = true;
        //delete audioCapture;
        delete videoCapture;
        delete videoDecoder;
        delete videoEncoder;
        delete m_audio_buf;
        delete m_encoder_buf;
        delete []m_rgb_buf;
        m_rgb_buf = NULL;
    }
}

void VideoDisplay::resizeEvent(QResizeEvent *event)
{
    (void)event;
    des_w_h_ratio = static_cast<double>(this->width()) / static_cast<double>(this->height());
    update();
}

void VideoDisplay::set_src_ratio(unsigned int width, unsigned int height)
{
    src_w_h_ratio = static_cast<double>(width) / static_cast<double>(height);
}

void VideoDisplay::set_background_color(QColor color)
{
    background_color = color;
}

#if 0
void VideoDisplay::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    videoEncoder->m_real_time = videoCapture->m_real_time;
    if(videoDecoder->m_pixmap.isNull()) {
  //      painter.fillRect(this->rect(), QColor(40, 40, 40));
    } else {
        m_pixmap = m_pixmap1;
    }

    int des_h = this->height();     //窗口高度
    int des_w = this->width();      //窗口寬度

    if(des_w_h_ratio >= src_w_h_ratio) {    //當窗口的寬高比>圖像的寬高比時圖像縮放後的高爲窗口的高，寬需要經過縮放
        scale_h = des_h;
        scale_w = static_cast<int>(src_w_h_ratio * des_h);
    } else {                                //反之
        scale_w = des_w;
        scale_h = static_cast<int>(des_w / src_w_h_ratio);
    }

    QPixmap temp_pixmap =m_pixmap.scaled(scale_w, scale_h);     //圖像縮放
    int adjust_pos_h = des_h - temp_pixmap.height();
    int adjust_pos_w = des_w - temp_pixmap.width();

    QRect draw_rect = this->rect();
    draw_rect.adjust(adjust_pos_w / 2, adjust_pos_h / 2, -adjust_pos_w / 2, -adjust_pos_h / 2);

    painter.fillRect(this->rect(), background_color);
    painter.drawPixmap(draw_rect, m_pixmap);
    m_pixmap1 = videoDecoder->m_pixmap;
}

#else
void VideoDisplay::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    videoEncoder->m_real_time = videoCapture->m_real_time;

    int des_h = this->height();     //窗口高度
    int des_w = this->width();      //窗口寬度

    if(des_w_h_ratio >= src_w_h_ratio) {    //當窗口的寬高比>圖像的寬高比時圖像縮放後的高爲窗口的高，寬需要經過縮放
        scale_h = des_h;
        scale_w = static_cast<int>(src_w_h_ratio * des_h);
    } else {                                //反之
        scale_w = des_w;
        scale_h = static_cast<int>(des_w / src_w_h_ratio);
    }

    //QImage temp_image =videoDecoder->m_frame.scaled(scale_w, scale_h);     //圖像縮放
    int adjust_pos_h = des_h - scale_h;
    int adjust_pos_w = des_w - scale_w;

    QRect draw_rect = this->rect();
    //draw_rect.adjust(adjust_pos_w / 2, adjust_pos_h / 2, -adjust_pos_w / 2, -adjust_pos_h / 2);

    int flag = videoDecoder->m_frame_flag ^ 1;
    painter.fillRect(this->rect(), background_color);
    painter.drawImage(draw_rect, videoDecoder->m_frame[flag]);
}

#endif
