#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core.hpp"
#include "opencv2/calib3d.hpp"
#include "libqr.h"

using namespace cv;
using namespace std;

static
std::string make_resp(bool ok, string err, int angle = -1, string qrcode = "", double elapsed = 0)
{
    char buf[512];
    snprintf(buf, sizeof(buf), R"({ "ok": %s, "err": "%s", "qrcode": "%s", "angle": %d, "elapsed": %lf })",
             ok ? "true" : "false",
             err.c_str(),
             qrcode.c_str(),
             angle,
             elapsed
            );
    return string(buf);
}


extern "C" {
const char *qrtool_angle(uint8_t *data, int width, int height, uint8_t *dot_area, float camera_sensitivity) {
    ProcessState ps;
    ps.laplacian_thres = camera_sensitivity / 10.0;

    auto start = std::chrono::system_clock::now();
    static char ret[512];
    printf("qrtool_angle, width: %d height %d\n", width, height);
    for (int i = 0; i < 16; i++) {
        printf("%d ", data[i]);
    }
    printf("\n");
    Mat orig(Size(width, height), CV_8UC4, data);
    printf("mat: %d %d\n", orig.cols, orig.rows);
    string qrcode, err;
    float angle;
    auto ok = emblem_dot_angle(ps, orig, angle, qrcode, err);
    auto end = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed = end-start;
    auto x = make_resp(ok, err, angle, qrcode, elapsed.count());
    if (dot_area) {
        if (!ps.dot_area.empty()) {
            Mat da;
            ps.dot_area.convertTo(da, CV_8UC4);
            resize(da, da, Size(32 ,32));
            memset(dot_area, 255, 32 * 32 * 4);
            memcpy(dot_area, da.ptr(), 32 * 32 * 4);
        } else {
            memset(dot_area, 55, 32 * 32 * 4);
        }
    }
    snprintf(ret, 512, "%s", x.c_str());
    return ret;
}
}
