#include "claserdriver_jdsu.h"
#include "callsystem.h"
#include "cmserialport.h"

CLaserDriver_JDSU::CLaserDriver_JDSU(const QString &name, int32_t id)
    :CLaserDriver_Base(name,id)
{

}

CLaserDriver_JDSU::~CLaserDriver_JDSU()
{

}

int32_t CLaserDriver_JDSU::init_driver()
{
    m_pSerialPort->open();

    SetShutter(LASER,true);
    GetFreq(LASER);
    GetSerial(LASER);

    SetPowerRate(LASER,99);
    GetPowerRate(LASER);

    CLaser* pLaser=(CLaser*)FindChannel(LASER);
    Q_ASSERT(pLaser);
    dword_t dwFPKTime=
            pLaser->m_Variants.get_VData(Var_Laser_FPKTime_ID)->toInt();
    SetFPKTime(LASER,dwFPKTime,true);
    GetFPKTime(LASER);

    SetWorkMode(LASER,0);
    GetCurrent_Ref(LASER);
    GetCurrent_Cur(LASER);
    GetTHGTemp(LASER);
    GetDiodTemp(LASER);
    return CDriverCard::init_driver();
}

int32_t CLaserDriver_JDSU::exit_driver()
{
    if(m_bCloseLaser)
    {
        SetShutter(LASER,false);
    }
    m_pSerialPort->close();
    return RTN_SUCCESS1;
}


void CLaserDriver_JDSU::SendCommand(const char *pCommand, char *pResponse)
{

    QMutexLocker locker(&m_CardMutex);
    char ch[RESPONSELENGTH]={0};
    strcat(ch,"\x1B");
    strcat(ch,pCommand);
    strcat(ch,"\n\r");
    int isize=strlen(ch);

    qDebug()<<"JDSU Send:"<<ch;
    m_pSerialPort->send(ch,isize);
    int iWaitTime=50;
    MSleep(iWaitTime);
    int32_t irtn=m_pSerialPort->wait();
    m_pSerialPort->receive(pResponse,irtn);

    qDebug()<<"JDSU Response:"<<pResponse;
    memset(ch,0,RESPONSELENGTH);
    int iR=0,ich=0;

    while(pResponse[iR])
    {
        if(pResponse[iR]!='\r'&&pResponse[iR]!=':'&&
                pResponse[iR]!=' '&&pResponse[iR]!='\n')
        {
            ch[ich]=pResponse[iR];
            ich++;
        }
        iR++;
    }
    strcpy(pResponse,ch);

}

void CLaserDriver_JDSU::SendCommand(const char *pCommand, char *pResponse, char *pOkMsg)
{
    SendCommand(pCommand,pResponse);
    if(strcmp(pResponse,pOkMsg))
    {
        MQT_THROW_STR(QObject::trUtf8("Laser response err.Correct response:%1"
                                      "Current response:%2").arg(pOkMsg).arg(pResponse));

    }
}

char * CLaserDriver_JDSU::GetNums(char *pResponse)
{
   char ch[RESPONSELENGTH]={0};
   int iR=0,ich=0;
   while(pResponse[iR])
   {
       if((pResponse[iR]>='0'&&pResponse[iR]<='9')
               ||pResponse[iR]=='.')
       {
           ch[ich]=pResponse[iR];
           ich++;
       }
       iR++;
   }
   strcpy(pResponse,ch);
   return pResponse;
}

