#include "ccamdriver_mv.h"
#include "CameraApi.h"
#include "ccam_mv.h"
CCamDriver_MV::CCamDriver_MV(const QString &name, int32_t id)
    :CCamDriver(name,id)
{

}

int32_t CCamDriver_MV::init_driver()
{
    int                     iCameraCounts = 4;
    tSdkCameraDevInfo       tCameraEnumList[4];
    MVCAMFUN(CameraSdkInit(1));
    MVCAMFUN(CameraEnumerateDevice(tCameraEnumList,&iCameraCounts));

    int iSize=mchannels.size();
    if(iCameraCounts!=iSize)
    {
        MQT_THROW_STR(QObject::trUtf8("Need %1 Cam, Find %2 Cam ")
                      .arg(iSize).arg(iCameraCounts));
    }
    CHANNELMAP::iterator ii=mchannels.begin();
    for(;ii!=mchannels.end();ii++)
    {
        QByteArray sn= (*ii)->m_Variants.get_VData(Var_Base_SerialID_ID)->toString().toLatin1();
        int i=0;
        for(i=0;i<iCameraCounts;i++)
        {
            if(!strcmp(sn.data(),tCameraEnumList[i].acSn))
            {
                CCam_MV* pcamMV=( CCam_MV*)(*ii);
                memcpy(&pcamMV->m_MVCamInfo,tCameraEnumList+i,
                       sizeof(tSdkCameraDevInfo));
                break;
            }
        }
        if(i==iCameraCounts)
        {
            MQT_THROW_STR(QObject::trUtf8("Can not Find Cam %1 Info,Cam SN:%2")
                          .arg((*ii)->m_sName).arg(sn.data()));
        }
    }
    return CCamDriver::init_driver();
}

int32_t CCamDriver_MV::grab_image(int32_t camid, CMImage *pImageDest)
{
 //   QMutexLocker locker(&m_CardMutex);
    CCam_MV* pcam=(CCam_MV*)FindChannel(camid);
    Q_ASSERT(pcam);
    QMutexLocker locker1(&pcam->m_CHMutex);

    unsigned char* pFrameBuffer;
    INT iWidth,iHeight;
    MVCAMFUN(CameraPlay(pcam->m_MVCamHandle));
    MVCAMFUN(CameraGetImageBuffer(pcam->m_MVCamHandle,
                                                &pcam->m_MVCamFrameHead,
                                  &pFrameBuffer,1000));

   // pcam->SaveImage();
            iWidth=pcam->m_MVCamFrameHead.iWidth;
    iHeight=pcam->m_MVCamFrameHead.iHeight;


    int iWidth1=pcam->m_Variants.get_VData(Var_Cam_Width_ID)->toInt();
    int iHeight1=pcam->m_Variants.get_VData(Var_Cam_Height_ID)->toInt();


    bool bFold=pcam->m_Variants.get_VData(Var_Cam_Image_Fold)->toBool();
    if(bFold)
    {
        iWidth/=2;
        iHeight/=2;
    }
    if(iWidth!=iWidth1||iHeight!=iHeight1)
    {
            MQT_THROW_STR(QObject::trUtf8("%1 Bad Frame ").arg(pcam->m_sName));

    }

//    if(iWidth!=pcam->m_Variants.get_VData(Var_Cam_Width_ID)->toInt()||
//            iHeight!=pcam->m_Variants.get_VData(Var_Cam_Height_ID)->toInt())
//    {
//        QMutexLocker locker1(&pcam->m_imageContainer.mutex);
//        if(pcam->m_pRawImageData) delete [] pcam->m_pRawImageData;
//        pcam->m_pRawImageData=new uint8_t[iHeight*iWidth];
//        pcam->m_Variants.set_VData(Var_Cam_Width_ID,int(iWidth));
//        pcam->m_Variants.set_VData(Var_Cam_Height_ID,int(iHeight));
//        pcam->m_imageContainer.m_Image=CMImage(iWidth,iHeight,(uint8_t*)(pFrameBuffer));

//        locker1.unlock();
//    }
    int iMirrortype=NO_MIRROR;
    uint iFilpytpe= pcam->m_Variants.get_VData(Var_Cam_Image_Filp)->toUInt();
    switch(iFilpytpe)
    {
        case 1:iMirrortype=MIRROR_H; break;
        case 2:iMirrortype=MIRROR_V; break;
        case 3:iMirrortype=MIRROR_VH; break;
        default:break;
    }

    memcpy_mirror(pcam->m_pRawImageData,
                  (uint8_t*)(pFrameBuffer), iWidth, iHeight, iMirrortype,bFold);
    MVCAMFUN(CameraReleaseImageBuffer(pcam->m_MVCamHandle,pFrameBuffer));
    CCamDriver::grab_image(camid,pImageDest);
    return RTN_SUCCESS1;
}

