#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "magnifierwidget.h"
#include "mydef.h"
#include "mystruct.h" // Moved to be before qhyccd.h
#include "aboutdialog.h"
#include "astrorefractiondialog.h"
#include "poletrackingdialog.h"
#include "capturethread.h"
#include "toolsclass.h"
#include "favoritedialog.h"

#include <libqhy/qhyccd.h>

#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>

#include <QMouseEvent>
#include <QScrollBar>
#include <QPainter>
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include <QDesktopServices>
#include <QUrl>
#include <QSettings>
#include <QQueue>
#include <QTimer>
#include <QDate>
#include <QMutex>
#include <QWindow>
#include <QTabBar>
#include <QValidator>
#include <QDateTime>
#include <mainwindow.h>

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

qhyccd_handle *camhandle;


struct CAMERA camparam;
struct MASKSTARDATA northStarsData;
struct MASKSTARDATA southStarsData;
ToolsClass myTools;

cv::Mat *inputImg = NULL;   //used for find star and get star position
cv::Mat *displayImg = NULL;  //hold on the display image
cv::Mat *enlarge5Img = NULL;
cv::Mat *enlarge5Img_color = NULL;
cv::Mat *enlargeRoiImg = NULL; // Reverted to cv::Mat*

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

double curAxisX;
double curAxisY;
int curRadius;

double curEptPolarisX; //current expected polaris point
double curEptPolarisY;
double curPoleX;   //current pole point
double curPoleY;

double curXStarA;  //star A precise point
double curYStarA;
double curXStarB;  //star B precise point
double curYStarB;
double curAngleA;
double curAngleB;
double starA_area_X;  //star A area center point
double starA_area_Y;
double starB_area_X;  //star A area center point
double starB_area_Y;

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

double increAngle;
QString viewStyle;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    img_magnifier = new QImage(1280, 960, QImage::Format_ARGB32);
    //create magnifier glass widget
    widget_magnifier = new MagnifierWidget(150, 150, ui->scrollArea_showImg);
    widget_magnifier->setLoupeScale(5.0);
    widget_magnifier->setLoupePixmap(QPixmap::fromImage(*img_magnifier));
    widget_magnifier->update();

    //create direction image
    label_directionImg = new QLabel(ui->scrollArea_showImg);
    label_directionImg->setGeometry(0, 130, 238, 171);
    label_directionImg->setPixmap(QPixmap(":/images/direction.png"));
    label_directionImg->setAttribute(Qt::WA_TransparentForMouseEvents);

    //create north template image
    northTemplateImg = new QImage(":/images/north_mask.png");
    //create south template image
    southTemplateImg = new QImage(":/images/south_mask.png");

    //create graphics effect and set it into horizontalSlider_confirm_match
    dropShowEffect_confirm = new QGraphicsDropShadowEffect();
    dropShowEffect_confirm->setBlurRadius(20);
    dropShowEffect_confirm->setOffset(0);
    dropShowEffect_confirm->setColor(QColor(224, 134, 26));
    dropShowEffect_confirm->setEnabled(false);
    ui->horizontalSlider_confirm_match->setGraphicsEffect(dropShowEffect_confirm);
    //create graphics effect and set it into horizontalSlider_rough_match
    dropShowEffect_rough = new QGraphicsDropShadowEffect();
    dropShowEffect_rough->setBlurRadius(20);
    dropShowEffect_rough->setOffset(0);
    dropShowEffect_rough->setColor(QColor(224, 134, 26));
    dropShowEffect_rough->setEnabled(false);
    ui->horizontalSlider_rough_match->setGraphicsEffect(dropShowEffect_rough);

    //create tip message showing widget
    createTipMsgTabWidget();

    //If exclusive is true, only one checkable action in the action group can ever be active at any time.
    zoomGroup = new QActionGroup(ui->menuZoom);
    zoomGroup->addAction(ui->action100);
    zoomGroup->addAction(ui->action75);
    zoomGroup->addAction(ui->action50);
    zoomGroup->setExclusive(true);
    ui->action100->setChecked(true);

    languageGroup = new QActionGroup(ui->menuLanguage);
    languageGroup->addAction(ui->actionEnglish);
    languageGroup->addAction(ui->actionChinese);
    languageGroup->addAction(ui->actionJapanese);
    languageGroup->addAction(ui->actionRussian);
    languageGroup->addAction(ui->actionFrench);
    languageGroup->addAction(ui->actionGerman);
    languageGroup->addAction(ui->actionSpanish);
    languageGroup->addAction(ui->actionPortuguese);
    languageGroup->addAction(ui->actionItalian);
    languageGroup->addAction(ui->actionKorean);
    languageGroup->setExclusive(true);
    ui->actionEnglish->setChecked(true);


    //status bar
    label_status_mousePos = new QLabel(this);
    label_status_mousePos->setFrameShape(QFrame::NoFrame);
    label_status_mousePos->setFixedSize(85, 18);
    label_fps = new QLabel(this);
    label_fps->setFrameShape(QFrame::NoFrame);
    label_fps->setFixedSize(85, 18);
    label_fps->setText("FPS : 0.0");
    ui->statusBar->addWidget(label_status_mousePos);
    ui->statusBar->addWidget(label_fps);

    //image show area layout
    showImgAreaLayout = new QGridLayout;
    showImgAreaLayout->addWidget(ui->label_showImg);
    showImgAreaLayout->setSpacing(0);
    showImgAreaLayout->setContentsMargins(0, 0, 0, 0);
    showImgAreaLayout->setAlignment(ui->label_showImg, Qt::AlignLeft | Qt::AlignTop);
    ui->scrollAreaWidgetContents_showImg->setLayout(showImgAreaLayout);

    ui->label_showImg->installEventFilter(this); //Installs an event filter on label_showImg

    ui->label_showImg->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    ui->label_templateImg->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    // 将自己设为鼠标事件透明并重新搜索是否有后面的控件会响应鼠标事件。
    ui->label_templateImg->setAttribute(Qt::WA_TransparentForMouseEvents);


    aboutDialog = new AboutDialog(this);
    astroRefDialog = new AstroRefractionDialog(this);
    poleTrackingDialog = new PoleTrackingDialog(this);
    favoriteDialog = new FavoriteDialog(this);

    translator = new QTranslator(this);  //create the translator object

    captureFrameThread = new CaptureThread;

    connect(this, SIGNAL(changeLanguage()), this, SLOT(languageChanged()));
    connect(this, SIGNAL(resetUI()), aboutDialog, SLOT(uiReset()));
    connect(this, SIGNAL(resetUI()), astroRefDialog, SLOT(uiReset()));
    connect(this, SIGNAL(resetUI()), poleTrackingDialog, SLOT(uiReset()));
    connect(this, SIGNAL(resetUI()), this, SLOT(uiReset()));

    connect(this, SIGNAL(initAstroRefraction()), astroRefDialog, SLOT(initValues()));

    connect(poleTrackingDialog, SIGNAL(trackPole(double)), this, SLOT(poleTracking(double)));

    updateImgTimer = new QTimer(this);
    QObject::connect(updateImgTimer, SIGNAL(timeout()), this, SLOT(showImages()));
    updateImgTimer->start(20);

    updateFPSTimer = new QTimer(this);
    QObject::connect(updateFPSTimer, SIGNAL(timeout()), this, SLOT(updateFPS()));
    updateFPSTimer->start(500);

    increaseAngleTimer = new QTimer(this);
    connect(increaseAngleTimer, SIGNAL(timeout()), this, SLOT(increaseAngleTimeout()));
    increaseAngleTimer->start(100);

    graphicsEffectTimer = new QTimer(this);
    graphicsEffectTimer->setInterval(500);
    connect(graphicsEffectTimer, SIGNAL(timeout()), this, SLOT(graphicsEffectTimeout()));
    //graphicsEffectTimer->start(500);

    //----------------------------
    //init or set with default value


    //devPixRatio = qApp->devicePixelRatio();
    //qDebug() << "device pixel ratio:" << devPixRatio;

#if 0
    QString simulatorImgPath = QCoreApplication::applicationDirPath() + "/simulator.bmp";
    if(QFile::exists(simulatorImgPath))
    {
        std::string strpath = simulatorImgPath.toStdString();
        inputImg = new cv::Mat(cv::imread(strpath, cv::IMREAD_GRAYSCALE));
    }
    else
    {
        qCritical() << "not found simulator stars image!!";
    }
#else
    inputImg = new cv::Mat(960, 1280, CV_8UC1);
#endif
    displayImg = new cv::Mat(960, 1280, CV_8UC3);
    enlarge5Img = new cv::Mat(4800, 6400, CV_8UC1);
    enlarge5Img_color = new cv::Mat(4800, 6400, CV_8UC3);
    enlargeRoiImg = new cv::Mat(200, 200, CV_8UC3); // Reverted to cv::Mat allocation

    camparam.startX = 0;
    camparam.startY = 0;
    camparam.NumX = 1280;
    camparam.NumY = 960;
    camparam.speed = 0.0;
    camparam.usbtraffic = 30.0;
    camparam.xbin = 1;
    camparam.ybin = 1;
    camparam.bitsmode = 8;
    camparam.streammode = 1;
    camparam.exptime = 20000.0; //1ms in default
    camparam.gain = 1.0;
    camparam.canUseSDK = false;
    camparam.isConnected = false;
    camparam.t_start = 0;
    camparam.t_end = 0;
    camparam.fps_1 = 0;
    camparam.fps_2 = 0;

    stepIndex = 0; //
    rotateAngle = 0;

    loadStarsData();  //load the stars data
    drawPoleOnTemplateImage(); //draw the pole on the template image. make sure you called loadStarsData and template image was exist before you call it.

    if(!loadParamFromIni())
    {
        //if load param from ini failed, then init the params.
        viewStyle = "Color";
        lang = "EN";
        region = "North";
        scaledFactor = 1.0;
        latitude = 39.9;
        longitude = 116.3;
        presure = 101.0;
        presureUnit = "kPa";
        temperature = 10.0;
        enabledAstroRefCorrect = false;
        curAxisX = 0;
        curAxisY = 0;
    }

    //init current center of template image....
    templateImgCenter.setX(640 * scaledFactor);
    templateImgCenter.setY(480 * scaledFactor);
    templateImgCenter_originalImg.setX(640);
    templateImgCenter_originalImg.setY(480);

    //init region setting and template star data...
    if(region.compare("North") == 0)
    {
        posX_pole_mask = northStarsData.poleX;
        posY_pole_mask = northStarsData.poleY;
        posX_starA_mask = northStarsData.starAX;
        posY_starA_mask = northStarsData.starAY;
        posX_starB_mask = northStarsData.starBX;
        posY_starB_mask = northStarsData.starBY;
        angleA_mask = northStarsData.angleBAP;
        angleB_mask = northStarsData.angleABP;

        ui->radioButton_north->setChecked(true);
    }
    else
    {
        posX_pole_mask = southStarsData.poleX;
        posY_pole_mask = southStarsData.poleY;
        posX_starA_mask = southStarsData.starAX;
        posY_starA_mask = southStarsData.starAY;
        posX_starB_mask = southStarsData.starBX;
        posY_starB_mask = southStarsData.starBY;
        angleA_mask = southStarsData.angleBAP;
        angleB_mask = southStarsData.angleABP;

        ui->radioButton_south->setChecked(true);
    }
    curAngleA = angleA_mask;  //init current angleA angleB
    curAngleB = angleB_mask;

    //init label_tempalteImg...
    setCurrentTemplateImg(scaledFactor, region);

    //init mono style...
    if(viewStyle.compare("Mono") == 0)
    {
        ui->actionMono_Style->setChecked(true);

        dropShowEffect_confirm->setColor(QColor(248, 248, 255)); //change graphics effect color
        dropShowEffect_rough->setColor(QColor(248, 248, 255));

        ui->label_precise_poleIcon->setPixmap(QPixmap(":/images/pole.png"));
        ui->label_precise_axisIcon->setPixmap(QPixmap(":/images/center.png"));

        ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
        ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
        ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
    }
    else
    {
        ui->actionMono_Style->setChecked(false);

        dropShowEffect_confirm->setColor(QColor(224, 134, 26)); //change graphics effect color
        dropShowEffect_rough->setColor(QColor(224, 134, 26));

        ui->label_precise_poleIcon->setPixmap(QPixmap(":/images/pole_color.png"));
        ui->label_precise_axisIcon->setPixmap(QPixmap(":/images/center_color.png"));

        ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
        ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
        ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
    }

    //init zoom...
    if(scaledFactor == 0.5)
        ui->action50->setChecked(true);
    else if(scaledFactor == 0.75)
        ui->action75->setChecked(true);
    else
        ui->action100->setChecked(true);
    //scaled the direction image
    scaledDirectionImg(scaledFactor);

    //init astroRefaction Dialog values when got the initition value form ini file...
    emit initAstroRefraction();

    //init the language menu setting....
    if(lang.compare("ZH") == 0)
        ui->actionChinese->setChecked(true);
    else if(lang.compare("JA") == 0)
        ui->actionJapanese->setChecked(true);
    else if(lang.compare("DE") == 0)
        ui->actionGerman->setChecked(true);
    else if(lang.compare("ES") == 0)
        ui->actionSpanish->setChecked(true);
    else if(lang.compare("FR") == 0)
        ui->actionFrench->setChecked(true);
    else if(lang.compare("IT") == 0)
        ui->actionItalian->setChecked(true);
    else if(lang.compare("RU") == 0)
        ui->actionRussian->setChecked(true);
    else if(lang.compare("PT") == 0)
        ui->actionPortuguese->setChecked(true);
    else if(lang.compare("KO") == 0)
        ui->actionKorean->setChecked(true);
    else
        ui->actionEnglish->setChecked(true);
    //emit the signal to retranslate the ui
    emit changeLanguage();

    //other init...
    ui->label_templateImg->hide();   //hide templateImage in default
    label_directionImg->hide();
    tabWidget_tipMsg->hide(); //hide tip message in default

    ui->actionSave_As->setEnabled(false);
    ui->actionDisplay_Template->setEnabled(false);
    ui->actionAstronomical_Refraction->setEnabled(false);
    ui->actionManual_Trace->setEnabled(false);
    ui->menuZoom->setEnabled(false);
    //hide stretch menu action
    ui->actionStretch->setVisible(false);
    ui->actionDisplay_Template->setVisible(false);
    ui->actionFavorite->setVisible(false);

    //    ui->pushButton_exp_50->setChecked(true);  //exp=50ms in default
    //    ui->pushButton_gain_50->setChecked(true);  //gain=50 in default

    ui->pushButton_head_region->setChecked(false);
    ui->pushButton_head_region->setEnabled(false);
    ui->widget_region->setVisible(false);
    ui->pushButton_head_setting->setChecked(false);
    ui->pushButton_head_setting->setEnabled(false);
    ui->widget_setting->setVisible(false);
    ui->pushButton_head_confirm->setChecked(false);
    ui->pushButton_head_confirm->setEnabled(false);
    ui->widget_confirm->setVisible(false);
    ui->pushButton_head_rough->setChecked(false);
    ui->pushButton_head_rough->setEnabled(false);
    ui->widget_rough->setVisible(false);
    ui->pushButton_head_precise->setChecked(false);
    ui->pushButton_head_precise->setEnabled(false);
    ui->widget_precise->setVisible(false);

    QRegularExpression lineEdit("[0-9]+$");
    QValidator *validatorNum = new QRegularExpressionValidator(lineEdit, this);
    ui->lineEditExpose->setValidator(validatorNum);
    ui->lineEditGain->setValidator(validatorNum);
    ui->lineEditTraffic->setValidator(validatorNum);
    ui->lineEditSpeed->setValidator(validatorNum);

    Music = new QMediaPlayer(this);//QMediaplayer用于解析音频文件和视频文件
    audioOutput = new QAudioOutput(this);
    Music->setAudioOutput(audioOutput);
    Music->setSource(QUrl("qrc:/audio/audio.mp3"));//设置音频文件
    Music->setLoops(QMediaPlayer::Infinite);//无限循环播放
    audioOutput->setVolume(0);

    uint32_t ret = InitQHYCCDResource();
    if(ret != QHYCCD_SUCCESS)
    {
        qCritical("InitQHYCCDResource: failed");
        camparam.canUseSDK = false;
    }
    else
    {
        qDebug() << "InitQHYCCDSDK success";
        camparam.canUseSDK = true;
    }

    //#ifdef Q_OS_MAC
    //    QString path = QCoreApplication::applicationDirPath();
    //    ret = OSXInitQHYCCDFirmware((char*)path.toStdString().c_str());
    //    if(ret == QHYCCD_SUCCESS)
    //    {
    //        QThread::sleep(5);
    //    }

    //#endif

}

