//
//  mat_utils.cpp
//  TestApp
//
//  Created by Jakub Tomczyński on 01.09.2017.
//
//

#include "mat_utils.h"

#include <QDebug>
#include <cmath>
#define _USEM_MATH_DEFINES
QVector<QVector<double> > Mat_to_QVector2D(const cv::Mat &input) {
    QVector<QVector<double> > retval;
    QVector<double> temp(input.cols);
    for (int r = 0; r < input.rows; r++) {
        switch (input.type()) {
            case CV_64F:
                for (int c = 0; c < input.cols; c++) {
                    temp[c] = input.at<double>(r, c);
                }
                break;
            default:
                qDebug() << "UNSUPPORTED MAT TYPE";
        }
        retval.push_back(temp);
    }
    return retval;
}

cv::Mat QVector2D_to_Mat(const QVector<QVector<double> > &input, int type) {
    if (input.size() == 0) {
        return cv::Mat(0, 0, type);
    }
    
    cv::Mat retval(input.size(), input[0].size(), type);
    for (int r = 0; r < retval.rows; r++) {
        switch (retval.type()) {
            case CV_64F:
                for (int c = 0; c < retval.cols; c++) {
                    retval.at<double>(r, c) = input[r][c];
                }
                break;
            default:
                qDebug() << "UNSUPPORTED MAT TYPE";
        }
    }
    return retval;
}

QImage Mat_to_QImage(const cv::Mat &input) {
    QImage img;
    switch (input.type()) {
        case CV_8UC3:
        case CV_8SC3:
            img = QImage(input.cols, input.rows, QImage::Format_RGB888);
            if (input.cols % 4 ==0) {
                memcpy(img.bits(),input.data,input.cols*input.rows*3);
            } else {
                for (int r = 0; r < input.rows; r++) {
                    memcpy(img.scanLine(r),input.data+(input.step[0]*r),input.cols*3);
                }
            }
            img = img.rgbSwapped();
            break;
        case CV_8UC1:
        case CV_8SC1:
            img = QImage(input.cols, input.rows, QImage::Format_Grayscale8);
            memcpy(img.bits(),input.data,input.cols*input.rows);
            break;
        default:
            qDebug() << "Mat_to_QImage(): unsupported input format";
            break;
    }
    return img;
}

bool is_inside_rectangle(cv::RotatedRect rectangle, cv::Point2d point) {
    double alpha = rectangle.angle / 180.0 * M_PI;
    double pxp = cos(-alpha) * (point.x - rectangle.center.x) - sin(-alpha) * (point.y - rectangle.center.y);
    double pyp = sin(-alpha) * (point.x - rectangle.center.x) + cos(-alpha) * (point.y - rectangle.center.y);

    if (pxp >= -rectangle.size.width/2 && pxp <= rectangle.size.width/2 &&
        pyp >= -rectangle.size.height/2 && pyp <= rectangle.size.height/2) {
        return true;
    }
    return false;
}

QStringList split_with_escape(QString input, char separator, char escape_char) {
    QStringList retval;
    QString temp;
    bool escape = false;
    for (int i = 0; i < input.size(); i++) {
        if (escape) {
            if (input[i] == separator || input == escape_char) {
                temp += input[i];
            } else {
                qWarning() << "split_with_escape(): unknown escape sequence" << escape_char << input[i];
            }
            escape = false;
        } else {
            if (input[i] == separator) {
                temp = temp.trimmed();
                retval.push_back(temp);
                temp.clear();
            } else if (input[i] == escape_char) {
                escape = true;
            } else {
                temp += input[i];
            }
        }
    }
    if (!temp.isEmpty()) {
        temp = temp.trimmed();
        retval.push_back(temp);
    }
    return retval;
}
