#include "capturethread.h"

#ifdef Q_OS_WIN32
#include "qhyccd.h"
#elif defined(Q_OS_LINUX)
#include <libqhy/qhyccd.h>
#elif defined(Q_OS_MAC)
#include <qhyccd.h>
#endif

#include "mystruct.h"
#include "mydef.h"
#include "toolsclass.h"

#include <QDebug>
#include <QImage>
#include <QQueue>
#include <QPainter>
#include <QMutex>
#include <QDateTime>

extern QQueue<QImage> frameQueue;
extern QQueue<QImage> roiEnlargeImgQueue;
//extern int frameCounter;
extern QMutex capImgMutex;
extern QMutex roiImgMutex;
extern QMutex updateFPSMutex;

extern ToolsClass myTools;

extern qhyccd_handle *camhandle;
extern cv::Mat *inputImg;
extern cv::Mat *displayImg;
extern cv::Mat *enlarge5Img;
extern cv::Mat *enlarge5Img_color;
extern cv::Mat *enlargeRoiImg;

extern double curAxisX;
extern double curAxisY;
extern int curRadius;
extern double curEptPolarisX;
extern double curEptPolarisY;
extern double curPoleX;
extern double curPoleY;
extern double starA_area_X;  //star A area center point
extern double starA_area_Y;
extern double starB_area_X;  //star B area center point
extern double starB_area_Y;
extern double curXStarA;  //star A precise point
extern double curYStarA;
extern double curXStarB;  //star B precise point
extern double curYStarB;
extern double curAngleA;
extern double curAngleB;

extern bool showingAxisCenter;
extern bool showingValidateCircle;
extern bool showingEptPolaris;
extern bool showingPole;
extern bool showingRefStarA;
extern bool showingRefStarB;

extern double increAngle;
extern QString viewStyle;

extern float latitude;   //parameters to hold the AstroRefraction values
extern float longitude;
extern float presure;
extern float temperature;
extern bool enabledAstroRefCorrect;
extern QString presureUnit;

CaptureThread::CaptureThread(QObject *parent) :
    QThread(parent)
{
    stopWork = false;

    disQImg = NULL;
    roiBiggerImg = NULL;

    disQImg = new QImage(1280, 960, QImage::Format_RGB888);
    roiBiggerImg = new QImage(200, 200, QImage::Format_RGB888);
}

QImage *CaptureThread::MatToQImage(const cv::Mat *matImage)
{
    QImage *image = NULL;

    if (!matImage || matImage->empty())
    {
        qCritical() << "MatToQImage: Input Mat is null or empty.";
        return NULL;
    }

    if (matImage->depth() == CV_8U)
    {
        if (matImage->channels() == 1)
        {
            // Grayscale 8-bit
            image = new QImage(matImage->data, matImage->cols, matImage->rows, matImage->step, QImage::Format_Indexed8);
        }
        else if (matImage->channels() == 3)
        {
            // BGR 8-bit (OpenCV default for color images)
            // QImage expects RGB, so we need to convert BGR to RGB
            cv::Mat rgbImage;
            cv::cvtColor(*matImage, rgbImage, cv::COLOR_BGR2RGB);
            image = new QImage(rgbImage.data, rgbImage.cols, rgbImage.rows, rgbImage.step, QImage::Format_RGB888);
        }
        else
        {
            qCritical() << "MatToQImage: image format is not supported : depth=8U and channels=" << QString::number(
                            matImage->channels());
        }
    }
    else
    {
        qCritical() << "MatToQImage: image format is not supported : depth=" << matImage->depth();
    }

    return image;
}

void CaptureThread::stopThread()
{
    stopWork = true;
}

void CaptureThread::startThread()
{
    stopWork = false;
    this->start();
}