MainWindow::~MainWindow()
{
    if(graphicsEffectTimer)
    {
        graphicsEffectTimer->deleteLater();
    }
    if(increaseAngleTimer)
    {
        increaseAngleTimer->deleteLater();
    }
    if(updateImgTimer)
    {
        updateImgTimer->deleteLater();
    }

    if(aboutDialog)
    {
        aboutDialog->deleteLater();
    }
    if(astroRefDialog)
    {
        astroRefDialog->deleteLater();
    }
    if(poleTrackingDialog)
    {
        poleTrackingDialog->deleteLater();
    }
    if(favoriteDialog)
    {
        favoriteDialog->deleteLater();
    }
    if(translator)
    {
        translator->deleteLater();
    }
    if(captureFrameThread)
    {
        delete captureFrameThread;
        captureFrameThread = NULL;
    }

    if(showImgAreaLayout)
    {
        delete showImgAreaLayout;
        showImgAreaLayout = NULL;
    }
    if(label_status_mousePos)
    {
        label_status_mousePos->deleteLater();
    }
    if(languageGroup)
    {
        languageGroup->deleteLater();
    }
    if(zoomGroup)
    {
        zoomGroup->deleteLater();
    }
    if(dropShowEffect_rough)
    {
        delete dropShowEffect_rough;
        dropShowEffect_rough = NULL;
    }
    if(dropShowEffect_confirm)
    {
        delete dropShowEffect_confirm;
        dropShowEffect_confirm = NULL;
    }
    if(southTemplateImg)
    {
        delete southTemplateImg;
        southTemplateImg = NULL;
    }
    if(northTemplateImg)
    {
        delete northTemplateImg;
        northTemplateImg = NULL;
    }
    if(label_directionImg)
    {
        label_directionImg->deleteLater();
    }
    if(widget_magnifier)
    {
        widget_magnifier->deleteLater();
    }

    if(Music)
    {
        Music->deleteLater();
    }

    if(tab_finetunePole)
    {
        delete tab_finetunePole;
        tab_finetunePole = NULL;
    }
    if(tab_calcPole)
    {
        delete tab_calcPole;
        tab_calcPole = NULL;
    }
    if(tab_getEptPolaris)
    {
        delete tab_getEptPolaris;
        tab_getEptPolaris = NULL;
    }
    if(tab_getCurPolaris)
    {
        delete tab_getCurPolaris;
        tab_getCurPolaris = NULL;
    }
    if(tab_movePolaris)
    {
        delete tab_movePolaris;
        tab_movePolaris = NULL;
    }
    if(tab_getStar3)
    {
        delete tab_getStar3;
        tab_getStar3 = NULL;
    }
    if(tab_rotateStar2)
    {
        delete tab_rotateStar2;
        tab_rotateStar2 = NULL;
    }
    if(tab_getStar2)
    {
        delete tab_getStar2;
        tab_getStar2 = NULL;
    }
    if(tab_rotateStar1)
    {
        delete tab_rotateStar1;
        tab_rotateStar1 = NULL;
    }
    if(tab_getStar1)
    {
        delete tab_getStar1;
        tab_getStar1 = NULL;
    }
    if(tab_confirm)
    {
        delete tab_confirm;
        tab_confirm = NULL;
    }
    if(tab_setting)
    {
        delete tab_setting;
        tab_setting = NULL;
    }
    if(tabWidget_tipMsg)
    {
        tabWidget_tipMsg->deleteLater();
    }

    if(inputImg)
    {
        delete inputImg;
        inputImg = NULL;
    }
    if(displayImg)
    {
        delete displayImg;
        displayImg = NULL;
    }
    if(enlarge5Img)
    {
        delete enlarge5Img;
        enlarge5Img = NULL;
    }
    if(enlarge5Img_color)
    {
        delete enlarge5Img_color;
        enlarge5Img_color = NULL;
    }
    if(enlargeRoiImg)
    {
        delete enlargeRoiImg;
        enlargeRoiImg = NULL;
    }

    delete ui;
}

