#include "Common.h"
#include "LicensePlateRecognition.h"



LicensePlateRecognition::LicensePlateRecognition() {}

LicensePlateRecognition::~LicensePlateRecognition(){
}

LicensePlateRecognition* LicensePlateRecognition::instance = nullptr;



//void  LicensePlateRecognition::initHlprContext(const QString &modelPaths, const QString &carCascade, float carConfidence){
//    HLPR_ContextConfiguration configuration = {0};
//    QByteArray && by_mpath=modelPaths.toUtf8();
//    char* m_path=by_mpath.data();
//    configuration.models_path = m_path;
//    configuration.max_num = 5;
//    configuration.det_level = DETECT_LEVEL_LOW;
//    configuration.use_half = false;
//    configuration.nms_threshold = 0.5f;
//    configuration.rec_confidence_threshold = carConfidence;
//    configuration.box_conf_threshold = 0.30f;
//    configuration.threads = 1;
//    this->carCascadeUrl=carCascade;
//    ctx = HLPR_CreateContext(&configuration);
//}
void LicensePlateRecognition::oldLicensePlateNumber(const cv::Mat &source,const QString &modelPaths,QString & lpNumber){
    HLPR_ImageData data = {0};
    data.data = source.data;
    data.width = source.cols;
    data.height = source.rows;
    data.format = STREAM_BGR;
    data.rotation = CAMERA_ROTATION_0;
    // create DataBuffer
    P_HLPR_DataBuffer buffer = HLPR_CreateDataBuffer(&data);
    
    // 检测图片数据流是否正确，如果出现崩溃或图像不符合预期 则表示数据流格式异常导致内部编码出错
    HLPR_DataBufferTest(buffer, "test_buffer.jpg");
    
    // create context
    HLPR_ContextConfiguration configuration = {0};
    QByteArray && by_mpath=modelPaths.toUtf8();
    char* m_path=by_mpath.data();
    configuration.models_path = m_path;
    configuration.max_num = 5;
    configuration.det_level = DETECT_LEVEL_LOW;
    configuration.use_half = false;
    configuration.nms_threshold = 0.5f;
    configuration.rec_confidence_threshold = 0.8f;
    configuration.box_conf_threshold = 0.30f;
    configuration.threads = 1;
    P_HLPR_Context ctx1 = HLPR_CreateContext(&configuration);
    HREESULT ret = HLPR_ContextQueryStatus(ctx1);
    if (ret != HResultCode::Ok) {
        printf("create error.\n");
        return ;
    }
    // exec plate recognition
    HLPR_PlateResultList results = {0};
    HLPR_ContextUpdateStream(ctx1, buffer, &results);
    
    
    
    QStringList lpResults;
    for (int i = 0; i < results.plate_size; ++i) {
        std::string type;
        if (results.plates[i].type == HLPR_PlateType::PLATE_TYPE_UNKNOWN) {
            type = "未知";
        } else {
            type = types[results.plates[i].type];
        }
        qDebug()<<QString("车牌号:%1").arg(results.plates[i].code);
        QString plateResult = QString("第%1个,%2,车牌号:%3,置信度:%4,左上角点x坐标:%5,左上角点y坐标:%6,右下角点x坐标:%7,右下角点y坐标:%8")
                .arg(i + 1).arg(type.c_str()).arg(results.plates[i].code)
                .arg(results.plates[i].text_confidence).arg(results.plates[i].x1, 0, 'Q', 4)
                .arg(results.plates[i].y1, 0, 'Q', 4).arg(results.plates[i].x2, 0, 'Q', 4)
                .arg(results.plates[i].y2, 0, 'Q', 4);
        
        lpResults.append(plateResult);
    }
    
    lpNumber =lpResults.join("\n");
    // release buffer
    HLPR_ReleaseDataBuffer(buffer);
    // release context
    HLPR_ReleaseContext(ctx1);
}


void LicensePlateRecognition::licensePlateNumber(const cv::Mat &source, QString &lpNumber,vides_data::requestLicensePlate &plate,
                                                 qint64 currentTime,P_HLPR_Context ctx) {


    // 执行一帧图像数据检测行人
    // create ImageData
    HLPR_ImageData data = {0};
    data.data = source.data;
    data.width = source.cols;
    data.height = source.rows;
    data.format = STREAM_BGR;
    data.rotation = CAMERA_ROTATION_0;
    // create DataBuffer
    P_HLPR_DataBuffer buffer = HLPR_CreateDataBuffer(&data);

    HREESULT ret = HLPR_ContextQueryStatus(ctx);
    if (ret != HResultCode::Ok) {
        qInfo()<<QString("create error");
        return ;
    }
    // exec plate recognition
    HLPR_PlateResultList results = {0};
    HLPR_ContextUpdateStream(ctx, buffer, &results);
    
    if (results.plate_size <= 0) {
        HLPR_ReleaseDataBuffer(buffer);
        return;
    }
    
    QStringList lpResults;
    for (int i = 0; i < results.plate_size; ++i) {
        std::string type;
        if (results.plates[i].type == HLPR_PlateType::PLATE_TYPE_UNKNOWN) {
            type = "未知";
        } else {
            type = types[results.plates[i].type];
        }
        vides_data::LicensePlate newPlate;
        newPlate.time=currentTime;
        newPlate.new_color=QString::fromStdString(type);
        newPlate.new_plate=QString::fromUtf8(results.plates[i].code);
        newPlate.text_confidence=results.plates[i].text_confidence;
        vides_data::ParkingArea area;
        area.topLeftCornerX=results.plates[i].x1;
        area.topLeftCornerY=results.plates[i].y1;
        area.bottomLeftCornerX=results.plates[i].x1;
        area.bottomLeftCornerY=results.plates[i].y2;
        area.topRightCornerX=results.plates[i].x2;  // 修改这里
        area.topRightCornerY=results.plates[i].y1;  // 修改这里
        area.bottomRightCornerX=results.plates[i].x2;
        area.bottomRightCornerY=results.plates[i].y2;
        newPlate.recognition=area;
        QString plateResult = QString("第%1个,%2,车牌号:%3,置信度:%4,左上角点x坐标:%5,左上角点y坐标:%6,右下角点x坐标:%7,右下角点y坐标:%8")
                .arg(i + 1).arg(type.c_str()).arg(results.plates[i].code)
                .arg(results.plates[i].text_confidence).arg(results.plates[i].x1, 0, 'Q', 4)
                .arg(results.plates[i].y1, 0, 'Q', 4).arg(results.plates[i].x2, 0, 'Q', 4)
                .arg(results.plates[i].y2, 0, 'Q', 4);
        //QString plateResult = QString(results.plates[i].code);
        plate.plates.push_front(newPlate);
        lpResults.append(plateResult);
    }
    lpNumber =lpResults.join("\t");
    
    HLPR_ReleaseDataBuffer(buffer);
    
}


