#include <QApplication>
#include <QDesktopWidget>
#include <QTime>
#include <QMessageBox>
#include <QTextCodec>
#include <QTranslator>
#include <QSplashScreen>

#include "mainwindow.h"
#include "cchannel.h"
#include "cmakepath.h"
#include "cmallsystem.h"

#include "logic.h"
#include "CrashHandler.h"
#include "secsmanager.h"
#include "AuthorityManager/cmwauthoritymanager.h"

//#include "vld.h"
//#define GLOG_NO_ABBREVIATED_SEVERITIES
#include <cpp/HalconCpp.h>
#include "glog/logging.h"
//#include <QStyleFactory>

//自定义错误码
#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll

static void HalconExceptionHandler(const Halcon::HException& except)
{
    QString str=QObject::trUtf8("Algorithm err;Code:%1;Command:%2;Message:%3")
            .arg((int)except.err).arg(except.proc).arg(except.message);
    str.replace("HALCON","OpenCV");
    throw(str);
}
bool Checkinstance()
{
    HANDLE m_hMutex=CreateMutex(NULL,FALSE,"LowKCut");
    if(GetLastError()==ERROR_ALREADY_EXISTS)
    {
        CloseHandle(m_hMutex);
        m_hMutex=NULL;
        return true;
    }
    return false;
}
int main(int argc, char *argv[])
{
    Halcon::HException::InstallHHandler(&HalconExceptionHandler);

	CCrashHandler::SetProcessExceptionHandlers();
	CCrashHandler::SetThreadExceptionHandlers();

	
//////////////////////////winsock start up/////////////
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested =MAKEWORD( 2, 1 );
    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 ) {
    /* Tell the user that we couldn't find a useable */
    /* winsock.dll. */
    MqDebug()<<err;
    return -1;
    }
//////////////////////////winsock start up Finish/////////////

    QApplication a(argc, argv);
    //处理opengl异常
    //blog.csdn.net/qq_38264844/article/details/118753917
    QApplication::setAttribute(Qt::AA_DisableShaderDiskCache);

    /*CMWAuthorityManager x;
    x.showNormal();
    a.exec();
    return -1;*/

	if(Checkinstance())
    {
        QMessageBox::warning(0,
                             QObject::trUtf8("Check"),
                             QObject::trUtf8("Process already exist."),
                             QMessageBox::Ok);
        return 0;
    }
	//68305024
	/*CCamDriver_IMG* pcard=new CCamDriver_IMG("Camera Driver", 1);
	pcard->init_driver();
	CCam_IMG* pCam2X=new CCam_IMG("Cam2",1);
	pCam2X->m_Variants.set_VData(Var_Base_SerialID_ID, "");
	pCam2X->init_channel();

	pcard->addChannel(pCam2X);
	{
	CMImage mImage;

	pcard->grab_image(1, &mImage);

	QImage img(pCam2X->m_pRawImageData,4000,3000,
		QImage::Format_Grayscale8);

	bool b = img.save("file3.jpg","JPG", 100);
	}

	return 0;*/

	/*
    QTranslator appTranslater;
    appTranslater.load(CMakePath::make_bin_path("../theme/project_cn"));
    a.installTranslator(&appTranslater);
	*/

    static CMAllsystem s_System;

    SystemHelper::Instance().SetInstance(&s_System);
    CMSystemHelper::Instance().SetInstance(&s_System);
    SystemExternalHelper::Instance().SetInstance(&s_System);

    QSplashScreen *pSlash=new QSplashScreen();
    QPixmap pixmap(600,400);
    pixmap.load(CMakePath::make_bin_path("../theme/Splash.png"));

    pSlash->setPixmap(pixmap);
    //   QImage image;
    //   image.load(CMakePath::make_bin_path("Splash.png"));
    //   pSlash->setPixmap(QPixmap::fromImage(image));
    pSlash->show();

    QIcon icon_window;
    icon_window.addFile(CMakePath::make_bin_path("../theme/logo.ico"));
    a.setWindowIcon(icon_window);

	//a.setStyle(QStyleFactory::create("Fusion"));

    google::InitGoogleLogging(argv[0]);
    FLAGS_log_dir = "log";
    FLAGS_logbufsecs = 1;
	//FLAGS_max_log_size = 5;
	google::SetLogDestination(google::GLOG_INFO, "log\\info_");
	google::SetLogDestination(google::GLOG_ERROR, "log\\error_");
	google::SetLogDestination(google::GLOG_WARNING, "log\\warning_");
	//google::EnableLogCleaner(30);
	//LOG(INFO)<<"Test";
    try
    {
        m_gSystem.createSystem();

    }
    catch(QString& s)
    {
        QMessageBox box;
        box.setText(s);
        box.exec();
		google::ShutdownGoogleLogging();
        return -100;
    }

    m_gSystem.initSystem();
    while (!m_gSystem.isInitFininshed())
    {
        if(m_gSystem.m_SysMsg.m_bSet)
        {
            m_gSystem.m_SysMsg.m_bSet= false;
            pSlash->showMessage(m_gSystem.m_SysMsg.GetMsg(),
                                Qt::AlignLeft|Qt::AlignBottom,
                                Qt::green);
        }
    }

    if(!m_gSystem.isInitSuccessed())
    {
        delete pSlash;
        QMessageBox box;
        box.setText(m_gSystem.m_SysMsg.GetMsg());
        box.exec();
        m_gSystem.exitSystem();
        QMessageBox::information(0,
                                 QObject::trUtf8("Exit"),
                                 QObject::trUtf8("Exit Success."),
                                 QMessageBox::Ok);
		google::ShutdownGoogleLogging();
        return -1;
    }

	if(0!=g_SecsManager.InitConnect()){
		delete pSlash;
		QMessageBox box;
		box.setText("Init MES failed");
		box.exec();
		m_gSystem.exitSystem();
		QMessageBox::information(0,
			QObject::trUtf8("Exit"),
			QObject::trUtf8("Exit Success."),
			QMessageBox::Ok);
		google::ShutdownGoogleLogging();
	}
	m_gSystem.prepareSystem();
	