void MainWindow::createTipMsgTabWidget()
{
    tabWidget_tipMsg = new QTabWidget(ui->scrollArea_showImg);
    tabWidget_tipMsg->setObjectName(QStringLiteral("tabWidget_tipMsg"));
    tabWidget_tipMsg->setGeometry(QRect(163, 5, 470, 100));
    tabWidget_tipMsg->tabBar()->hide();

    //PoleMaster setting tab
    tab_setting = new QWidget();
    tab_setting->setObjectName(QStringLiteral("tab_setting"));
    label_setting_tipMsg = new QLabel(tab_setting);
    label_setting_tipMsg->setObjectName(QStringLiteral("label_setting_tipMsg"));
    label_setting_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_setting_tipMsg->setWordWrap(true);
    label_setting_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    label_setting_tipMsg->setText(tr("Set the parameters to the left to make more stars around Polaris visable."));
    label_settiing_ask = new QLabel(tab_setting);
    label_settiing_ask->setObjectName(QStringLiteral("label_setting_ask"));
    label_settiing_ask->setGeometry(QRect(5, 70, 290, 23));
    label_settiing_ask->setText(tr("Has setting up finished?"));
    label_settiing_ask->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_settingDone = new QPushButton(tab_setting);
    pushButton_settingDone->setObjectName(QStringLiteral("pushButton_setting_done"));
    pushButton_settingDone->setGeometry(QRect(380, 70, 75, 23));
    pushButton_settingDone->setText(tr("Setting Finished"));

    tab_setting->setMouseTracking(true);
    tab_setting->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_setting, QString());

    //confirm polaris tab
    tab_confirm = new QWidget();
    tab_confirm->setObjectName(QStringLiteral("tab_confirm"));
    label_confirm_tipMsg = new QLabel(tab_confirm);
    label_confirm_tipMsg->setObjectName(QStringLiteral("label_confirm_tipMsg"));
    label_confirm_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_confirm_tipMsg->setWordWrap(true);
    label_confirm_tipMsg->setText(
        tr("Double Click Polaris and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around Polaris."));
    label_confirm_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    label_confirm_ask = new QLabel(tab_confirm);
    label_confirm_ask->setObjectName(QStringLiteral("label_confirm_ask"));
    label_confirm_ask->setGeometry(QRect(5, 70, 290, 23));
    label_confirm_ask->setText(tr("Does match success?"));
    label_confirm_ask->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_confirmDone = new QPushButton(tab_confirm);
    pushButton_confirmDone->setObjectName(QStringLiteral("pushButton_confirm_done"));
    pushButton_confirmDone->setGeometry(QRect(380, 70, 75, 23));
    pushButton_confirmDone->setText(tr("Success"));

    tab_confirm->setMouseTracking(true);
    tab_confirm->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_confirm, QString());

    //get star first position tab
    tab_getStar1 = new QWidget();
    tab_getStar1->setObjectName(QStringLiteral("tab_getStar1"));
    label_getStar1_tipMsg = new QLabel(tab_getStar1);
    label_getStar1_tipMsg->setObjectName(QStringLiteral("label_getStar1_tipMsg"));
    label_getStar1_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_getStar1_tipMsg->setWordWrap(true);
    label_getStar1_tipMsg->setText(
        tr("Choose a star other than Polaris and Double click it in the image. Remember this star, you will be selecting it again in the following steps (Step 1 of 3)."));
    label_getStar1_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);

    tab_getStar1->setMouseTracking(true);
    tab_getStar1->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_getStar1, QString());

    //rotate star first tab
    tab_rotateStar1 = new QWidget();
    tab_rotateStar1->setObjectName(QStringLiteral("tab_rotateStar1"));
    label_rotateStar1_tipMsg = new QLabel(tab_rotateStar1);
    label_rotateStar1_tipMsg->setObjectName(QStringLiteral("label_rotateStar1_tipMsg"));
    label_rotateStar1_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_rotateStar1_tipMsg->setWordWrap(true);
    label_rotateStar1_tipMsg->setText(
        tr("Rotate your mounts 'RA' axis in the direction indicated by the arrow now at the top of the screen (rotate a minimum of 30 degree's)."));
    label_rotateStar1_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    label_rotateStar1_ask = new QLabel(tab_rotateStar1);
    label_rotateStar1_ask->setObjectName(QStringLiteral("label_rotateStar1_ask"));
    label_rotateStar1_ask->setGeometry(QRect(5, 70, 290, 23));
    label_rotateStar1_ask->setText(tr("Has rotation finished?"));
    label_rotateStar1_ask->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_rotateStar1_reset = new QPushButton(tab_rotateStar1);
    pushButton_rotateStar1_reset->setObjectName(QStringLiteral("pushButton_rotateStar1_reset"));
    pushButton_rotateStar1_reset->setGeometry(QRect(300, 70, 75, 23));
    pushButton_rotateStar1_reset->setText(tr("Reset"));
    pushButton_rotateStar1_done = new QPushButton(tab_rotateStar1);
    pushButton_rotateStar1_done->setObjectName(QStringLiteral("pushButton_rotateStar1_done"));
    pushButton_rotateStar1_done->setGeometry(QRect(380, 70, 75, 23));
    pushButton_rotateStar1_done->setText(tr("rotation Finished"));

    tab_rotateStar1->setMouseTracking(true);
    tab_rotateStar1->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_rotateStar1, QString());

    //get star second position tab
    tab_getStar2 = new QWidget();
    tab_getStar2->setObjectName(QStringLiteral("tab_getStar2"));
    label_getStar2_tipMsg = new QLabel(tab_getStar2);
    label_getStar2_tipMsg->setObjectName(QStringLiteral("label_getStar2_tipMsg"));
    label_getStar2_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_getStar2_tipMsg->setWordWrap(true);
    label_getStar2_tipMsg->setText(tr("Double click the same star again chosen in the previous step (Step 2 of 3)."));
    label_getStar2_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_getStar2_reset = new QPushButton(tab_getStar2);
    pushButton_getStar2_reset->setObjectName(QStringLiteral("pushButton_getStar2_reset"));
    pushButton_getStar2_reset->setGeometry(QRect(300, 70, 75, 23));
    pushButton_getStar2_reset->setText(tr("Reset"));

    tab_getStar2->setMouseTracking(true);
    tab_getStar2->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_getStar2, QString());

    //rotate star second tab
    tab_rotateStar2 = new QWidget();
    tab_rotateStar2->setObjectName(QStringLiteral("tab_rotateStar2"));
    label_rotateStar2_tipMsg = new QLabel(tab_rotateStar2);
    label_rotateStar2_tipMsg->setObjectName(QStringLiteral("label_rotateStar2_tipMsg"));
    label_rotateStar2_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_rotateStar2_tipMsg->setWordWrap(true);
    label_rotateStar2_tipMsg->setText(tr("Again, Rotate your mounts 'RA' axis in the same direction at least 30 degrees."));
    label_rotateStar2_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    label_rotateStar2_ask = new QLabel(tab_rotateStar2);
    label_rotateStar2_ask->setObjectName(QStringLiteral("label_rotateStar2_ask"));
    label_rotateStar2_ask->setGeometry(QRect(5, 70, 290, 23));
    label_rotateStar2_ask->setText(tr("Has rotation finished?"));
    label_rotateStar2_ask->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_rotateStar2_reset = new QPushButton(tab_rotateStar2);
    pushButton_rotateStar2_reset->setObjectName(QStringLiteral("pushButton_rotateStar2_reset"));
    pushButton_rotateStar2_reset->setGeometry(QRect(300, 70, 75, 23));
    pushButton_rotateStar2_reset->setText(tr("Reset"));
    pushButton_rotateStar2_done = new QPushButton(tab_rotateStar2);
    pushButton_rotateStar2_done->setObjectName(QStringLiteral("pushButton_rotateStar2_done"));
    pushButton_rotateStar2_done->setGeometry(QRect(380, 70, 75, 23));
    pushButton_rotateStar2_done->setText(tr("rotation Finished"));

    tab_rotateStar2->setMouseTracking(true);
    tab_rotateStar2->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_rotateStar2, QString());

    //get star third tab
    tab_getStar3 = new QWidget();
    label_getStar3_tipMsg = new QLabel(tab_getStar3);
    label_getStar3_tipMsg->setObjectName(QStringLiteral("label_getStar3_tipMsg"));
    label_getStar3_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_getStar3_tipMsg->setWordWrap(true);
    label_getStar3_tipMsg->setText(
        tr("Double click the same star one last time chosen in the previous 2 steps (Step 3 of 3)."));
    label_getStar3_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_getStar3_reset = new QPushButton(tab_getStar3);
    pushButton_getStar3_reset->setObjectName(QStringLiteral("pushButton_getStar3_reset"));
    pushButton_getStar3_reset->setGeometry(QRect(300, 70, 75, 23));
    pushButton_getStar3_reset->setText(tr("Reset"));

    tab_getStar3->setMouseTracking(true);
    tab_getStar3->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_getStar3, QString());

    //validate center tab
    tab_validateCenter = new QWidget();
    tab_validateCenter->setObjectName(QStringLiteral("tab_validateCenter"));
    label_validateCenter_tipMsg = new QLabel(tab_validateCenter);
    label_validateCenter_tipMsg->setObjectName(QStringLiteral("label_validateCenter_tipMsg"));
    label_validateCenter_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_validateCenter_tipMsg->setWordWrap(true);
    label_validateCenter_tipMsg->setText(
        tr("Return the 'RA' axis to the 'Home' position - Ensure your chosen star stays on the circle while your mount rotates to the PARK position."));
    label_validateCenter_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    label_validateCenter_ask = new QLabel(tab_validateCenter);
    label_validateCenter_ask->setObjectName(QStringLiteral("label_validateCenter_ask"));
    label_validateCenter_ask->setGeometry(QRect(5, 70, 290, 23));
    label_validateCenter_ask->setText(tr("Is the axis center correct?"));
    label_validateCenter_ask->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_validateCenter_reset = new QPushButton(tab_validateCenter);
    pushButton_validateCenter_reset->setObjectName(QStringLiteral("pushButton_validateCenter_reset"));
    pushButton_validateCenter_reset->setGeometry(QRect(300, 70, 75, 23));
    pushButton_validateCenter_reset->setText(tr("Reset"));
    pushButton_validateCenter_done = new QPushButton(tab_validateCenter);
    pushButton_validateCenter_done->setObjectName(QStringLiteral("pushButton_validateCenter_done"));
    pushButton_validateCenter_done->setGeometry(QRect(380, 70, 75, 23));
    pushButton_validateCenter_done->setText(tr("Correct"));

    tab_validateCenter->setMouseTracking(true);
    tab_validateCenter->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_validateCenter, QString());

    //get expected polaris tab
    tab_getEptPolaris = new QWidget();
    tab_getEptPolaris->setObjectName(QStringLiteral("tab_getEptPolaris"));
    label_getEptPolaris_tipMsg = new QLabel(tab_getEptPolaris);
    label_getEptPolaris_tipMsg->setObjectName(QStringLiteral("label_getEptPolaris_tipMsg"));
    label_getEptPolaris_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_getEptPolaris_tipMsg->setWordWrap(true);
    label_getEptPolaris_tipMsg->setText(
        tr("Expected position: Double Click Polaris and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around Polaris."));
    label_getEptPolaris_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    label_getEptPolaris_ask = new QLabel(tab_getEptPolaris);
    label_getEptPolaris_ask->setObjectName(QStringLiteral("label_getEptPolaris_ask"));
    label_getEptPolaris_ask->setGeometry(QRect(5, 70, 290, 23));
    label_getEptPolaris_ask->setText(tr("Does match success?"));
    label_getEptPolaris_ask->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_getEptPolaris_done = new QPushButton(tab_getEptPolaris);
    pushButton_getEptPolaris_done->setObjectName(QStringLiteral("pushButton_getEptPolaris_done"));
    pushButton_getEptPolaris_done->setGeometry(QRect(380, 70, 75, 23));
    pushButton_getEptPolaris_done->setText(tr("Success"));

    tab_getEptPolaris->setMouseTracking(true);
    tab_getEptPolaris->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_getEptPolaris, QString());

    //move polaris tab
    tab_movePolaris = new QWidget();
    tab_movePolaris->setObjectName(QStringLiteral("tab_movePolaris"));
    label_movePolaris_tipMsg = new QLabel(tab_movePolaris);
    label_movePolaris_tipMsg->setObjectName(QStringLiteral("label_movePolaris_tipMsg"));
    label_movePolaris_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_movePolaris_tipMsg->setWordWrap(true);
    label_movePolaris_tipMsg->setText(
        tr("Using your Altitude and Azimuth bolts, move Polaris into the center of the small Rotating circle now shown on the image."));
    label_movePolaris_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    label_movePolaris_ask = new QLabel(tab_movePolaris);
    label_movePolaris_ask->setObjectName(QStringLiteral("label_movePolaris_ask"));
    label_movePolaris_ask->setGeometry(QRect(5, 70, 290, 23));
    label_movePolaris_ask->setText(tr("Has adjustment finished?"));
    label_movePolaris_ask->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_movePolaris_done = new QPushButton(tab_movePolaris);
    pushButton_movePolaris_done->setObjectName(QStringLiteral("pushButton_movePolaris_done"));
    pushButton_movePolaris_done->setGeometry(QRect(380, 70, 75, 23));
    pushButton_movePolaris_done->setText(tr("adjustment Finished"));

    tab_movePolaris->setMouseTracking(true);
    tab_movePolaris->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_movePolaris, QString());

    //get current polaris tab
    tab_getCurPolaris = new QWidget();
    tab_getCurPolaris->setObjectName(QStringLiteral("tab_getCurPolaris"));
    label_getCurPolaris_tipMsg = new QLabel(tab_getCurPolaris);
    label_getCurPolaris_tipMsg->setObjectName(QStringLiteral("label_getCurPolaris_tipMsg"));
    label_getCurPolaris_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_getCurPolaris_tipMsg->setWordWrap(true);
    label_getCurPolaris_tipMsg->setText(
        tr("Current position: Double Click Polaris and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around Polaris."));
    label_getCurPolaris_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    label_getCurPolaris_ask = new QLabel(tab_getCurPolaris);
    label_getCurPolaris_ask->setObjectName(QStringLiteral("label_getCurPolaris_ask"));
    label_getCurPolaris_ask->setGeometry(QRect(5, 70, 290, 23));
    label_getCurPolaris_ask->setText(tr("Does match success?"));
    label_getCurPolaris_ask->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_getCurPolaris_done = new QPushButton(tab_getCurPolaris);
    pushButton_getCurPolaris_done->setObjectName(QStringLiteral("pushButton_getCurPolaris_done"));
    pushButton_getCurPolaris_done->setGeometry(QRect(380, 70, 75, 23));
    pushButton_getCurPolaris_done->setText(tr("Success"));

    tab_getCurPolaris->setMouseTracking(true);
    tab_getCurPolaris->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_getCurPolaris, QString());

    //calculate pole
    tab_calcPole = new QWidget();
    tab_calcPole->setObjectName(QStringLiteral("tab_calcPole"));
    label_calcPole_tipMsg = new QLabel(tab_calcPole);
    label_calcPole_tipMsg->setObjectName(QStringLiteral("label_calcPole_tipMsg"));
    label_calcPole_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_calcPole_tipMsg->setWordWrap(true);
    label_calcPole_tipMsg->setText(tr("Please click the 'Start Monitor' button."));
    label_calcPole_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);

    tab_calcPole->setMouseTracking(true);
    tab_calcPole->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_calcPole, QString());

    //finetune pole
    tab_finetunePole = new QWidget();
    tab_finetunePole->setObjectName(QStringLiteral("tab_finetunePole"));
    label_finetunePole_tipMsg = new QLabel(tab_finetunePole);
    label_finetunePole_tipMsg->setObjectName(QStringLiteral("label_finetunePole_tipMsg"));
    label_finetunePole_tipMsg->setGeometry(QRect(5, 0, 460, 70));
    label_finetunePole_tipMsg->setWordWrap(true);
    label_finetunePole_tipMsg->setText(
        tr("Use your Altitude and Azimuth bolts only to move the Pole rectangle on top of the Axis circle."));
    label_finetunePole_tipMsg->setAttribute(Qt::WA_TransparentForMouseEvents);
    pushButton_finetunePole_reset = new QPushButton(tab_finetunePole);
    pushButton_finetunePole_reset->setObjectName(QStringLiteral("pushButton_finetunePole_reset"));
    pushButton_finetunePole_reset->setGeometry(QRect(300, 70, 75, 23));
    pushButton_finetunePole_reset->setText(tr("Restart"));
    pushButton_finetunePole_done = new QPushButton(tab_finetunePole);
    pushButton_finetunePole_done->setObjectName(QStringLiteral("pushButton_finetunePole_done"));
    pushButton_finetunePole_done->setGeometry(QRect(380, 70, 75, 23));
    pushButton_finetunePole_done->setText(tr("Done"));

    tab_finetunePole->setMouseTracking(true);
    tab_finetunePole->installEventFilter(this);

    tabWidget_tipMsg->addTab(tab_finetunePole, QString());

    connect(pushButton_settingDone, SIGNAL(clicked(bool)), this, SLOT(pushbuttonSettingDoneClicked()));
    connect(pushButton_confirmDone, SIGNAL(clicked(bool)), this, SLOT(pushbuttonConfirmDoneClicked()));
    connect(pushButton_rotateStar1_reset, SIGNAL(clicked(bool)), this, SLOT(pushbuttonRotateStar1ResetClicked()));
    connect(pushButton_rotateStar1_done, SIGNAL(clicked(bool)), this, SLOT(pushbuttonRotateStar1DoneClicked()));
    connect(pushButton_getStar2_reset, SIGNAL(clicked(bool)), this, SLOT(pushbuttonGetStar2ResetClicked()));
    connect(pushButton_rotateStar2_reset, SIGNAL(clicked(bool)), this, SLOT(pushbuttonRotateStar2ResetClicked()));
    connect(pushButton_rotateStar2_done, SIGNAL(clicked(bool)), this, SLOT(pushbuttonRotateStar2DoneClicked()));
    connect(pushButton_getStar3_reset, SIGNAL(clicked(bool)), this, SLOT(pushbuttonGetStar3ResetClicked()));
    connect(pushButton_validateCenter_reset, SIGNAL(clicked(bool)), this, SLOT(pushbuttonValidateCenterResetClicked()));
    connect(pushButton_validateCenter_done, SIGNAL(clicked(bool)), this, SLOT(pushbuttonValidateCenterDoneClicked()));
    connect(pushButton_getEptPolaris_done, SIGNAL(clicked(bool)), this, SLOT(pushbuttonGetEptPolarisDoneClicked()));
    connect(pushButton_movePolaris_done, SIGNAL(clicked(bool)), this, SLOT(pushbuttonMovePolarisDoneClicked()));
    connect(pushButton_getCurPolaris_done, SIGNAL(clicked(bool)), this, SLOT(pushbuttonGetCurPolarisDoneClicked()));
    connect(pushButton_finetunePole_reset, SIGNAL(clicked(bool)), this, SLOT(pushbuttonFinetunePoleResetClicked()));
    connect(pushButton_finetunePole_done, SIGNAL(clicked(bool)), this, SLOT(pushbuttonFinetunePoleDoneClicked()));
}

void MainWindow::saveParamToIni()
{
    //Qt中使用QSettings类读写ini文件
    //QSettings构造函数的第一个参数是ini文件的路径,第二个参数表示针对ini文件,第三个参数可以缺省
    QString inifileFullPath = QCoreApplication::applicationDirPath() + "/" + "PoleMaster.ini";
    inifileFullPath = QDir::toNativeSeparators(inifileFullPath);
    QSettings *iniWrite = new QSettings(inifileFullPath, QSettings::IniFormat);

    iniWrite->beginGroup("STYLE");
    iniWrite->setValue("style", viewStyle);
    iniWrite->endGroup();

    iniWrite->beginGroup("LANGUAGE");
    iniWrite->setValue("lang", lang);
    iniWrite->endGroup();

    iniWrite->beginGroup("REGION");
    iniWrite->setValue("region", region);
    iniWrite->endGroup();

    iniWrite->beginGroup("ZOOM");
    iniWrite->setValue("factor", QString::number(scaledFactor));
    iniWrite->endGroup();

    iniWrite->beginGroup("ASTRONOMICAL_REFRACTION");
    iniWrite->setValue("latitude", QString::number(latitude));
    iniWrite->setValue("longitude", QString::number(longitude));
    iniWrite->setValue("P", QString::number(presure));
    iniWrite->setValue("T", QString::number(temperature));
    iniWrite->setValue("enabledCorrect", enabledAstroRefCorrect);
    iniWrite->setValue("P_unit", presureUnit);
    iniWrite->endGroup();

    iniWrite->beginGroup("AXIS_CENTER");
    iniWrite->setValue("x", QString::number(curAxisX));
    iniWrite->setValue("y", QString::number(curAxisY));
    iniWrite->endGroup();

    //写入完成后删除指针
    delete iniWrite;
}