void CaptureThread::run()
{
    qDebug() << "CaptureThread start...";

    if(camparam.isConnected)
    {
        uint32_t ret = QHYCCD_ERROR;

        //        // set color mode
        //        ret = IsQHYCCDControlAvailable(camhandle, CAM_IS_COLOR);
        //        if (ret == QHYCCD_SUCCESS)
        //        {
        //            ret = SetQHYCCDDebayerOnOff(camhandle, false);
        //            if(ret == QHYCCD_ERROR)
        //            {
        //                qDebug() << "SetQHYCCDDebayerOnOff false";
        //            }
        //        }

        //        //set bits mode
        //        ret = SetQHYCCDBitsMode(camhandle, camparam.bitsmode);
        //        if(ret == QHYCCD_SUCCESS)
        //        {
        //            qDebug() << "SetQHYCCDBitsMode" << camparam.bitsmode;
        //        }

        //        //set binning
        //        ret = SetQHYCCDBinMode(camhandle, camparam.xbin, camparam.ybin);
        //        if(ret == QHYCCD_SUCCESS)
        //        {
        //            qDebug() << "SetQHYCCDBinMode" << camparam.xbin << camparam.ybin;
        //        }

        //        // set resolution
        //        ret = SetQHYCCDResolution(camhandle, camparam.startX, camparam.startY, camparam.NumX, camparam.NumY);
        //        if (ret == QHYCCD_SUCCESS)
        //        {
        //            qDebug() << "SetQHYCCDResolution" << camparam.startX << camparam.startY << camparam.NumX << camparam.NumY;
        //        }

        //        // set parameters
        //        ret = SetQHYCCDParam(camhandle, CONTROL_EXPOSURE, camparam.exptime);
        //        if (ret == QHYCCD_SUCCESS)
        //        {
        //            qDebug() << "SetQHYCCDParam CONTROL_EXPOSURE" << camparam.exptime;
        //            camparam.lastexptime = camparam.exptime;
        //        }

        //        ret = SetQHYCCDParam(camhandle, CONTROL_GAIN, camparam.gain);
        //        if (ret == QHYCCD_SUCCESS)
        //        {
        //            qDebug() << "SetQHYCCDParam CONTROL_GAIN" << camparam.gain;
        //            camparam.lastgain = camparam.gain;
        //        }

        //        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_OFFSET);
        //        if(ret == QHYCCD_SUCCESS)
        //        {
        //            ret = SetQHYCCDParam(camhandle, CONTROL_OFFSET, 10);
        //        }

        //        ret = SetQHYCCDParam(camhandle, CONTROL_USBTRAFFIC, camparam.usbtraffic);
        //        if (ret == QHYCCD_SUCCESS)
        //        {
        //            qDebug() << "SetQHYCCDParam CONTROL_USBTRAFFIC" << camparam.usbtraffic;
        //            camparam.lastusbtraffic = camparam.usbtraffic;
        //        }

        //        ret = SetQHYCCDParam(camhandle, CONTROL_SPEED, camparam.speed);
        //        if (ret == QHYCCD_SUCCESS)
        //        {
        //            qDebug() << "SetQHYCCDParam CONTROL_SPEED" << camparam.speed;
        //            camparam.lastspeed = camparam.speed;
        //        }

        //        // Gain R
        //        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_WBR);
        //        if(ret == QHYCCD_SUCCESS)
        //        {
        //            ret = SetQHYCCDParam(camhandle, CONTROL_WBR, 20.0);
        //        }

        //        // Gain G
        //        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_WBG);
        //        if(ret == QHYCCD_SUCCESS)
        //        {
        //            ret = SetQHYCCDParam(camhandle, CONTROL_WBG, 20.0);
        //        }

        //        // Gain B
        //        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_WBB);
        //        if(ret == QHYCCD_SUCCESS)
        //        {
        //            ret = SetQHYCCDParam(camhandle, CONTROL_WBB, 20.0);
        //        }

        //        // Brightness
        //        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_BRIGHTNESS);
        //        if(ret == QHYCCD_SUCCESS)
        //        {
        //            ret = SetQHYCCDParam(camhandle, CONTROL_BRIGHTNESS, 0.0);
        //        }

        //        // Contrast
        //        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_CONTRAST);
        //        if(ret == QHYCCD_SUCCESS)
        //        {
        //            ret = SetQHYCCDParam(camhandle, CONTROL_CONTRAST, 0.0);
        //        }

        //        // Gamma
        //        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_GAMMA);
        //        if(ret == QHYCCD_SUCCESS)
        //        {
        //            ret = SetQHYCCDParam(camhandle, CONTROL_GAMMA, 1.0);
        //        }

        // begin exposure
        ret = BeginQHYCCDLive(camhandle);
        if (ret == QHYCCD_SUCCESS)
        {
            camparam.t_start = QDateTime::currentDateTime().toMSecsSinceEpoch();

            while(!stopWork)
            {
                // get frame
                ret = GetQHYCCDLiveFrame(camhandle, &camparam.NumX, &camparam.NumY, &camparam.bpp, &camparam.channels, camparam.rawArray);
                if (ret == QHYCCD_SUCCESS)
                {
                    updateFPSMutex.lock();
                    camparam.t_end = QDateTime::currentDateTime().toMSecsSinceEpoch();
                    double fps = 1000.0 / (double)(camparam.t_end - camparam.t_start);
                    camparam.fps_1 = (int)fps;
                    camparam.fps_2 = (int)(fps * 10.0) - camparam.fps_1 * 10;
                    camparam.t_start = QDateTime::currentDateTime().toMSecsSinceEpoch();
                    updateFPSMutex.unlock();

                    //frameCounter++;
#if 0
                    //use simalutor stars image
                    if(!inputImg)
                    {
                        qCritical() << "No simulator stars Image...";
                        break;
                    }
#else
                    // Create a cv::Mat from the raw data
                    *inputImg = cv::Mat(camparam.NumY, camparam.NumX, CV_MAKETYPE(CV_8U, camparam.channels), camparam.rawArray);
#endif
                    //copy imagedata to displayImg
                    if (inputImg->channels() == 3)
                        inputImg->copyTo(*displayImg);
                    else
                        cv::cvtColor(*inputImg, *displayImg, cv::COLOR_GRAY2RGB);

                    if(showingPole)
                    {
                        uint32_t retVal = RETURE_ERROR;
                        //get starA precise point
                        retVal = myTools.GetPreciseStarPos(inputImg, starA_area_X, starA_area_Y, &curXStarA, &curYStarA);
                        if(retVal == RETURE_ERROR)
                        {
                            curXStarA = starA_area_X;
                            curYStarA = starA_area_Y;
                        }
                        //get starB precise point
                        retVal = myTools.GetPreciseStarPos(inputImg, starB_area_X, starB_area_Y, &curXStarB, &curYStarB);
                        if(retVal == RETURE_ERROR)
                        {
                            curXStarB = starB_area_X;
                            curYStarB = starB_area_Y;
                        }
                        //Astronomical Refraction correction for StarA
                        if(enabledAstroRefCorrect)
                        {
                            if(presureUnit.compare("hPa") == 0)
                            {
                                myTools.CorrectAtmRefraction(curYStarA, latitude, presure / 10.0, temperature, &curYStarA);
                                myTools.CorrectAtmRefraction(curYStarB, latitude, presure / 10.0, temperature, &curYStarB);
                            }
                            else
                            {
                                myTools.CorrectAtmRefraction(curYStarA, latitude, presure / 10.0, temperature, &curYStarA);
                                myTools.CorrectAtmRefraction(curYStarB, latitude, presure / 10.0, temperature, &curYStarB);
                            }
                        }

                        // get the pole position
                        retVal = myTools.CalcPoleCOOR(curXStarA, curYStarA, curAngleA, curXStarB, curYStarB, curAngleB,
                                                      &curPoleX, &curPoleY, curAxisX, curAxisY);
                        if (retVal == RETURE_SUCCESS)
                        {
                            cv::resize(*inputImg, *enlarge5Img, enlarge5Img->size()); // resize
                            cv::cvtColor(*enlarge5Img, *enlarge5Img_color, cv::COLOR_GRAY2RGB); // to color

                            cv::Scalar poleColor, axisColor;
                            if(viewStyle.compare("Mono") == 0)
                            {
                                poleColor = cv::Scalar(255, 248, 248); // BGR for white
                                axisColor = cv::Scalar(255, 248, 248); // BGR for white
                            }
                            else
                            {
                                poleColor = cv::Scalar(0, 255, 0); // BGR for green
                                axisColor = cv::Scalar(255, 0, 0); // BGR for blue
                            }

                            //sign circle center
                            cv::circle(*enlarge5Img_color, cv::Point(curAxisX * 5, curAxisY * 5), 1,  axisColor, -1, cv::LINE_AA);
                            cv::circle(*enlarge5Img_color, cv::Point(curAxisX * 5, curAxisY * 5), 8,  axisColor, 1, cv::LINE_AA);
                            cv::line(*enlarge5Img_color, cv::Point(curAxisX * 5 - 11, curAxisY * 5), cv::Point(curAxisX * 5 - 6, curAxisY * 5),
                                     axisColor);
                            cv::line(*enlarge5Img_color, cv::Point(curAxisX * 5 + 11, curAxisY * 5), cv::Point(curAxisX * 5 + 6, curAxisY * 5),
                                     axisColor);
                            cv::line(*enlarge5Img_color, cv::Point(curAxisX * 5, curAxisY * 5 - 11), cv::Point(curAxisX * 5, curAxisY * 5 - 6),
                                     axisColor);
                            cv::line(*enlarge5Img_color, cv::Point(curAxisX * 5, curAxisY * 5 + 11), cv::Point(curAxisX * 5, curAxisY * 5 + 6),
                                     axisColor);
                            //sign pole position
                            cv::circle(*enlarge5Img_color, cv::Point(curPoleX * 5, curPoleY * 5), 2, poleColor, -1, cv::LINE_AA); // 标极点
                            cv::line(*enlarge5Img_color, cv::Point(curPoleX * 5 - 11, curPoleY * 5), cv::Point(curPoleX * 5 + 11, curPoleY * 5),
                                     poleColor);
                            cv::line(*enlarge5Img_color, cv::Point(curPoleX * 5, curPoleY * 5 - 11), cv::Point(curPoleX * 5, curPoleY * 5 + 11),
                                     poleColor);
                            cv::line(*enlarge5Img_color, cv::Point(curPoleX * 5 - 9, curPoleY * 5 - 9), cv::Point(curPoleX * 5 - 9, curPoleY * 5 - 4),
                                     poleColor);
                            cv::line(*enlarge5Img_color, cv::Point(curPoleX * 5 - 9, curPoleY * 5 - 9), cv::Point(curPoleX * 5 - 4, curPoleY * 5 - 9),
                                     poleColor);
                            cv::line(*enlarge5Img_color, cv::Point(curPoleX * 5 + 9, curPoleY * 5 - 9), cv::Point(curPoleX * 5 + 9, curPoleY * 5 - 4),
                                     poleColor);
                            cv::line(*enlarge5Img_color, cv::Point(curPoleX * 5 + 9, curPoleY * 5 - 9), cv::Point(curPoleX * 5 + 4, curPoleY * 5 - 9),
                                     poleColor);
                            cv::line(*enlarge5Img_color, cv::Point(curPoleX * 5 + 9, curPoleY * 5 + 9), cv::Point(curPoleX * 5 + 9, curPoleY * 5 + 4),
                                     poleColor);
                            cv::line(*enlarge5Img_color, cv::Point(curPoleX * 5 + 9, curPoleY * 5 + 9), cv::Point(curPoleX * 5 + 4, curPoleY * 5 + 9),
                                     poleColor);
                            cv::line(*enlarge5Img_color, cv::Point(curPoleX * 5 - 9, curPoleY * 5 + 9), cv::Point(curPoleX * 5 - 9, curPoleY * 5 + 4),
                                     poleColor);
                            cv::line(*enlarge5Img_color, cv::Point(curPoleX * 5 - 9, curPoleY * 5 + 9), cv::Point(curPoleX * 5 - 4, curPoleY * 5 + 9),
                                     poleColor);

                            //roi the image
                            cv::Rect roi(curAxisX * 5 - 100, curAxisY * 5 - 100, 200, 200);
                            *enlargeRoiImg = (*enlarge5Img_color)(roi);

#if 1 // Changed from 0 to 1 to enable MatToQImage
                            if(roiBiggerImg)
                            {
                                delete roiBiggerImg;
                                roiBiggerImg = NULL;
                            }
                            roiBiggerImg = MatToQImage(enlargeRoiImg); // Use enlargeRoiImg (cv::Mat*)
#else
                            // Original memcpy, now replaced by MatToQImage
                            // memcpy(roiBiggerImg->bits(), enlargeRoiImg->imageData, enlargeRoiImg->imageSize);
#endif
                            roiImgMutex.lock();
                            //if(roiBiggerImg && roiEnlargeImgQueue.length() < 2)
                            if(!roiBiggerImg->isNull() && roiEnlargeImgQueue.length() < 2)
                            {
                                roiEnlargeImgQueue.enqueue(*roiBiggerImg);
                            }
                            roiImgMutex.unlock();
                        }
                    }

#if 1 // Changed from 0 to 1 to enable MatToQImage
                    if(disQImg)
                    {
                        delete disQImg;
                        disQImg = NULL;
                    }
                    disQImg = MatToQImage(displayImg); // Use displayImg (cv::Mat*)

                    if(disQImg)
#else
                    // Original memcpy, now replaced by MatToQImage
                    // memcpy(disQImg->bits(), displayImg->imageData, displayImg->imageSize);
                    if(!disQImg->isNull())
#endif
                    {
                        QPainter painter;
                        if(painter.begin(disQImg))
                        {
                            painter.setRenderHint(QPainter::Antialiasing, true);

                            //axis center
                            if(showingAxisCenter)
                            {
                                if(viewStyle.compare("Mono") == 0)
                                    painter.setPen(QPen(Qt::white, 0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
                                else
                                    painter.setPen(QPen(Qt::red, 0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
                                painter.drawEllipse(QPointF(curAxisX, curAxisY), 1, 1);
                                painter.drawEllipse(QPointF(curAxisX, curAxisY), 4, 4);
                                painter.drawLine(QPointF(curAxisX - 7, curAxisY), QPointF(curAxisX - 3, curAxisY));
                                painter.drawLine(QPointF(curAxisX + 7, curAxisY), QPointF(curAxisX + 3, curAxisY));
                                painter.drawLine(QPointF(curAxisX, curAxisY - 7), QPointF(curAxisX, curAxisY - 3));
                                painter.drawLine(QPointF(curAxisX, curAxisY + 7), QPointF(curAxisX, curAxisY + 3));
                            }

                            //validate circle
                            if(showingValidateCircle)
                            {
                                if(viewStyle.compare("Mono") == 0)
                                    painter.setPen(QPen(QColor(255, 255, 255, 178), 0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
                                else
                                    painter.setPen(QPen(QColor(0, 255, 0, 178), 0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
                                painter.drawEllipse(QPointF(curAxisX, curAxisY), curRadius, curRadius);
                            }

                            //expect polaris
                            if(showingEptPolaris)
                            {
                                painter.setPen(QPen(Qt::white, 0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
                                painter.drawLine(QPointF(curEptPolarisX - 3, curEptPolarisY), QPointF(curEptPolarisX + 3, curEptPolarisY));
                                painter.drawLine(QPointF(curEptPolarisX, curEptPolarisY - 3), QPointF(curEptPolarisX, curEptPolarisY + 3));
                                painter.drawArc(QRectF(curEptPolarisX - 10, curEptPolarisY - 10, 20, 20), (18 + increAngle) * 16, 54 * 16);
                                painter.drawArc(QRectF(curEptPolarisX - 10, curEptPolarisY - 10, 20, 20), (108 + increAngle) * 16, 54 * 16);
                                painter.drawArc(QRectF(curEptPolarisX - 10, curEptPolarisY - 10, 20, 20), (198 + increAngle) * 16, 54 * 16);
                                painter.drawArc(QRectF(curEptPolarisX - 10, curEptPolarisY - 10, 20, 20), (288 + increAngle) * 16, 54 * 16);
                            }

                            //reference starA
                            if(showingRefStarA)
                            {
                                painter.setPen(QPen(Qt::white, 0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
                                painter.drawLine(QPointF(curXStarA - 5, curYStarA), QPointF(curXStarA + 5, curYStarA));
                                painter.drawLine(QPointF(curXStarA, curYStarA - 5), QPointF(curXStarA, curYStarA + 5));
                                painter.drawRect(QRectF(curXStarA - 20, curYStarA - 20, 40, 40));
                            }
                            //reference starB
                            if(showingRefStarB)
                            {
                                painter.setPen(QPen(Qt::white, 0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
                                painter.drawLine(QPointF(curXStarB - 5, curYStarB), QPointF(curXStarB + 5, curYStarB));
                                painter.drawLine(QPointF(curXStarB, curYStarB - 5), QPointF(curXStarB, curYStarB + 5));
                                painter.drawRect(QRectF(curXStarB - 20, curYStarB - 20, 40, 40));
                            }

                            //pole
                            if(showingPole)
                            {
                                if(viewStyle.compare("Mono") == 0)
                                    painter.setPen(QPen(Qt::white, 0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
                                else
                                    painter.setPen(QPen(Qt::green, 0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
                                painter.drawEllipse(QPointF(curPoleX, curPoleY), 1, 1);
                                painter.drawLine(QPointF(curPoleX - 8, curPoleY), QPointF(curPoleX + 8, curPoleY));
                                painter.drawLine(QPointF(curPoleX, curPoleY - 8), QPointF(curPoleX, curPoleY + 8));
                                painter.drawLine(QPointF(curPoleX - 6, curPoleY - 6), QPointF(curPoleX - 6, curPoleY - 3));
                                painter.drawLine(QPointF(curPoleX - 6, curPoleY - 6), QPointF(curPoleX - 3, curPoleY - 6));
                                painter.drawLine(QPointF(curPoleX + 6, curPoleY - 6), QPointF(curPoleX + 6, curPoleY - 3));
                                painter.drawLine(QPointF(curPoleX + 6, curPoleY - 6), QPointF(curPoleX + 3, curPoleY - 6));
                                painter.drawLine(QPointF(curPoleX + 6, curPoleY + 6), QPointF(curPoleX + 6, curPoleY + 3));
                                painter.drawLine(QPointF(curPoleX + 6, curPoleY + 6), QPointF(curPoleX + 3, curPoleY + 6));
                                painter.drawLine(QPointF(curPoleX - 6, curPoleY + 6), QPointF(curPoleX - 6, curPoleY + 3));
                                painter.drawLine(QPointF(curPoleX - 6, curPoleY + 6), QPointF(curPoleX - 3, curPoleY + 6));
                            }

                            painter.end();
                        }

                        capImgMutex.lock();
                        //Adds one frame in Queue
                        if(frameQueue.length() < 2)
                        {
                            frameQueue.enqueue(*disQImg);
                        }
                        capImgMutex.unlock();
                    }
                }
                else
                {
                    usleep(10000);
                }

                //                //------if exp or gain changed
                //                if(camparam.lastexptime != camparam.exptime)
                //                {
                //                    ret = SetQHYCCDParam(camhandle, CONTROL_EXPOSURE, camparam.exptime);
                //                    if (ret == QHYCCD_SUCCESS)
                //                    {
                //                        qDebug() << "SetQHYCCDParam CONTROL_EXPOSURE" << camparam.exptime;
                //                        camparam.lastexptime = camparam.exptime;
                //                    }
                //                    else
                //                    {
                //                        qCritical() << "SetQHYCCDParam CONTROL_EXPOSURE" << camparam.exptime << "Failure.";
                //                    }
                //                }
                //                if(camparam.lastgain != camparam.gain)
                //                {
                //                    ret = SetQHYCCDParam(camhandle, CONTROL_GAIN, camparam.gain);
                //                    if (ret == QHYCCD_SUCCESS)
                //                    {
                //                        qDebug() << "SetQHYCCDParam CONTROL_GAIN" << camparam.gain;
                //                        camparam.lastgain = camparam.gain;
                //                    }
                //                    else
                //                    {
                //                        qCritical() << "SetQHYCCDParam CONTROL_GAIN" << camparam.gain << "Failure";
                //                    }
                //                }
                //                if(camparam.lastusbtraffic != camparam.usbtraffic)
                //                {
                //                    ret = SetQHYCCDParam(camhandle, CONTROL_USBTRAFFIC, camparam.usbtraffic);
                //                    if (ret == QHYCCD_SUCCESS)
                //                    {
                //                        qDebug() << "SetQHYCCDParam CONTROL_USBTRAFFIC" << camparam.usbtraffic;
                //                        camparam.lastusbtraffic = camparam.usbtraffic;
                //                    }
                //                    else
                //                    {
                //                        qCritical() << "SetQHYCCDParam CONTROL_USBTRAFFIC" << camparam.usbtraffic << "Failure";
                //                    }
                //                }
                //                if(camparam.lastspeed != camparam.speed)
                //                {
                //                    ret = SetQHYCCDParam(camhandle, CONTROL_SPEED, camparam.speed);
                //                    if (ret == QHYCCD_SUCCESS)
                //                    {
                //                        qDebug() << "SetQHYCCDParam CONTROL_SPEED" << camparam.speed;
                //                        camparam.lastspeed = camparam.speed;
                //                    }
                //                    else
                //                    {
                //                        qCritical() << "SetQHYCCDParam CONTROL_SPEED" << camparam.speed << "Failure";
                //                    }
                //                }
            }
        }
        else
        {
            qCritical() << "BeginQHYCCDLive failure";
        }
    }

    qDebug() << "CaptureThread done";
}