//    QTime time1;time1.start();
//    while(time1.elapsed()<600);
    //MqDebug()<<"Start MainWindow..";
    //   int isizex=QApplication::desktop()->width();
    //   w.setMaximumWidth(isizex);

    QString strQssPath=CMakePath::make_bin_path("../theme/styleSheet-Light.qss");
    uint qsstype=m_gSystem.m_Variants.get_VData(Var_AllSystem_StyleSheet_Type_ID)
            ->toUInt();
    if(qsstype==1)
    {
        strQssPath=CMakePath::make_bin_path("../theme/styleSheet-Dark.qss");
    }
    QFile file(strQssPath);
    file.open(QFile::ReadOnly);
    QString styleSheet = file.readAll();
    a.setStyleSheet(styleSheet);
    file.close();

    MainWindow w;
    m_gMainWindow=&w;


    m_gSystem.m_pfnNotifyLogMessage = std::function<void(const QString&, int)>(std::bind(&MainWindow::SendNotifyLogMessage, &w, std::placeholders::_1, std::placeholders::_2));
    m_gSystem.m_pfnNotifyTerminalMessage = std::function<void(const std::string&)>(std::bind(&MainWindow::SendTerminalMessage, &w, std::placeholders::_1));
    m_gSystem.m_pfnGetLightData = std::function<void(int&, int&, int iCamIndex)>(std::bind(&MainWindow::GetLightData, &w, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    m_gSystem.m_pfnGetCamInfo = std::function<void(int&, int&, int iCamIndex)>(std::bind(&MainWindow::GetCamInfo, &w, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
	m_gSystem.m_pfnSetCamInfo = std::function<void(int, int, int iCamIndex)>(std::bind(&MainWindow::SetCamInfo, &w, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    m_gSystem.m_pfnSetLightData = std::function<void(int, int, int iCamIndex)>(std::bind(&MainWindow::SetLightData, &w, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    m_gSystem.m_pfnShowPowerMsg = std::function<void(bool bVisible)>(std::bind(&MainWindow::SendPowerMessage, &w, std::placeholders::_1));
    m_gSystem.runSystem();
    w.mainwindow_Init();
    //    m_gSystem.publish_msg(CStateMachine::STATE_MANUAL,SIG_STOP);
    m_gSystem.m_SysMsg.m_bSet=false;
    uint iShowType=m_gSystem.m_Variants.get_VData(Var_AllSystem_FullScreen_ID)
            ->toUInt();
    if(iShowType==0)
    {
        w.showFullScreen();

		//解决全屏不能显示combox
		QRect  rect = qApp->desktop()->geometry();
		rect.setY(-1);
		rect.setHeight(rect.height());

		w.setGeometry(rect);
    }
    else if(iShowType==1)
    {
        w.ShowMax();
    }
    else
    {
        w.show();
    }
    pSlash->finish(&w);

    QString strFilePath=a.applicationFilePath();
    QFileInfo info(strFilePath);
    QDateTime time= info.lastModified();
    QString title= strFilePath+"-"+time.toString( Qt::ISODate);

    w.setWindowTitle(title);

    int irtn= a.exec();

    CLaserDriver* pLaserDriver=GET_CARD(LASER_DRIVER,CLaserDriver);
    Q_ASSERT(pLaserDriver);

    pLaserDriver->m_bCloseLaser= QMessageBox::question(0,
                                                       QObject::trUtf8("Laser"),
                                                       QObject::trUtf8("Shutdown laser or not?\n"
                                                                       "Click \"Yes\" to shutdown.\n"
                                                                       "Click \"No\" to ignore.\n" ),
                                                       QMessageBox::Yes|QMessageBox::No)==QMessageBox::Yes;


    MqDebug()<<"exec exit";
    m_gSystem.exitSystem();
    pSlash->show();
    while (!m_gSystem.isExitFinished())
    {
        if(m_gSystem.m_SysMsg.m_bSet)
        {
            m_gSystem.m_SysMsg.m_bSet=false;
            pSlash->showMessage(m_gSystem.m_SysMsg.GetMsg(),
                                Qt::AlignLeft|Qt::AlignBottom,
                                Qt::green);
        }
    }
    pSlash->hide();
    MqDebug()<<"exitSystem exit";
    w.mainwindow_Exit();
    MqDebug()<<"mainwindow_Exit exit";

    try
    {
        m_gSystem.write_config( true);
    }
    catch(QString& s)
    {
        QMessageBox box;
        box.setText(s);
        box.exec();
    }

    MqDebug()<<"write_config to exit";
    QMessageBox::information(0,
                             QObject::trUtf8("Exit"),
                             QObject::trUtf8("Exit Success."),
                             QMessageBox::Ok);

    delete pSlash;

/////////////////////////////win sock clean up///////////
    /* Confirm that the Windows Sockets DLL supports 1.1.*/
    /* Note that if the DLL supports versions greater */
    /* than 1.1 in addition to 1.1, it will still return */
    /* 1.1 in wVersion since that is the version we */
    /* requested. */
    if ( LOBYTE( wsaData.wVersion ) != 1 ||
    HIBYTE( wsaData.wVersion ) != 1 )
    {
    /* Tell the user that we couldn't find a useable */
    /* winsock.dll. */
    WSACleanup( );
    }
/////////////////////////////win sock clean up finish///////////

	//google::EnableLogCleaner(30);
	google::ShutdownGoogleLogging();

    return irtn;
}