bool MainWindow::loadParamFromIni()
{
    bool ret = false;

    //读取EZCAP.ini中的内容
    QString inifileFullPath = QCoreApplication::applicationDirPath() + "/" + "PoleMaster.ini";
    inifileFullPath = QDir::toNativeSeparators(inifileFullPath);

    QFile *settingFile = new QFile(inifileFullPath);
    if(settingFile->exists())
    {
        QSettings *iniRead = new QSettings(inifileFullPath, QSettings::IniFormat);

        iniRead->beginGroup("STYLE");
        viewStyle = iniRead->value("style", "Color").toString();
        iniRead->endGroup();

        iniRead->beginGroup("LANGUAGE");
        lang = iniRead->value("lang", "EN").toString();
        iniRead->endGroup();

        iniRead->beginGroup("REGION");
        region = iniRead->value("region", "North").toString();
        iniRead->endGroup();

        iniRead->beginGroup("ZOOM");
        scaledFactor = iniRead->value("factor", 1.0).toFloat();
        iniRead->endGroup();

        iniRead->beginGroup("ASTRONOMICAL_REFRACTION");
        latitude = iniRead->value("latitude", 39.9).toFloat();
        longitude = iniRead->value("longitude", 116.3).toFloat();
        presure = iniRead->value("P", 101).toFloat();
        temperature = iniRead->value("T", 10).toFloat();
        enabledAstroRefCorrect = iniRead->value("enabledCorrect", false).toBool();
        presureUnit = iniRead->value("P_unit", "kPa").toString();
        iniRead->endGroup();

        iniRead->beginGroup("AXIS_CENTER");
        curAxisX = iniRead->value("x", 0).toFloat();
        curAxisY = iniRead->value("y", 0).toFloat();
        iniRead->endGroup();

        delete iniRead;

        ret = true;
    }

    delete settingFile;

    return ret;
}

void MainWindow::loadStarsData()
{
    double factor = 100000000000000.0;
    double tempvalue = 0.0;
    QString key_BAP = "BAP_20160523";
    QString key_ABP = "ABP_20160523";
    QString key_DBP = "DBP_20160523";
    QDate curDate = QDate::currentDate();

    if(curDate < QDate(2016, 11, 23))
    {
        qDebug() << "Loading star data at 20160523";
        key_BAP = "BAP_20160523";
        key_ABP = "ABP_20160523";
        key_DBP = "DBP_20160523";
    }
    else if(curDate < QDate(2017, 11, 23))
    {
        qDebug() << "Loading star data at 20170523";
        key_BAP = "BAP_20170523";
        key_ABP = "ABP_20170523";
        key_DBP = "DBP_20170523";
    }
    else if(curDate < QDate(2018, 11, 23))
    {
        qDebug() << "Loading star data at 20180523";
        key_BAP = "BAP_20180523";
        key_ABP = "ABP_20180523";
        key_DBP = "DBP_20180523";
    }
    else if(curDate < QDate(2019, 11, 23))
    {
        qDebug() << "Loading star data at 20190523";
        key_BAP = "BAP_20190523";
        key_ABP = "ABP_20190523";
        key_DBP = "DBP_20190523";
    }
    else if(curDate < QDate(2020, 11, 23))
    {
        qDebug() << "Loading star data at 20200523";
        key_BAP = "BAP_20200523";
        key_ABP = "ABP_20200523";
        key_DBP = "DBP_20200523";
    }
    else if(curDate < QDate(2021, 11, 23))
    {
        qDebug() << "Loading star data at 20210523";
        key_BAP = "BAP_20210523";
        key_ABP = "ABP_20210523";
        key_DBP = "DBP_20210523";
    }
    else if(curDate < QDate(2022, 11, 23))
    {
        qDebug() << "Loading star data at 20220523";
        key_BAP = "BAP_20220523";
        key_ABP = "ABP_20220523";
        key_DBP = "DBP_20220523";
    }
    else if(curDate < QDate(2023, 11, 23))
    {
        qDebug() << "Loading star data at 20230523";
        key_BAP = "BAP_20230523";
        key_ABP = "ABP_20230523";
        key_DBP = "DBP_20230523";
    }
    else
    {
        qDebug() << "Loading star data at 20240523";
        key_BAP = "BAP_20240523";
        key_ABP = "ABP_20240523";
        key_DBP = "DBP_20240523";
    }

    //load south star data
    QSettings *sIniRead = new QSettings(":/starData/SStarPosData.ini", QSettings::IniFormat);

    southStarsData.starAX = sIniRead->value("A_X_Mask", 230.0).toDouble();
    southStarsData.starAY = sIniRead->value("A_Y_Mask", 405.0).toDouble();
    southStarsData.starBX = sIniRead->value("B_X_Mask", 400.0).toDouble();
    southStarsData.starBY = sIniRead->value("B_Y_Mask", 337.0).toDouble();
    southStarsData.starDX = sIniRead->value("D_X_Mask", 230.0).toDouble();
    southStarsData.starDY = sIniRead->value("D_Y_Mask", 562.0).toDouble();

    tempvalue = sIniRead->value(key_BAP, 0).toDouble();
    southStarsData.angleBAP = tempvalue / factor;
    tempvalue = sIniRead->value(key_ABP, 0).toDouble();
    southStarsData.angleABP = tempvalue / factor;
    tempvalue = sIniRead->value(key_DBP, 0).toDouble();
    southStarsData.angleDBP = tempvalue / factor;

    delete sIniRead;

    //north star data
    QSettings *nIniRead = new QSettings(":/starData/NStarPosData.ini", QSettings::IniFormat);

    northStarsData.starAX = nIniRead->value("A_X_Mask", 264.0).toDouble();
    northStarsData.starAY = nIniRead->value("A_Y_Mask", 272.0).toDouble();
    northStarsData.starBX = nIniRead->value("B_X_Mask", 400.0).toDouble();
    northStarsData.starBY = nIniRead->value("B_Y_Mask", 400.0).toDouble();
    northStarsData.starDX = nIniRead->value("D_X_Mask", 602.0).toDouble();
    northStarsData.starDY = nIniRead->value("D_Y_Mask", 230.0).toDouble();

    tempvalue = nIniRead->value(key_BAP, 0).toDouble();
    northStarsData.angleBAP = tempvalue / factor;
    tempvalue = nIniRead->value(key_ABP, 0).toDouble();
    northStarsData.angleABP = tempvalue / factor;
    tempvalue = nIniRead->value(key_DBP, 0).toDouble();
    northStarsData.angleDBP = tempvalue / factor;

    delete nIniRead;
}

void MainWindow::drawPoleOnTemplateImage()
{
    //when you
    uint32_t ret = RETURE_ERROR;
    if(northTemplateImg)
    {
        //calc pole position into mask image.
        ret = myTools.CalcMaskPoleCoor(northStarsData.starAX, northStarsData.starAY, northStarsData.angleBAP,
                                       northStarsData.starBX, northStarsData.starBY, northStarsData.angleABP,
                                       &northStarsData.poleX, &northStarsData.poleY,
                                       northStarsData.starDX, northStarsData.starDY, northStarsData.angleDBP);
        if(ret == RETURE_SUCCESS)
        {
            qDebug() << "north pole in template" << northStarsData.poleX << northStarsData.poleY;

            //draw north pole on template image
            QPainter painter;
            painter.begin(northTemplateImg);
            painter.setRenderHint(QPainter::Antialiasing, true);
            painter.setPen(QPen(QColor(150, 244, 254)));
            painter.drawLine(QPointF(northStarsData.poleX - 5, northStarsData.poleY), QPointF(northStarsData.poleX + 5,
                             northStarsData.poleY));
            painter.drawLine(QPointF(northStarsData.poleX, northStarsData.poleY - 5), QPointF(northStarsData.poleX,
                             northStarsData.poleY + 5));
            painter.end();
        }
        else
        {
            qCritical() << "Failed to calculate the north pole.";
        }
    }

    if(southTemplateImg)
    {
        //calc pole position into mask image.
        ret = myTools.CalcMaskPoleCoor(southStarsData.starAX, southStarsData.starAY, southStarsData.angleBAP,
                                       southStarsData.starBX, southStarsData.starBY, southStarsData.angleABP,
                                       &southStarsData.poleX, &southStarsData.poleY,
                                       southStarsData.starDX, southStarsData.starDY, southStarsData.angleDBP);
        if(ret == RETURE_SUCCESS)
        {
            qDebug() << "south pole in template" << southStarsData.poleX << southStarsData.poleY;

            //draw north pole on template image
            QPainter painter;
            painter.begin(southTemplateImg);
            painter.setRenderHint(QPainter::Antialiasing, true);
            painter.setPen(QPen(QColor(150, 244, 254)));
            painter.drawLine(QPointF(southStarsData.poleX - 5, southStarsData.poleY), QPointF(southStarsData.poleX + 5,
                             southStarsData.poleY));
            painter.drawLine(QPointF(southStarsData.poleX, southStarsData.poleY - 5), QPointF(southStarsData.poleX,
                             southStarsData.poleY + 5));
            painter.end();
        }
        else
        {
            qCritical() << "Failed to calculate the south pole.";
        }
    }
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    uint32_t ret = QHYCCD_ERROR;

    //save parameters into INI file
    saveParamToIni();

    if(graphicsEffectTimer)
        graphicsEffectTimer->stop();
    if(increaseAngleTimer)
        increaseAngleTimer->stop();
    if(updateImgTimer)
        updateImgTimer->stop();

    if(captureFrameThread->isRunning())
    {
        captureFrameThread->stopThread();
    }

    if(camparam.isConnected)
    {
        if(camhandle)
        {
            ret = StopQHYCCDLive(camhandle);
            if(ret == QHYCCD_SUCCESS)
            {
                qDebug() << "StopQHYCCDLive";
            }

            ret = CloseQHYCCD(camhandle);
            if(ret == QHYCCD_SUCCESS)
            {
                qDebug() << "CloseQHYCCD";
                camparam.isConnected = false;
            }
        }
    }

    if(camparam.canUseSDK)
    {
        //ret = ReleaseQHYCCDResource();
        if(ret == QHYCCD_SUCCESS)
            qDebug() << "ReleaseQHYCCDResource success";

        camparam.canUseSDK = false;
    }

    event->accept();  //accept the signal, program will exit
}