int32_t CCamDriver_MV::get_cam_property_range(int32_t camid, int32_t propertyid)
{
 //   QMutexLocker locker(&m_CardMutex);
    CCam_MV* pcam=(CCam_MV*)FindChannel(camid);
    Q_ASSERT(pcam);
    int iRangeMin=0,iRangeMax=100;
    switch(propertyid)
    {
    case Var_Cam_Exposure_ID   :
    {
        tSdkExpose      *  SdkExpose =   &pcam->m_MVCamCapbility.sExposeDesc;
        iRangeMin=SdkExpose->uiExposeTimeMin;
        iRangeMax=SdkExpose->uiExposeTimeMax;
    }
        break;
    case Var_Cam_Gain_ID       :
    {
        tSdkExpose      *  SdkExpose =   &pcam->m_MVCamCapbility.sExposeDesc;
        iRangeMin=SdkExpose->uiAnalogGainMin;
        iRangeMax=SdkExpose->uiAnalogGainMax;
        break;
    }
    case Var_Cam_Brightness_ID :
    {
        tSharpnessRange  *  SharpnessRange =   &pcam->m_MVCamCapbility.sSharpnessRange;
        iRangeMin=SharpnessRange->iMin;
        iRangeMax=SharpnessRange->iMax;
        break;
    }
    case Var_Cam_Contrast_ID   :
    {
        tContrastRange      *  sContrastRange   =   &pcam->m_MVCamCapbility.sContrastRange;
        iRangeMin=sContrastRange->iMin;
        iRangeMax=sContrastRange->iMax;
        break;
    }
    default: Q_ASSERT(0); break;
    }
    iRangeMax=min(iRangeMax,20000);
    QStringList& lrange=pcam->m_Variants.get_IndexList(propertyid);
    lrange.clear();
    lrange<<QString::number(iRangeMin)<<QString::number(iRangeMax);
    return RTN_SUCCESS1;
}

int32_t CCamDriver_MV::set_cam_property(int32_t camid, int32_t propertyid, int32_t data, bool_t bsetdefault)
{
    QMutexLocker locker(&m_CardMutex);
    CCam_MV* pcam=(CCam_MV*)FindChannel(camid);
    Q_ASSERT(pcam);
    QMutexLocker locker1(&pcam->m_CHMutex);
    MVCAMFUN(CameraPause(pcam->m_MVCamHandle));
    QStringList& lrange=pcam->m_Variants.get_IndexList(propertyid);

    int iRangeMin=lrange[0].toInt();
    int iRangeMax=lrange[1].toInt();
    if(data>iRangeMax)data=iRangeMax;
    if(data<iRangeMin)data=iRangeMin;
    switch(propertyid)
    {
    case Var_Cam_Exposure_ID   :
        MVCAMFUN(CameraSetExposureTime(pcam->m_MVCamHandle,double(data)));
        break;
    case Var_Cam_Gain_ID       :
        MVCAMFUN(CameraSetAnalogGain(pcam->m_MVCamHandle,data));
        break;
    case Var_Cam_Brightness_ID :
        MVCAMFUN(CameraSetSharpness(pcam->m_MVCamHandle,data));
        break;
    case Var_Cam_Contrast_ID   :
        MVCAMFUN(CameraSetContrast(pcam->m_MVCamHandle,data));
        break;
    default: Q_ASSERT(0); break;
    }
    MVCAMFUN(CameraPlay(pcam->m_MVCamHandle));
    return CCamDriver::set_cam_property(camid,propertyid,data,bsetdefault);
}

int32_t CCamDriver_MV::fresh_cam_property(int32_t camid, int32_t propertyid)
{
    QMutexLocker locker(&m_CardMutex);
    CCam_MV* pcam=(CCam_MV*)FindChannel(camid);
    Q_ASSERT(pcam);
    QMutexLocker locker1(&pcam->m_CHMutex);
    double data;
    switch(propertyid)
    {
    case Var_Cam_Exposure_ID   :
    {

        MVCAMFUN(CameraGetExposureTime(pcam->m_MVCamHandle,&data));
        break;
    }
    case Var_Cam_Gain_ID       :
    {
        int iData;
        MVCAMFUN(CameraGetAnalogGain(pcam->m_MVCamHandle,&iData));
        data=iData;
        break;
    }
    case Var_Cam_Brightness_ID :
    {
        int iData;
        MVCAMFUN(CameraGetSharpness(pcam->m_MVCamHandle,&iData));
        data=iData;
        break;
    }
    case Var_Cam_Contrast_ID   :
    {
        int iData;
        MVCAMFUN(CameraGetContrast(pcam->m_MVCamHandle,&iData));
        data=iData;
        break;
    }
    default: Q_ASSERT(0); break;
    }
    pcam->m_Variants.set_VData(propertyid,int(data));
    return 0;
}

int32_t CCamDriver_MV::autoadjust_property(int32_t camid)
{
    CCam_MV* pcam=(CCam_MV*)FindChannel(camid);
    Q_ASSERT(pcam);
//    QMutexLocker locker1(&pcam->m_CHMutex);
//    QMutexLocker locker(&m_CardMutex);
    MVCAMFUN(CameraSetAeState(pcam->m_MVCamHandle,true));
    int32_t time=m_Variants.get_VData(Var_CamDriver_AutoAdjust_Time_ID)->toInt();
    MSleep(time);

    MVCAMFUN(CameraSetAeState(pcam->m_MVCamHandle,false));

    fresh_cam_property(  camid, Var_Cam_Exposure_ID);
    fresh_cam_property(  camid, Var_Cam_Gain_ID);
    fresh_cam_property(  camid, Var_Cam_Brightness_ID);
    fresh_cam_property(  camid, Var_Cam_Contrast_ID);

    pcam->m_Variants.set_VData(Var_Cam_Exposure_default_ID, pcam->m_Variants.get_VData(Var_Cam_Exposure_ID)->toInt());
    pcam->m_Variants.set_VData(Var_Cam_Gain_default_ID, pcam->m_Variants.get_VData(Var_Cam_Gain_ID)->toInt());
    pcam->m_Variants.set_VData(Var_Cam_Brightness_default_ID, pcam->m_Variants.get_VData(Var_Cam_Brightness_ID)->toInt());
    pcam->m_Variants.set_VData(Var_Cam_Contrast_default_ID, pcam->m_Variants.get_VData(Var_Cam_Contrast_ID)->toInt());

    //m_gSystem.m_bNeedFreshUI=true;
    return 0;
}

int32_t CCamDriver_MV::light_off(int32_t camid)
{
    UNUSED(camid);
    return 0;
}