int CLaserDriver_JDSU::SetFreq(int32_t laserid, float64_t dFreq)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
//    if(dFreq<100)
//    {sprintf(strComm,"09R4%03d",int(dFreq*10));}
//    else if(dFreq<1000)
//    {sprintf(strComm,"09R5%03d",int(dFreq));}
//    SendCommand(strComm,strReturn);
    sprintf(strComm,"08R%d",int(dFreq*1000));
    SendCommand(strComm,strReturn);
    double dFreqReturn=atof(GetNums(strReturn));
    double dDiff=fabs(dFreqReturn-dFreq);
    double dFreqTolerance=m_Variants.get_VData(Var_LaserDriver_FreqTolerance_ID)
            ->toDouble();
    if (dDiff>dFreqTolerance)
    {
        MQT_THROW_STR(QObject::trUtf8("Laser freq set err."
                      "set freq :%1."
                      "return freq :%2."
                      "freq tolerance:%3")
                      .arg(dFreq)
                      .arg(dFreqReturn)
                      .arg(dFreqTolerance));
    }
    pLaser->m_Variants.set_VData(Var_Laser_Freq_ID,dFreq);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetFreq(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"04R",0);
    SendCommand(strComm,strReturn);
    double dFreqReturn=atof(GetNums(strReturn));
    pLaser->m_Variants.set_VData(Var_Laser_Freq_ID,dFreqReturn);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::OpenLaserGate(int32_t laserid, bool_t bOpen)
{
#ifdef __USE_DWIDE_LASER__

    CMotorDriver* pDriver=GET_CARD(MOTOR_DRIVER,CMotorDriver);
    Q_ASSERT(pDriver);
    if (bOpen)
    {
        if(m_gEnbaleLaserOpen)
        {
            CLaser* pLaser=(CLaser*)FindChannel(LASER);
            Q_ASSERT(pLaser);
            GetLaserTime(LASER);
            int iLaserTime=pLaser->m_Variants.get_VData(Var_Laser_LaserTime_ID)->toInt();
            int iLaserTimeLimit=pLaser->m_Variants.get_VData(Var_Laser_LaserTime_Limit_ID)->toInt();

            if(iLaserTime>iLaserTimeLimit)
            {
                MQT_THROW_STR(QObject::trUtf8("Laser use time :%d hours "
                                              "bigger then limit time :%d")
                              .arg(iLaserTime).arg(iLaserTimeLimit));
            }
            pDriver->setio(IO_OUTPUT,OUT_LENS_Blow_Inner,true);
            pDriver->set_cylinder(OUT_Shutter_All_Open,IN_LASER_Shutter_All_Down);
            if (laserid==LASERPATH_D_WIDE)
            {
                pDriver->set_cylinder(OUT_Shutter_Narrow_Open,IN_LASER_Shutter_Narrow_Down);
                pDriver->set_cylinder(OUT_Shutter_Wide_Open,IN_LASER_Shutter_Narrow_Up,FALSE);
            }
            else if (laserid==LASERPATH_D_NARROW)
            {
                pDriver->set_cylinder(OUT_Shutter_Wide_Open,IN_LASER_Shutter_Wide_Down);
                pDriver->set_cylinder(OUT_Shutter_Narrow_Open,IN_LASER_Shutter_Narrow_Up,FALSE);
            }
            else
            {
                Q_ASSERT(0);
            }

        }
    }
    else
    {
        pDriver->set_cylinder(OUT_Shutter_All_Open,IN_LASER_Shutter_All_Up,FALSE);
        pDriver->setio(IO_OUTPUT,OUT_LENS_Blow_Inner,false);
    }
#endif
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::SetPowerRate(int32_t laserid, float64_t dPower)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    pLaser->m_Variants.set_VData(Var_Laser_Power_ID,dPower);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetPowerRate(int32_t laserid)
{
    UNUSED(laserid);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::SetGateSource(int32_t laserid, bool_t bInt)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    CMotorDriver_ACS* pMotorDriver=GET_CARD(MOTOR_DRIVER,CMotorDriver_ACS);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"Laser_On=%d",bInt?1:0);
    pMotorDriver->SendCommand(strComm,strReturn);
    pLaser->m_Variants.set_VData(Var_Laser_IntGate_ID,bInt?true:false);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::SetPRFSource(int32_t laserid, bool_t bExt)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);

    pLaser->m_Variants.set_VData(Var_Laser_ExtPRF_ID,bExt?true:false);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::SetFPKTime(int32_t laserid, dword_t dwTime, bool bEnable)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0},strOK[RESPONSELENGTH]={0};
    if(bEnable)
    {
        sprintf(strComm,"02F",0);
        sprintf(strOK,"FPSON",0);
    }
    else
    {
        sprintf(strComm,"03F",0);
        sprintf(strOK,"FPSOFF",0);
    }
    SendCommand(strComm,strReturn,strOK);

    pLaser->m_Variants.set_VData(Var_Laser_EnableFPK_ID,bEnable);
    pLaser->m_Variants.set_VData(Var_Laser_FPKTime_ID,int(dwTime));
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetFPKTime(int32_t laserid)
{
    UNUSED(laserid);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::SetShutter(int32_t laserid, bool_t bOn)
{
    UNUSED(laserid);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    if (bOn)
    {
        sprintf(strComm,"02I",0);
    }
    else
    {
        sprintf(strComm,"03I",0);
    }
    SendCommand(strComm,strReturn);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::SetCurrent_Ref(int32_t laserid, double dCurrent)
{
    UNUSED(laserid);
    UNUSED(dCurrent);
//    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
//    sprintf(strComm,"09A%.2f",dCurrent);
//    SendCommand(strComm,strReturn);
//    pLaser->mparams[CLaser::CURRENT_REF]->setDataDirect(dCurrent);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::SetCurrent_Max(int32_t laserid, double dCurrent)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    pLaser->m_Variants.set_VData(Var_Laser_Current_Max_ID,dCurrent);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetCurrent_Cur(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"04J",0);
    SendCommand(strComm,strReturn);
    double dCurrent_cur=atof(GetNums(strReturn));
    pLaser->m_Variants.set_VData(Var_Laser_Current_Cur_ID,dCurrent_cur);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetCurrent_Ref(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"04J",0);
    SendCommand(strComm,strReturn);
    double dCurrent_Ref=atof(GetNums(strReturn));
    pLaser->m_Variants.set_VData(Var_Laser_Current_Ref_ID,dCurrent_Ref);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetCurrent_Max(int32_t laserid)
{
    UNUSED(laserid);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetShutterStatus(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"04I",0);
    SendCommand(strComm,strReturn);
    bool bon=!strcmp(strReturn,"ShutOpen");
    pLaser->m_Variants.set_VData(Var_Laser_shutter_ID,bon);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetUVPower(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"047",0);
    SendCommand(strComm,strReturn);
    double dUVPower=atof(GetNums(strReturn));
    pLaser->m_Variants.set_VData(Var_Laser_UVPower_ID,dUVPower);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetLaserTime(int32_t laserid)
{
    UNUSED(laserid);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetSerial(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"041",0);
    SendCommand(strComm,strReturn);
    pLaser->m_Variants.set_VData(Var_Base_SerialID_ID,QString(strReturn));
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::SetDiodTemp(int32_t laserid, double dTemp)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"09B%.1f",dTemp);
    SendCommand(strComm,strReturn);
    pLaser->m_Variants.set_VData(Var_Laser_Diodtemp_ID,dTemp);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetDiodTempRef(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"04B",0);
    SendCommand(strComm,strReturn);
    double dDiodref=atof(GetNums(strReturn));
    pLaser->m_Variants.set_VData(Var_Laser_diodtempref_ID,dDiodref);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetDiodTemp(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"04C",0);
    SendCommand(strComm,strReturn);
    double dDiodtemp=atof(GetNums(strReturn));
    pLaser->m_Variants.set_VData(Var_Laser_Diodtemp_ID,dDiodtemp);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::SetTHGTempAdjust(int32_t laserid, byte adjust)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"09X%d",adjust);
    SendCommand(strComm,strReturn);
    pLaser->m_Variants.set_VData(Var_Laser_thgtempadjust_ID,(int)adjust);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetTHGTempAdjustRef(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"04X",0);
    SendCommand(strComm,strReturn);
    double dTempAdjustRef=atof(GetNums(strReturn));
    pLaser->m_Variants.set_VData(Var_Laser_thgtempadjustref_ID,(int)dTempAdjustRef);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetTHGTemp(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"14M",0);
    SendCommand(strComm,strReturn);
    double dTHGTemp=atof(GetNums(strReturn));
    pLaser->m_Variants.set_VData(Var_Laser_thgtemp_ID,dTHGTemp);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetTHGTempRef(int32_t laserid)
{

    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"14J",0);
    SendCommand(strComm,strReturn);
    double THGTempRef=atof(GetNums(strReturn));
    pLaser->m_Variants.set_VData(Var_Laser_thgtempref_ID,THGTempRef);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::SetWorkMode(int32_t laserid, int iworkMode)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0},strOK[RESPONSELENGTH]={0};
    switch(iworkMode)
    {
    case 0:
        sprintf(strComm,"09Q2",0);
       sprintf(strOK,"INTTRIG",0);
     //   sprintf(strOK,"INTERNAL",0);

        break;
    case 1:
        sprintf(strComm,"09Q1",0);
        sprintf(strOK,"CW",0);
        break;
    default:
        Q_ASSERT(0);
        break;
    }
    SendCommand(strComm,strReturn,strOK);

    pLaser->m_Variants.set_VData(Var_Laser_workmode_ID,(uint)iworkMode);
    return RTN_SUCCESS1;
}

int CLaserDriver_JDSU::GetWorkMode(int32_t laserid)
{
    CLaser* pLaser=(CLaser*)FindChannel(laserid);
    Q_ASSERT(pLaser);
    char strReturn[RESPONSELENGTH]={0},strComm[COMM_LEN]={0};
    sprintf(strComm,"04Q",0);
    SendCommand(strComm,strReturn);
    if(!strlen(strReturn))
    {
        MQT_THROW_STR(QObject::trUtf8("Laser error.Can not get laser work mode."));
    }
    if(!strcmp(strReturn,"INTERNAL"))
    {
        pLaser->m_Variants.set_VData(Var_Laser_workmode_ID,(uint)0);
    }
    else if(!strcmp(strReturn,"CW"))
    {
        pLaser->m_Variants.set_VData(Var_Laser_workmode_ID,(uint)1);
    }
    else
    {
        Q_ASSERT(0);
    }
    return RTN_SUCCESS1;
}