void MainWindow::setCurrentStepIndex(int index)
{
    switch(index)
    {
        case STEP_POLEMASTER_SETTING:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(0); //show setting tipmsg

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(true);
            ui->widget_setting->setVisible(true);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(false);
            ui->widget_rough->setVisible(false);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(false);

            stepIndex = STEP_POLEMASTER_SETTING;

            showingAxisCenter = false;
            showingValidateCircle = false;
            showingEptPolaris = false;
            showingPole = false;
            showingRefStarA = false;
            showingRefStarB = false;
        }
        break;
        case STEP_CONFIRM_POLARIS:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(1);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(true);
            ui->widget_confirm->setVisible(true);
            ui->pushButton_head_rough->setChecked(false);
            ui->widget_rough->setVisible(false);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            label_directionImg->setVisible(false);

            stepIndex = STEP_CONFIRM_POLARIS;
        }
        break;
        case STEP_GET_STAR_FIRST:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(2);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(true);
            ui->widget_rough->setVisible(true);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(false);

            if(viewStyle.compare("Mono") == 0)
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
            }
            else
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
            }

            stepIndex = STEP_GET_STAR_FIRST;

            showingAxisCenter = false;
            showingValidateCircle = false;

            graphicsEffectTimer->stop();  //stop graphics effect timer
        }
        break;
        case STEP_ROTATE_FIRST:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(3);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(true);
            ui->widget_rough->setVisible(true);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(true);

            if(viewStyle.compare("Mono") == 0)
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
            }
            else
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
            }

            stepIndex = STEP_ROTATE_FIRST;

            showingAxisCenter = false;
            showingValidateCircle = false;
        }
        break;
        case STEP_GET_STAR_SECOND:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(4);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(true);
            ui->widget_rough->setVisible(true);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(false);

            if(viewStyle.compare("Mono") == 0)
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
            }
            else
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
            }

            stepIndex = STEP_GET_STAR_SECOND;

            showingAxisCenter = false;
            showingValidateCircle = false;
        }
        break;
        case STEP_ROTATE_SECOND:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(5);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(true);
            ui->widget_rough->setVisible(true);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(true);

            if(viewStyle.compare("Mono") == 0)
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
            }
            else
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
            }

            stepIndex = STEP_ROTATE_SECOND;

            showingAxisCenter = false;
            showingValidateCircle = false;
        }
        break;
        case STEP_GET_STAR_THIRD:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(6);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(true);
            ui->widget_rough->setVisible(true);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(false);

            if(viewStyle.compare("Mono") == 0)
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
            }
            else
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
            }

            stepIndex = STEP_GET_STAR_THIRD;

            showingAxisCenter = false;
            showingValidateCircle = false;
        }
        break;
        case STEP_VALIDATE_CENTER:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(7);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(true);
            ui->widget_rough->setVisible(true);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(false);

            if(viewStyle.compare("Mono") == 0)
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
            }
            else
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
            }

            stepIndex = STEP_VALIDATE_CENTER;

            showingAxisCenter = true;
            showingValidateCircle = true;
        }
        break;
        case STEP_GET_EXPECT_POLARIS:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(8);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(true);
            ui->widget_rough->setVisible(true);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            label_directionImg->setVisible(false);

            if(viewStyle.compare("Mono") == 0)
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
            }
            else
            {
                ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
                ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
                ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
            }

            stepIndex = STEP_GET_EXPECT_POLARIS;

            showingAxisCenter = true;
            showingValidateCircle = false;
            showingEptPolaris = true;
        }
        break;
        case STEP_MOVE_POLARIS:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(9);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(true);
            ui->widget_rough->setVisible(true);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(false);

            stepIndex = STEP_MOVE_POLARIS;

            showingAxisCenter = true;
            showingValidateCircle = false;
            showingEptPolaris = true;

            graphicsEffectTimer->stop();  //stop graphics effect timer
        }
        break;
        case STEP_GET_CUR_POLARIS:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(10);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(true);
            ui->widget_rough->setVisible(true);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            //ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(false);

            stepIndex = STEP_GET_CUR_POLARIS;

            showingAxisCenter = true;
            showingValidateCircle = false;
            showingEptPolaris = false;
        }
        break;
        case STEP_CALC_POLE:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(11);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(false);
            ui->widget_rough->setVisible(false);
            ui->pushButton_head_precise->setChecked(true);
            ui->widget_precise->setVisible(true);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(false);

            stepIndex = STEP_CALC_POLE;

            graphicsEffectTimer->stop();  //stop graphics effect timer
        }
        break;
        case STEP_FINE_TUNE_POLE:
        {
            tabWidget_tipMsg->show();
            tabWidget_tipMsg->setCurrentIndex(12);

            ui->pushButton_head_region->setChecked(true);
            ui->widget_region->setVisible(true);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(false);
            ui->widget_rough->setVisible(false);
            ui->pushButton_head_precise->setChecked(true);
            ui->widget_precise->setVisible(true);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(false);

            stepIndex = STEP_FINE_TUNE_POLE;

            showingPole = true;
            showingRefStarA = true;
            showingRefStarB = true;
        }
        break;
        case STEP_POLEMASTER_DONE:
        {
            tabWidget_tipMsg->hide();
        }
        break;
        default:
        {
            tabWidget_tipMsg->hide();

            ui->pushButton_head_region->setChecked(false);
            ui->widget_region->setVisible(false);
            ui->pushButton_head_setting->setChecked(false);
            ui->widget_setting->setVisible(false);
            ui->pushButton_head_confirm->setChecked(false);
            ui->widget_confirm->setVisible(false);
            ui->pushButton_head_rough->setChecked(false);
            ui->widget_rough->setVisible(false);
            ui->pushButton_head_precise->setChecked(false);
            ui->widget_precise->setVisible(false);

            ui->label_templateImg->setVisible(false);
            label_directionImg->setVisible(false);

        }
    }
}

void MainWindow::setCurrentTemplateImg(float scale, QString curRegion)
{
    QImage tempImg;
    int tempImgW;
    int tempImgH;
    int xstart;
    int ystart;

    if(curRegion.compare("South") == 0)
    {
        if(southTemplateImg)
        {
            tempImgW = southTemplateImg->width() * scale;
            tempImgH = southTemplateImg->height() * scale;
            tempImg = southTemplateImg ->scaled(tempImgW, tempImgH, Qt::KeepAspectRatio, Qt::SmoothTransformation);

            xstart = templateImgCenter_originalImg.x() * scale - tempImgW / 2;
            ystart = templateImgCenter_originalImg.y() * scale - tempImgH / 2;

            ui->label_templateImg->setGeometry(xstart, ystart, tempImgW, tempImgH);
            ui->label_templateImg->setPixmap(QPixmap::fromImage(tempImg));
        }
    }
    else if(curRegion.compare("North") == 0)
    {
        if(northTemplateImg)
        {
            tempImgW = northTemplateImg->width() * scale;
            tempImgH = northTemplateImg->height() * scale;
            tempImg = northTemplateImg->scaled(tempImgW, tempImgH, Qt::KeepAspectRatio, Qt::SmoothTransformation);

            xstart = templateImgCenter_originalImg.x() * scale - tempImgW / 2;
            ystart = templateImgCenter_originalImg.y() * scale - tempImgH / 2;

            ui->label_templateImg->setGeometry(xstart, ystart, tempImgW, tempImgH);
            ui->label_templateImg->setPixmap(QPixmap::fromImage(tempImg));
        }
    }
}

void MainWindow::scaledDirectionImg(float scaled)
{
    QImage srcimg = QImage(":/images/direction.png");
    srcimg = srcimg.scaled(srcimg.width() * scaled, srcimg.height() * scaled, Qt::KeepAspectRatio, Qt::SmoothTransformation);

    label_directionImg->setPixmap(QPixmap::fromImage(srcimg));
}

void MainWindow::on_pushButton_head_region_toggled(bool checked)
{
    qDebug() << "region head " << checked;
    ui->widget_region->setVisible(checked);
    if(checked)
        ui->pushButton_head_region->setIcon(QIcon(":/images/collapse.png"));
    else
        ui->pushButton_head_region->setIcon(QIcon(":/images/expand.png"));
}

void MainWindow::on_pushButton_head_setting_toggled(bool checked)
{
    qDebug() << "setting head " << checked;
    ui->widget_setting->setVisible(checked);
    if(checked)
        ui->pushButton_head_setting->setIcon(QIcon(":/images/collapse.png"));
    else
        ui->pushButton_head_setting->setIcon(QIcon(":/images/expand.png"));
}

void MainWindow::on_pushButton_head_confirm_toggled(bool checked)
{
    qDebug() << "confirm head " << checked;
    ui->widget_confirm->setVisible(checked);
    if(checked)
        ui->pushButton_head_confirm->setIcon(QIcon(":/images/collapse.png"));
    else
        ui->pushButton_head_confirm->setIcon(QIcon(":/images/expand.png"));
}

void MainWindow::on_pushButton_head_rough_toggled(bool checked)
{
    qDebug() << "rough head " << checked;
    ui->widget_rough->setVisible(checked);
    if(checked)
        ui->pushButton_head_rough->setIcon(QIcon(":/images/collapse.png"));
    else
        ui->pushButton_head_rough->setIcon(QIcon(":/images/expand.png"));
}

void MainWindow::on_pushButton_head_precise_toggled(bool checked)
{
    qDebug() << "precise head " << checked;
    ui->widget_precise->setVisible(checked);
    if(checked)
        ui->pushButton_head_precise->setIcon(QIcon(":/images/collapse.png"));
    else
        ui->pushButton_head_precise->setIcon(QIcon(":/images/expand.png"));
}

void MainWindow::languageChanged()
{
    qDebug() << "current language" << lang;
    if(lang.compare("ZH") == 0)
    {
        if(translator->load(":/languages/lan_zh_cn.qm"))
        {
            qApp->installTranslator(translator);

            emit resetUI();
        }
    }
    else if(lang.compare("JA") == 0)
    {
        if(translator->load(":/languages/lan_ja_jp.qm"))
        {
            qApp->installTranslator(translator);

            emit resetUI();
        }
    }
    else if(lang.compare("DE") == 0)
    {
        if(translator->load(":/languages/lan_de_de.qm"))
        {
            qApp->installTranslator(translator);

            emit resetUI();
        }
    }
    else if(lang.compare("ES") == 0)
    {
        if(translator->load(":/languages/lan_es_es.qm"))
        {
            qApp->installTranslator(translator);

            emit resetUI();
        }
    }
    else if(lang.compare("FR") == 0)
    {
        if(translator->load(":/languages/lan_fr_fr.qm"))
        {
            qApp->installTranslator(translator);

            emit resetUI();
        }
    }
    else if(lang.compare("IT") == 0)
    {
        if(translator->load(":/languages/lan_it_it.qm"))
        {
            qApp->installTranslator(translator);

            emit resetUI();
        }
    }
    else if(lang.compare("RU") == 0)
    {
        if(translator->load(":/languages/lan_ru_ru.qm"))
        {
            qApp->installTranslator(translator);

            emit resetUI();
        }
    }
    else if(lang.compare("PT") == 0)
    {
        if(translator->load(":/languages/lan_pt_pt.qm"))
        {
            qApp->installTranslator(translator);

            emit resetUI();
        }
    }
    else if(lang.compare("KO") == 0)
    {
        if(translator->load(":/languages/lan_ko_kr.qm"))
        {
            qApp->installTranslator(translator);

            emit resetUI();
        }
    }
    else
    {
        if(translator->load(":/languages/lan_en_us.qm"))
        {
            qApp->installTranslator(translator);

            emit resetUI();
        }
    }
}

void MainWindow::pushbuttonSettingDoneClicked()
{
    // goto confirm tab
    setCurrentStepIndex(STEP_CONFIRM_POLARIS);
}

void MainWindow::pushbuttonConfirmDoneClicked()
{
    if(curAxisX > 0 && curAxisY > 0)
    {
        QMessageBox::StandardButton choiceBtn;
        choiceBtn = QMessageBox::question(NULL, tr("Question"),
                                          tr("Would you like to use the 'Axis center position' recorded last time you used Polemaster ?"),
                                          QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
        if(choiceBtn == QMessageBox::Yes)
        {
            ui->label_axisPos->setText("(" + QString::number(curAxisX, 'f', 1) + "," + QString::number(curAxisY, 'f', 1) + ")");

            setCurrentStepIndex(STEP_GET_EXPECT_POLARIS); // goto validate center step
        }
        else
        {
            curAxisX = 0;
            curAxisY = 0;

            setCurrentStepIndex(STEP_GET_STAR_FIRST); //goto get star pos1 tab
        }
    }
    else
    {
        setCurrentStepIndex(STEP_GET_STAR_FIRST); //goto get star pos1 tab
    }

}

void MainWindow::pushbuttonRotateStar1ResetClicked()
{
    setCurrentStepIndex(STEP_GET_STAR_FIRST); //back to get star pos1 tab
}

void MainWindow::pushbuttonRotateStar1DoneClicked()
{
    setCurrentStepIndex(STEP_GET_STAR_SECOND); //goto get star second tab
}

void MainWindow::pushbuttonGetStar2ResetClicked()
{
    setCurrentStepIndex(STEP_GET_STAR_FIRST); //back to get star pos1 tab
}

void MainWindow::pushbuttonRotateStar2ResetClicked()
{
    setCurrentStepIndex(STEP_GET_STAR_FIRST); //back to get star pos1 tab
}

void MainWindow::pushbuttonRotateStar2DoneClicked()
{
    setCurrentStepIndex(STEP_GET_STAR_THIRD); //goto get star pos 3 tab
}

void MainWindow::pushbuttonGetStar3ResetClicked()
{
    setCurrentStepIndex(STEP_GET_STAR_FIRST);  //back to get star pos1 tab
}

void MainWindow::pushbuttonValidateCenterResetClicked()
{
    setCurrentStepIndex(STEP_GET_STAR_FIRST);  //back to get star pos1 tab
}

void MainWindow::pushbuttonValidateCenterDoneClicked()
{
    curAxisX = tempCenterX;  //record the axis center
    curAxisY = tempCenterY;

    ui->label_axisPos->setText("(" + QString::number(curAxisX, 'f', 1) + "," + QString::number(curAxisY, 'f', 1) + ")");

    setCurrentStepIndex(STEP_GET_EXPECT_POLARIS); //goto get expected polaris tab
}

void MainWindow::pushbuttonGetEptPolarisDoneClicked()
{
    setCurrentStepIndex(STEP_MOVE_POLARIS); //goto move polaris tab
}

void MainWindow::pushbuttonMovePolarisDoneClicked()
{
    setCurrentStepIndex(STEP_GET_CUR_POLARIS); //goto current polaris tab
}

void MainWindow::pushbuttonGetCurPolarisDoneClicked()
{
    // ------get the precise position of StarA StarB------
    uint32_t ret = RETURE_ERROR;
    double x1, y1;
    double dstX, dstY;

    myTools.imgRotatedPoint(rotateAngle, posX_starA_mask, posY_starA_mask, posX_starB_mask, posY_starB_mask, &x1, &y1);
    dstX = posX_starN - posX_starB_mask + x1;
    dstY = posY_starN - posY_starB_mask + y1;
    //get starA area center position
    ret = myTools.GetPreciseStarPos(inputImg, dstX, dstY, &starA_area_X, &starA_area_Y);
    if(ret == RETURE_ERROR)
    {
        starA_area_X = dstX;  //if not get the precise position, then used the dstX, dstY;
        starA_area_Y = dstY;
    }
    originalStarAPosX = starA_area_X;  //record the original position of starA, used it when do pole tracking
    originalStarAPosY = starA_area_Y;
    qDebug() << "current StarA point" << starA_area_X << starA_area_Y;

    //get starB area center position
    ret = myTools.GetPreciseStarPos(inputImg, posX_starN, posY_starN, &starB_area_X, &starB_area_Y);
    if(ret == RETURE_ERROR)
    {
        starB_area_X = posX_starN;  //if not get the precise position, then used the dstX, dstY;
        starB_area_Y = posY_starN;
    }
    originalStarBPosX = starB_area_X;   //record the original position of starB, used it when do pole tracking
    originalStarBPosY = starB_area_Y;
    qDebug() << "current StarB point" << starB_area_X << starB_area_Y;

    setCurrentStepIndex(STEP_CALC_POLE); //goto calculate pole tab
}

void MainWindow::pushbuttonFinetunePoleResetClicked()
{
    setCurrentStepIndex(STEP_POLEMASTER_SETTING); //back to polemaster setting tab
}

void MainWindow::pushbuttonFinetunePoleDoneClicked()
{
    setCurrentStepIndex(STEP_POLEMASTER_DONE);
}

void MainWindow::showImages()
{
    capImgMutex.lock();
    if(!frameQueue.isEmpty())
    {
        int showW = camparam.NumX * scaledFactor;
        int showH = camparam.NumY * scaledFactor;
        capImg = frameQueue.dequeue().scaled(showW, showH, Qt::KeepAspectRatio, Qt::SmoothTransformation);

        ui->label_showImg->setPixmap(QPixmap::fromImage(capImg));

        //update magnifier glass image
        widget_magnifier->setLoupePixmap(QPixmap::fromImage(capImg));
        widget_magnifier->update();
    }
    capImgMutex.unlock();

    roiImgMutex.lock();
    if(showingPole && !roiEnlargeImgQueue.isEmpty())
    {
        roiEnlargeImg = roiEnlargeImgQueue.dequeue();
        ui->label_biggerImg->setPixmap(QPixmap::fromImage(roiEnlargeImg));

        ui->label_refStarA_pos->setText("(" + QString::number(curXStarA, 'f', 1) + "," + QString::number(curYStarA, 'f', 1) + ")");
        ui->label_refStarB_pos->setText("(" + QString::number(curXStarB, 'f', 1) + "," + QString::number(curYStarB, 'f', 1) + ")");
        ui->label_pole->setText("(" + QString::number(curPoleX, 'f', 1) + "," + QString::number(curPoleY, 'f', 1) + ")");
    }
    roiImgMutex.unlock();
}

void MainWindow::updateFPS()
{
    updateFPSMutex.lock();
    label_fps->clear();
    label_fps->setText("FPS : " + QString::number(camparam.fps_1) + "." + QString::number(camparam.fps_2));
    updateFPSMutex.unlock();
}

void MainWindow::increaseAngleTimeout()
{
    //the increase angle to draw the expected polaris position
    increAngle += 10;
    if(increAngle > 72)
        increAngle = 0;
}

void MainWindow::graphicsEffectTimeout()
{
    bool enabled;
    if(stepIndex == STEP_CONFIRM_POLARIS)
    {
        enabled = dropShowEffect_confirm->isEnabled();
        dropShowEffect_confirm->setEnabled(!enabled);
    }
    else if(stepIndex == STEP_GET_EXPECT_POLARIS || stepIndex == STEP_GET_CUR_POLARIS)
    {
        enabled = dropShowEffect_rough->isEnabled();
        dropShowEffect_rough->setEnabled(!enabled);
    }
}

void MainWindow::poleTracking(double degree)
{
    double dstX, dstY;
    myTools.imgRotatedPoint(degree, originalStarAPosX, originalStarAPosY, curAxisX, curAxisY, &dstX, &dstY);
    starA_area_X = dstX;  //update starA area center position
    starA_area_Y = dstY;

    myTools.imgRotatedPoint(degree, originalStarBPosX, originalStarBPosY, curAxisX, curAxisY, &dstX, &dstY);
    starB_area_X = dstX;  //update starB area center position
    starB_area_Y = dstY;

    qDebug() << "StarA area" << starA_area_X << starA_area_Y;
    qDebug() << "StarB area" << starB_area_X << starB_area_Y;
}

bool MainWindow::eventFilter(QObject *obj, QEvent *e)
{
    if(obj == ui->label_showImg)
    {
        if(camparam.isConnected && (e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseMove))
        {
            QMouseEvent *pMouseEvent = static_cast<QMouseEvent *>(e);
            double refMousePosX = pMouseEvent->x() / scaledFactor;
            double refMousePoxY = pMouseEvent->y() / scaledFactor;

            //update the magnifier's image with current cursor.
            this->label_status_mousePos->setText(QString::number(refMousePosX, 'f', 1) + "," + QString::number(refMousePoxY, 'f', 1));
            if(ui->label_showImg->pixmap().isNull())
            {
                qCritical() << "no pixmap has been set in the Label_showImg";
            }
            else
            {
                widget_magnifier->setLoupePixmap(ui->label_showImg->pixmap());
                widget_magnifier->setZoomRegionCenter(pMouseEvent->x(), pMouseEvent->y());
                widget_magnifier->update();
            }

            //deal with the double click event......
            if(e->type() == QEvent::MouseButtonDblClick)
            {
                uint32_t ret = RETURE_ERROR;
                double tempStarPosX, tempStarPosY;

                //get the star position in current mouse point
                ret =  myTools.GetPreciseStarPos(inputImg, refMousePosX, refMousePoxY, &tempStarPosX, &tempStarPosY);
                if(ret == RETURE_SUCCESS)
                {
                    //qDebug() << mousex << mousey << tempStarPosX << tempStarPosY;
                    if(stepIndex == STEP_CONFIRM_POLARIS)
                    {
                        //set the center of current template image
                        templateImgCenter.setX(pMouseEvent->x());
                        templateImgCenter.setY(pMouseEvent->y());
                        templateImgCenter_originalImg.setX(pMouseEvent->x() / scaledFactor);
                        templateImgCenter_originalImg.setY(pMouseEvent->y() / scaledFactor);
                        //calculate the position of the template image
                        int sx = templateImgCenter.x() - ui->label_templateImg->width() / 2;
                        int sy = templateImgCenter.y() - ui->label_templateImg->height() / 2;

                        //move the template image
                        ui->label_templateImg->move(sx, sy);
                        ui->label_templateImg->show();
                        //rotate template, in case it be rotated when label_templateImg was hidden.
                        rotateTemplateImage(rotateAngle);

                        //start the graphics effect timer
                        graphicsEffectTimer->start();
                    }
                    else if(stepIndex == STEP_GET_EXPECT_POLARIS || stepIndex == STEP_GET_CUR_POLARIS)
                    {
                        //set the center of current template image
                        templateImgCenter.setX(pMouseEvent->x());
                        templateImgCenter.setY(pMouseEvent->y());
                        templateImgCenter_originalImg.setX(pMouseEvent->x() / scaledFactor);
                        templateImgCenter_originalImg.setY(pMouseEvent->y() / scaledFactor);
                        //calculate the position of the template image
                        int sx = templateImgCenter.x() - ui->label_templateImg->width() / 2;
                        int sy = templateImgCenter.y() - ui->label_templateImg->height() / 2;

                        //move the template image
                        ui->label_templateImg->move(sx, sy);
                        ui->label_templateImg->show();
                        //rotate template, in case it be rotated when label_templateImg was hidden.
                        rotateTemplateImage(rotateAngle);

                        // record current Polaris or oct position
                        posX_starN = tempStarPosX;
                        posY_starN = tempStarPosY;
                        ui->label_curPos->setText("(" + QString::number(tempStarPosX, 'f', 1) + "," + QString::number(tempStarPosY, 'f', 1) + ")");

                        //start the graphics effect timer
                        graphicsEffectTimer->start();
                    }
                    else if(stepIndex == STEP_GET_STAR_FIRST)
                    {
                        starPos1_x = tempStarPosX;   //record star pos 1
                        starPos1_y = tempStarPosY;
                        qDebug() << "star pos1" << starPos1_x << starPos1_y;

                        setCurrentStepIndex(STEP_ROTATE_FIRST);
                    }
                    else if(stepIndex == STEP_GET_STAR_SECOND)
                    {
                        starPos2_x = tempStarPosX;  // record star pos 2
                        starPos2_y = tempStarPosY;
                        qDebug() << "star pos2" << starPos2_x << starPos2_y;

                        setCurrentStepIndex(STEP_ROTATE_SECOND);
                    }
                    else if(stepIndex == STEP_GET_STAR_THIRD)
                    {
                        starPos3_x = tempStarPosX;  //record star pos 3
                        starPos3_y = tempStarPosY;
                        qDebug() << "star pos3" << starPos3_x << starPos3_y;

                        ret = myTools.GetMathCircleCenter(starPos1_x, starPos1_y, starPos2_x, starPos2_y, starPos3_x, starPos3_y, &tempCenterX,
                                                          &tempCenterY, &tempRadius);
                        if (ret == RETURE_SUCCESS)
                        {
                            qDebug() << "axis center" << tempCenterX << tempCenterY << tempRadius;
                            curAxisX = tempCenterX;
                            curAxisY = tempCenterY;
                            curRadius = tempRadius;

                            setCurrentStepIndex(STEP_VALIDATE_CENTER);
                        }
                        else
                        {
                            QMessageBox::warning(this, tr("Warn"), tr("Can not get the Axis center, please click 'reset' to re-find it."));
                        }
                    }
                }
                else
                {
                    QMessageBox::warning(this, tr("Warn"), tr("Seems no star in this point, please try other point."));
                }
            }
            return true;
        }
        /*
        else if(camparam.isConnected && (e->type() == QEvent::MouseMove))
        {
            QMouseEvent *pMouseEvent = static_cast<QMouseEvent *>(e);
            float x = pMouseEvent->x() / scaledFactor;
            float y = pMouseEvent->y() / scaledFactor;
            this->label_status_mousePos->setText(QString::number(x, 'f', 1) + "," + QString::number(y, 'f', 1));

            if(ui->label_showImg->pixmap() == 0)
            {
                qCritical() << "no pixmap has been set in the Label_showImg";
            }
            else
            {
                widget_magnifier->setLoupePixmap(*ui->label_showImg->pixmap());
                widget_magnifier->setZoomRegionCenter(pMouseEvent->x(), pMouseEvent->y());
                widget_magnifier->update();
            }
            return true;
        }
        */
        else
        {
            return QObject::eventFilter(obj, e);
        }
    }
    else if((obj == tab_setting || obj == tab_confirm || obj == tab_getStar1 || obj == tab_rotateStar1 || obj == tab_getStar2 ||
             obj == tab_rotateStar2 || obj == tab_getStar3 || obj == tab_validateCenter || obj == tab_getEptPolaris ||
             obj == tab_movePolaris || obj == tab_getCurPolaris || obj == tab_calcPole || obj == tab_finetunePole) &&
            e->type() == QEvent::MouseMove && camparam.isConnected)
    {
        //get the mouse pos in the tab_setting, then calculate the relative pos in the showImg
        QMouseEvent *pMouseEvent = static_cast<QMouseEvent *>(e);
        int refPosx = tabWidget_tipMsg->x() + pMouseEvent->x();
        int refPosy = tabWidget_tipMsg->y() + pMouseEvent->y();

        this->label_status_mousePos->setText(QString::number(refPosx / scaledFactor, 'f',
                                             1) + "," + QString::number(refPosy / scaledFactor, 'f', 1));

        if(ui->label_showImg->pixmap().isNull())
        {
            qCritical() << "no pixmap has been set in the Label_showImg";
        }
        else
        {
            widget_magnifier->setLoupePixmap(ui->label_showImg->pixmap());
            widget_magnifier->setZoomRegionCenter(refPosx, refPosy);
            widget_magnifier->update();
        }

        return true;
    }
    else
    {
        // standard event processing
        return QObject::eventFilter(obj, e);
    }
}

void MainWindow::changeTipMsgContent(QString region)
{
    if(region.compare("North") == 0)
    {
        label_setting_tipMsg->setText(tr("Set the parameters to the left to make more stars around Polaris visable."));
        label_confirm_tipMsg->setText(
            tr("Double Click Polaris and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around Polaris."));
        label_getStar1_tipMsg->setText(
            tr("Choose a star other than Polaris and Double click it in the image. Remember this star, you will be selecting it again in the following steps (Step 1 of 3)."));
        label_getEptPolaris_tipMsg->setText(
            tr("Expected position: Double Click Polaris and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around Polaris."));
        label_movePolaris_tipMsg->setText(
            tr("Using your Altitude and Azimuth bolts, move Polaris into the center of the small Rotating circle now shown on the image."));
        label_getCurPolaris_tipMsg->setText(
            tr("Current position: Double Click Polaris and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around Polaris."));
    }
    else if(region.compare("South") == 0)
    {
        label_setting_tipMsg->setText(tr("Set the parameters to the left to make more stars around σ Oct visable."));
        label_confirm_tipMsg->setText(
            tr("Double Click σ Oct and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around σ Oct."));
        label_getStar1_tipMsg->setText(
            tr("Choose a star other than σ Oct and Double click it in the image. Remember this star, you will be selecting it again in the following steps (Step 1 of 3)."));
        label_getEptPolaris_tipMsg->setText(
            tr("Expected position: Double Click σ Oct and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around σ Oct."));
        label_movePolaris_tipMsg->setText(
            tr("Using your Altitude and Azimuth bolts, move σ Oct into the center of the small Rotating circle now shown on the image."));
        label_getCurPolaris_tipMsg->setText(
            tr("Current position: Double Click σ Oct and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around σ Oct."));
    }
}

void MainWindow::uiReset()
{
    ui->retranslateUi(this);

    //retranslate tip message content
    label_settiing_ask->setText(tr("Has setting up finished?"));
    pushButton_settingDone->setText(tr("Setting Finished"));

    label_confirm_ask->setText(tr("Does match success?"));
    pushButton_confirmDone->setText(tr("Success"));

    label_rotateStar1_tipMsg->setText(
        tr("Rotate your mounts 'RA' axis in the direction indicated by the arrow now at the top of the screen (rotate a minimum of 30 degree's)."));
    label_rotateStar1_ask->setText(tr("Has rotation finished?"));
    pushButton_rotateStar1_reset->setText(tr("Reset"));
    pushButton_rotateStar1_done->setText(tr("rotation Finished"));

    label_getStar2_tipMsg->setText(tr("Double click the same star again chosen in the previous step (Step 2 of 3)."));
    pushButton_getStar2_reset->setText(tr("Reset"));

    label_rotateStar2_tipMsg->setText(tr("Again, Rotate your mounts 'RA' axis in the same direction at least 30 degrees."));
    label_rotateStar2_ask->setText(tr("Has rotation finished?"));
    pushButton_rotateStar2_reset->setText(tr("Reset"));
    pushButton_rotateStar2_done->setText(tr("rotation Finished"));

    label_getStar3_tipMsg->setText(
        tr("Double click the same star one last time chosen in the previous 2 steps (Step 3 of 3)."));
    pushButton_getStar3_reset->setText(tr("Reset"));

    label_validateCenter_tipMsg->setText(
        tr("Return the 'RA' axis to the 'Home' position - Ensure your chosen star stays on the circle while your mount rotates to the PARK position."));
    label_validateCenter_ask->setText(tr("Is the axis center correct?"));
    pushButton_validateCenter_reset->setText(tr("Reset"));
    pushButton_validateCenter_done->setText(tr("Correct"));

    label_getEptPolaris_ask->setText(tr("Does match success?"));
    pushButton_getEptPolaris_done->setText(tr("Success"));

    label_movePolaris_ask->setText(tr("Has adjustment finished?"));
    pushButton_movePolaris_done->setText(tr("adjustment Finished"));

    label_getCurPolaris_ask->setText(tr("Does match success?"));
    pushButton_getCurPolaris_done->setText(tr("Success"));

    label_calcPole_tipMsg->setText(tr("Please click the 'Start Monitor' button."));

    label_finetunePole_tipMsg->setText(
        tr("Use your Altitude and Azimuth bolts only to move the Pole rectangle on top of the Axis circle."));
    pushButton_finetunePole_reset->setText(tr("Restart"));
    pushButton_finetunePole_done->setText(tr("Done"));

    if(region.compare("North") == 0)
    {
        label_setting_tipMsg->setText(tr("Set the parameters to the left to make more stars around Polaris visable."));
        label_confirm_tipMsg->setText(
            tr("Double Click Polaris and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around Polaris."));
        label_getStar1_tipMsg->setText(
            tr("Choose a star other than Polaris and Double click it in the image. Remember this star, you will be selecting it again in the following steps (Step 1 of 3)."));
        label_getEptPolaris_tipMsg->setText(
            tr("Expected position: Double Click Polaris and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around Polaris."));
        label_movePolaris_tipMsg->setText(
            tr("Using your Altitude and Azimuth bolts, move Polaris into the center of the small Rotating circle now shown on the image."));
        label_getCurPolaris_tipMsg->setText(
            tr("Current position: Double Click Polaris and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around Polaris."));
    }
    else if(region.compare("South") == 0)
    {
        label_setting_tipMsg->setText(tr("Set the parameters to the left to make more stars around σ Oct visable."));
        label_confirm_tipMsg->setText(
            tr("Double Click σ Oct and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around σ Oct."));
        label_getStar1_tipMsg->setText(
            tr("Choose a star other than σ Oct and Double click it in the image. Remember this star, you will be selecting it again in the following steps (Step 1 of 3)."));
        label_getEptPolaris_tipMsg->setText(
            tr("Expected position: Double Click σ Oct and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around σ Oct."));
        label_movePolaris_tipMsg->setText(
            tr("Using your Altitude and Azimuth bolts, move σ Oct into the center of the small Rotating circle now shown on the image."));
        label_getCurPolaris_tipMsg->setText(
            tr("Current position: Double Click σ Oct and use the 'Rotate' slider on the left to rotate the Template to match up to the stars around σ Oct."));
    }
}

void MainWindow::on_radioButton_north_toggled(bool checked)
{
    if(checked)
    {
        region = "North";
        qDebug() << "change region to " << region;

        posX_pole_mask = northStarsData.poleX;    // change current star data in template image
        posY_pole_mask = northStarsData.poleY;
        posX_starA_mask = northStarsData.starAX;
        posY_starA_mask = northStarsData.starAY;
        posX_starB_mask = northStarsData.starBX;
        posY_starB_mask = northStarsData.starBY;
        angleA_mask = northStarsData.angleBAP;
        angleB_mask = northStarsData.angleABP;

        curAngleA = angleA_mask;  //init current angleA angleB
        curAngleB = angleB_mask;

        changeTipMsgContent("North");

        setCurrentStepIndex(STEP_POLEMASTER_SETTING);  //back to setting step
    }
}

void MainWindow::on_radioButton_south_toggled(bool checked)
{
    if(checked)
    {
        region = "South";
        qDebug() << "change region to " << region;

        posX_pole_mask = southStarsData.poleX;     // change current star data in template image
        posY_pole_mask = southStarsData.poleY;
        posX_starA_mask = southStarsData.starAX;
        posY_starA_mask = southStarsData.starAY;
        posX_starB_mask = southStarsData.starBX;
        posY_starB_mask = southStarsData.starBY;
        angleA_mask = southStarsData.angleBAP;
        angleB_mask = southStarsData.angleABP;

        curAngleA = angleA_mask;  //init current angleA angleB
        curAngleB = angleB_mask;

        changeTipMsgContent("South");

        setCurrentStepIndex(STEP_POLEMASTER_SETTING);  //back to setting step
    }
}

void MainWindow::rotateTemplateImage(int angle)
{
    if(ui->label_templateImg->isVisible())
    {
        QTransform matrix;
        QImage rotatedImg;
        QImage srcImg;
        int srcImgW;
        int srcImgH;
        int xstart;
        int ystart;

        matrix.rotate(angle);
        if(region.compare("South") == 0)
        {
            srcImgW = southTemplateImg->width() * scaledFactor;
            srcImgH = southTemplateImg->height() * scaledFactor;
            srcImg = southTemplateImg->scaled(srcImgW, srcImgH, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        }
        else
        {
            srcImgW = northTemplateImg->width() * scaledFactor;
            srcImgH = northTemplateImg->height() * scaledFactor;
            srcImg = northTemplateImg->scaled(srcImgW, srcImgH, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        }

        rotatedImg = srcImg.transformed(matrix, Qt::SmoothTransformation);

        xstart = templateImgCenter.x() - rotatedImg.rect().center().x();
        ystart = templateImgCenter.y() - rotatedImg.rect().center().y();
        //qDebug() << "template center" << templateImgCenter.x() << templateImgCenter.y();

        ui->label_templateImg->setGeometry(xstart, ystart, rotatedImg.width(), rotatedImg.height());
        ui->label_templateImg->setPixmap(QPixmap::fromImage(rotatedImg));
    }
}

void MainWindow::on_horizontalSlider_confirm_match_valueChanged(int value)
{
    rotateAngle = value;  //hold on current angle of template image rotating.

    rotateTemplateImage(value);
}

void MainWindow::on_pushButton_confirm_minus_clicked()
{
    rotateAngle -= 1;
    if(rotateAngle < 0)
        rotateAngle = 0;

    ui->horizontalSlider_confirm_match->setValue(rotateAngle);
}

void MainWindow::on_pushButton_confirm_add_clicked()
{
    rotateAngle += 1;
    if(rotateAngle > 360)
        rotateAngle = 360;

    ui->horizontalSlider_confirm_match->setValue(rotateAngle);
}


void MainWindow::on_horizontalSlider_rough_match_valueChanged(int value)
{
    rotateAngle = value;

    rotateTemplateImage(value);

    //calculate the expected polaris position
    double x1, y1;
    double dx, dy;
    myTools.imgRotatedPoint(rotateAngle, posX_pole_mask, posY_pole_mask, posX_starB_mask, posY_starB_mask, &x1, &y1);
    double posX_pole_image = posX_starN - posX_starB_mask + x1;
    double posY_pole_image = posY_starN - posY_starB_mask + y1;
    dx = posX_pole_image - curAxisX;
    dy = posY_pole_image - curAxisY;

    curEptPolarisX = posX_starN - dx;  //expected polaris position
    curEptPolarisY = posY_starN - dy;

    ui->label_eptPos->setText("(" + QString::number(curEptPolarisX, 'f', 1) + "," + QString::number(curEptPolarisY, 'f',
                              1) + ")");

}

void MainWindow::on_pushButton_rough_minus_clicked()
{
    rotateAngle -= 1;
    if(rotateAngle < 0)
        rotateAngle = 0;

    ui->horizontalSlider_rough_match->setValue(rotateAngle);
}

void MainWindow::on_pushButton_rough_add_clicked()
{
    rotateAngle += 1;
    if(rotateAngle > 360)
        rotateAngle = 360;

    ui->horizontalSlider_rough_match->setValue(rotateAngle);
}

void MainWindow::on_pushButton_monitor_clicked()
{
    setCurrentStepIndex(STEP_FINE_TUNE_POLE);
}


void MainWindow::on_actionSave_As_triggered()
{
    if(camparam.isConnected)
    {
        qDebug() << "click save as...";
        QString filename = QFileDialog::getSaveFileName(this, tr("Save"), "", tr("Images (*.png *.jpg *.bmp)"));
        if (!filename.isNull())
        {
            capImg.save(filename);
        }
    }
}

void MainWindow::on_actionExit_triggered()
{
    //qDebug() << "click exit";
    this->close();
}

void MainWindow::on_actionConnect_triggered()
{
    //qDebug() << "click connect";
    uint32_t ret = QHYCCD_ERROR;

    if(camparam.canUseSDK)
    {
        if(camparam.isConnected)
        {
            //camera already connected, start to disconnet it.

            if(captureFrameThread->isRunning())
            {
                captureFrameThread->stopThread();
            }

            if(camhandle)
            {
                ret = StopQHYCCDLive(camhandle);
                if(ret == QHYCCD_SUCCESS)
                {
                    qDebug() << "StopQHYCCDLive";
                }

                ret = CloseQHYCCD(camhandle);
                if(ret == QHYCCD_SUCCESS)
                {
                    qDebug() << "CloseQHYCCD";
                    camparam.isConnected = false;

                    ui->actionConnect->setText(tr("Connect"));
                    setCurrentStepIndex(0);

                    ui->actionSave_As->setEnabled(false);
                    ui->actionDisplay_Template->setEnabled(false);
                    ui->actionAstronomical_Refraction->setEnabled(false);
                    ui->actionManual_Trace->setEnabled(false);
                    ui->menuZoom->setEnabled(false);
                }

                label_status_mousePos->clear();
                camparam.fps_1 = 0;
                camparam.fps_2 = 0;
                frameQueue.clear();
                ui->label_showImg->clear();
                widget_magnifier->setLoupePixmap(QPixmap::fromImage(*img_magnifier));
                widget_magnifier->update();
            }
        }
        else
        {
            //camera not connect, then start to connect it.
            bool foundDevice = false;

            int num = ScanQHYCCD();
            if (num > 0)
            {
                for (int i = 0; i < num; i++)
                {
                    ret = GetQHYCCDId(i, camparam.camID);
                    if (ret == QHYCCD_SUCCESS)
                    {
                        QString sid = QString(camparam.camID);
                        QString camModel = sid.left(sid.lastIndexOf('-')); // get device name
                        if (camModel.compare("POLEMASTER") == 0)
                        {
                            foundDevice = true;
                            // if it is poleMaster device. then can connect.
                            break;
                        }
                    }
                }

                if (foundDevice)
                {
                    camhandle = OpenQHYCCD(camparam.camID);
                    if (camhandle != NULL)
                    {
                        ret = SetQHYCCDReadMode(camhandle, 0);
                        if(ret == QHYCCD_ERROR)
                        {
                            qCritical() << "SetQHYCCDReadMode 0 Failure";
                        }

                        ret = SetQHYCCDStreamMode(camhandle, camparam.streammode);
                        if (ret != QHYCCD_SUCCESS)
                        {
                            qCritical() << "SetQHYCCDStreamMode 1 Failure";
                        }
                        else
                        {
                            ret = InitQHYCCD(camhandle);
                            if (ret == QHYCCD_SUCCESS)
                            {
                                camparam.isConnected = true;

                                ui->actionConnect->setText(tr("Disconnect"));
                                setCurrentStepIndex(STEP_POLEMASTER_SETTING);  //connect success, then goto PoleMaster Setting step

                                ui->actionSave_As->setEnabled(true);
                                ui->actionDisplay_Template->setEnabled(true);
                                ui->actionAstronomical_Refraction->setEnabled(true);
                                ui->actionManual_Trace->setEnabled(true);
                                ui->menuZoom->setEnabled(true);

                                this->setWindowTitle(QString("PoleMaster - ID:%1").arg(QString(camparam.camID)));

                                //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;
                                }

                                camparam.exptime = GetQHYCCDParam(camhandle, CONTROL_EXPOSURE);
                                ui->sliderExpose->blockSignals(true);
                                ui->sliderExpose->setValue((int)camparam.exptime / 1000);
                                ui->sliderExpose->blockSignals(false);
                                ui->lineEditExpose->setText(QString::number((int)camparam.exptime / 1000));
                                camparam.gain = GetQHYCCDParam(camhandle, CONTROL_GAIN);
                                ui->sliderGain->blockSignals(true);
                                ui->sliderGain->setValue((int)camparam.gain);
                                ui->sliderGain->blockSignals(false);
                                ui->lineEditGain->setText(QString::number((int)camparam.gain));

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

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

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

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

                                //start thread to capture frames
                                captureFrameThread->startThread();
                            }
                            else
                            {
                                qCritical() << "InitQHYCCD failure!";
                                camparam.isConnected = false;
                                QMessageBox::critical(this, tr("Error"), tr("Can not connect PoleMaster as InitQHYCCD error!"));
                            }
                        }
                    }
                    else
                    {
                        qCritical() << "OpenQHYCCD failure!";
                        camparam.isConnected = false;
                        QMessageBox::critical(this, tr("Error"), tr("Can not connect PoleMaster as OpenQHYCCD error!"));
                    }
                }
            }

            if(!foundDevice)
            {
                QMessageBox::information(this, tr("Info"), tr("Not Found QHYCCD PoleMaster equipment!"));
            }
        }
    }
}

void MainWindow::on_actionDisplay_Template_toggled(bool arg1)
{
    qDebug() << "click display tempalte" << arg1;
}

void MainWindow::on_actionMono_Style_toggled(bool arg1)
{
    if(arg1)
    {
        qDebug() << "switch to mono style";
        viewStyle = "Mono";

        dropShowEffect_confirm->setColor(QColor(248, 248, 255)); //change graphics effect color
        dropShowEffect_rough->setColor(QColor(248, 248, 255));

        ui->label_precise_poleIcon->setPixmap(QPixmap(":/images/pole.png"));
        ui->label_precise_axisIcon->setPixmap(QPixmap(":/images/center.png"));

        if(stepIndex == STEP_GET_STAR_FIRST)
        {
            ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
            ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
            ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
        }
        else if(stepIndex == STEP_ROTATE_FIRST || stepIndex == STEP_GET_STAR_SECOND)
        {
            ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
            ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
            ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
        }
        else if(stepIndex == STEP_ROTATE_SECOND || stepIndex == STEP_GET_STAR_THIRD)
        {
            ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
            ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
            ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_mono.png"));
        }
        else if(stepIndex == STEP_VALIDATE_CENTER || stepIndex == STEP_GET_EXPECT_POLARIS || stepIndex == STEP_GET_CUR_POLARIS)
        {
            ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
            ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
            ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lighton_mono.png"));
        }
    }
    else
    {
        qDebug() << "switch to color style";
        viewStyle = "Color";

        dropShowEffect_confirm->setColor(QColor(224, 134, 26)); //change graphics effect color
        dropShowEffect_rough->setColor(QColor(224, 134, 26));

        ui->label_precise_poleIcon->setPixmap(QPixmap(":/images/pole_color.png"));
        ui->label_precise_axisIcon->setPixmap(QPixmap(":/images/center_color.png"));

        if(stepIndex == STEP_GET_STAR_FIRST)
        {
            ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
            ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
            ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
        }
        else if(stepIndex == STEP_ROTATE_FIRST || stepIndex == STEP_GET_STAR_SECOND)
        {
            ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
            ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
            ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
        }
        else if(stepIndex == STEP_ROTATE_SECOND || stepIndex == STEP_GET_STAR_THIRD)
        {
            ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
            ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
            ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lightoff_color.png"));
        }
        else if(stepIndex == STEP_VALIDATE_CENTER || stepIndex == STEP_GET_EXPECT_POLARIS || stepIndex == STEP_GET_CUR_POLARIS)
        {
            ui->label_starPos1_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
            ui->label_starPos2_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
            ui->label_starPos3_icon->setPixmap(QPixmap(":/images/lighton_color.png"));
        }
    }
}

void MainWindow::on_actionStretch_toggled(bool arg1)
{
    qDebug() << "click stretch" << arg1;
}

void MainWindow::on_actionAstronomical_Refraction_triggered()
{
    //qDebug() << "click astronomical refraction";
    astroRefDialog->show();
}

void MainWindow::on_actionManual_Trace_triggered()
{
    //qDebug() << "click manual trace";
    poleTrackingDialog->show();
}

void MainWindow::on_action100_toggled(bool arg1)
{
    if(arg1)
    {
        scaledFactor = 1.0;

        //scaled direction image
        scaledDirectionImg(scaledFactor);

        //update current label_templateImg
        setCurrentTemplateImg(scaledFactor, region);

        if(stepIndex == STEP_CONFIRM_POLARIS || stepIndex == STEP_GET_EXPECT_POLARIS || stepIndex == STEP_GET_CUR_POLARIS)
        {
            templateImgCenter.setX(templateImgCenter_originalImg.x() * scaledFactor); //update curent center point of template image.
            templateImgCenter.setY(templateImgCenter_originalImg.y() * scaledFactor);

            rotateTemplateImage(rotateAngle);
        }
    }
}

void MainWindow::on_action75_toggled(bool arg1)
{
    if(arg1)
    {
        scaledFactor = 0.75;

        //scaled direction image
        scaledDirectionImg(scaledFactor);

        //update current label_templateImg
        setCurrentTemplateImg(scaledFactor, region);

        if(stepIndex == STEP_CONFIRM_POLARIS || stepIndex == STEP_GET_EXPECT_POLARIS || stepIndex == STEP_GET_CUR_POLARIS)
        {
            templateImgCenter.setX(templateImgCenter_originalImg.x() * scaledFactor); //update curent center point of template image.
            templateImgCenter.setY(templateImgCenter_originalImg.y() * scaledFactor);

            rotateTemplateImage(rotateAngle);
        }
    }
}

void MainWindow::on_action50_toggled(bool arg1)
{
    if(arg1)
    {
        scaledFactor = 0.5;

        //scaled direction image
        scaledDirectionImg(scaledFactor);

        //update current label_templateImg
        setCurrentTemplateImg(scaledFactor, region);

        if(stepIndex == STEP_CONFIRM_POLARIS || stepIndex == STEP_GET_EXPECT_POLARIS || stepIndex == STEP_GET_CUR_POLARIS)
        {
            templateImgCenter.setX(templateImgCenter_originalImg.x() * scaledFactor); //update curent center point of template image.
            templateImgCenter.setY(templateImgCenter_originalImg.y() * scaledFactor);

            rotateTemplateImage(rotateAngle);
        }
    }
}

void MainWindow::on_actionPoleMaster_Manual_triggered()
{
    if(lang.compare("ZH") == 0)
    {
        QDesktopServices::openUrl(QUrl("https://www.qhyccd.cn/polemaster/"));
    }
    else
    {
        QDesktopServices::openUrl(QUrl("https://www.qhyccd.com/polemaster/"));
    }
}

void MainWindow::on_actionAbout_triggered()
{
    //qDebug() << "click about";
    aboutDialog->show();
}

void MainWindow::on_actionEnglish_toggled(bool arg1)
{
    if(arg1)
    {
        lang = "EN";
        emit changeLanguage();//emit the signal to retranslate the ui of each dialog
    }
}

void MainWindow::on_actionChinese_toggled(bool arg1)
{
    if(arg1)
    {
        lang = "ZH";
        emit changeLanguage();//emit the signal to retranslate the ui of each dialog
    }
}

void MainWindow::on_actionJapanese_toggled(bool arg1)
{
    if(arg1)
    {
        lang = "JA";
        emit changeLanguage();//emit the signal to retranslate the ui of each dialog
    }
}

void MainWindow::on_actionRussian_toggled(bool arg1)
{
    if(arg1)
    {
        lang = "RU";
        emit changeLanguage();//emit the signal to retranslate the ui of each dialog
    }
}

void MainWindow::on_actionFrench_toggled(bool arg1)
{
    if(arg1)
    {
        lang = "FR";
        emit changeLanguage();//emit the signal to retranslate the ui of each dialog
    }
}

void MainWindow::on_actionGerman_toggled(bool arg1)
{
    if(arg1)
    {
        lang = "DE";
        emit changeLanguage();//emit the signal to retranslate the ui of each dialog
    }
}

void MainWindow::on_actionSpanish_toggled(bool arg1)
{
    if(arg1)
    {
        lang = "ES";
        emit changeLanguage();//emit the signal to retranslate the ui of each dialog
    }
}

void MainWindow::on_actionPortuguese_toggled(bool arg1)
{
    if(arg1)
    {
        lang = "PT";
        emit changeLanguage();//emit the signal to retranslate the ui of each dialog
    }
}

void MainWindow::on_actionItalian_toggled(bool arg1)
{
    if(arg1)
    {
        lang = "IT";
        emit changeLanguage();//emit the signal to retranslate the ui of each dialog
    }
}

void MainWindow::on_actionKorean_toggled(bool arg1)
{
    if(arg1)
    {
        lang = "KO";
        emit changeLanguage();//emit the signal to retranslate the ui of each dialog
    }
}


void MainWindow::on_sliderExpose_valueChanged(int value)
{
    camparam.exptime = (double)value * 1000.0;
    ui->lineEditExpose->setText(QString::number(value));
    uint32_t ret = QHYCCD_ERROR;
    ret = SetQHYCCDParam(camhandle, CONTROL_EXPOSURE, camparam.exptime);
}

void MainWindow::on_lineEditExpose_returnPressed()
{
    ui->sliderExpose->blockSignals(true);

    if(ui->lineEditExpose->text().toInt() < ui->sliderExpose->minimum())
        ui->lineEditExpose->setText(QString::number(ui->sliderExpose->minimum()));
    if(ui->lineEditExpose->text().toInt() > ui->sliderExpose->maximum())
        ui->lineEditExpose->setText(QString::number(ui->sliderExpose->maximum()));
    ui->sliderExpose->setValue(ui->lineEditExpose->text().toInt());

    ui->sliderExpose->blockSignals(false);

    camparam.exptime = ui->lineEditExpose->text().toDouble() * 1000.0;
    uint32_t ret = QHYCCD_ERROR;
    ret = SetQHYCCDParam(camhandle, CONTROL_EXPOSURE, camparam.exptime);
}

void MainWindow::on_sliderGain_valueChanged(int value)
{
    camparam.gain = (double)value;
    ui->lineEditGain->setText(QString::number(value));
    uint32_t ret = QHYCCD_ERROR;
    ret = SetQHYCCDParam(camhandle, CONTROL_GAIN, camparam.gain);
}

void MainWindow::on_lineEditGain_returnPressed()
{
    ui->sliderGain->blockSignals(true);

    if(ui->lineEditGain->text().toInt() < ui->sliderGain->minimum())
        ui->lineEditGain->setText(QString::number(ui->sliderGain->minimum()));
    if(ui->lineEditGain->text().toInt() > ui->sliderGain->maximum())
        ui->lineEditGain->setText(QString::number(ui->sliderGain->maximum()));
    ui->sliderGain->setValue(ui->lineEditGain->text().toInt());

    ui->sliderGain->blockSignals(false);

    camparam.gain = ui->lineEditGain->text().toDouble();
    uint32_t ret = QHYCCD_ERROR;
    ret = SetQHYCCDParam(camhandle, CONTROL_GAIN, camparam.gain);
}

void MainWindow::on_sliderTraffic_valueChanged(int value)
{
    camparam.usbtraffic = (double)value;
    ui->lineEditTraffic->setText(QString::number(value));
    uint32_t ret = QHYCCD_ERROR;
    ret = SetQHYCCDParam(camhandle, CONTROL_USBTRAFFIC, camparam.usbtraffic);
}

void MainWindow::on_lineEditTraffic_returnPressed()
{
    ui->sliderTraffic->blockSignals(true);

    if(ui->lineEditTraffic->text().toInt() < ui->sliderTraffic->minimum())
        ui->lineEditTraffic->setText(QString::number(ui->sliderTraffic->minimum()));
    if(ui->lineEditTraffic->text().toInt() > ui->sliderTraffic->maximum())
        ui->lineEditTraffic->setText(QString::number(ui->sliderTraffic->maximum()));
    ui->sliderTraffic->setValue(ui->lineEditTraffic->text().toInt());

    ui->sliderTraffic->blockSignals(false);

    camparam.usbtraffic = ui->lineEditTraffic->text().toDouble();
    uint32_t ret = QHYCCD_ERROR;
    ret = SetQHYCCDParam(camhandle, CONTROL_USBTRAFFIC, camparam.usbtraffic);
}

void MainWindow::on_sliderSpeed_valueChanged(int value)
{
    camparam.speed = (double)value;
    ui->lineEditSpeed->setText(QString::number(value));
    uint32_t ret = QHYCCD_ERROR;
    ret = SetQHYCCDParam(camhandle, CONTROL_SPEED, camparam.speed);
}

void MainWindow::on_lineEditSpeed_returnPressed()
{
    ui->sliderSpeed->blockSignals(true);

    if(ui->lineEditSpeed->text().toInt() < ui->sliderSpeed->minimum())
        ui->lineEditSpeed->setText(QString::number(ui->sliderSpeed->minimum()));
    if(ui->lineEditSpeed->text().toInt() > ui->sliderSpeed->maximum())
        ui->lineEditSpeed->setText(QString::number(ui->sliderSpeed->maximum()));
    ui->sliderSpeed->setValue(ui->lineEditSpeed->text().toInt());

    ui->sliderSpeed->blockSignals(false);

    camparam.speed = ui->lineEditSpeed->text().toDouble();
    uint32_t ret = QHYCCD_ERROR;
    ret = SetQHYCCDParam(camhandle, CONTROL_SPEED, camparam.speed);
}

void MainWindow::on_actionFavorite_triggered()
{
    favoriteDialog->show();
}

void MainWindow::on_actionPlay_Audio_toggled(bool arg1)
{
    //    ui->actionPlay_Audio->setChecked(arg1);

    //    if(arg1)
    //    {
    //        Music->play();
    //    }
    //    else
    //    {
    //         Music->stop();
    //    }
}

void MainWindow::on_actionPlay_Audio_triggered(bool checked)
{
    //    ui->actionPlay_Audio->setChecked(checked);

    if(checked)
        Music->play();
    else
        Music->stop();
}
