#include "rSeparationUtils.h"
#include "rwrapper.h"



//************************************
//************************************
//************************************

FRNormConorm::FRNormConorm(SEXP r_function) : NormConorm() {
    __r_function = r_function;
}

//************************************
//************************************
//************************************

double FRNormConorm::operator()(double a, double b) {
    ++__calls;
    
    int conta_proteggi = 0;
    
    SEXP a_r = Proteggi(Rf_allocVector(REALSXP, 1), conta_proteggi);
    REAL(a_r)[0] = a;
    SEXP b_r = Proteggi(Rf_allocVector(REALSXP, 1), conta_proteggi);
    REAL(b_r)[0] = b;
    
    auto R_fcall = Rf_lang3(__r_function, R_NilValue, R_NilValue);
    SETCADR(R_fcall, a_r);
    SETCADDR(R_fcall, b_r);
    auto fcall_ans = Proteggi(Rf_allocVector(VECSXP, 1), conta_proteggi);
    SET_VECTOR_ELT(fcall_ans, 0, Rf_eval(R_fcall, R_GlobalEnv));
    auto ans = VECTOR_ELT(fcall_ans, 0);
    if (!Rf_isVector(ans) || Rf_length(ans) != 1) {
        std::string err_str = "Not a vector";
        throw_line(err_str);
    }

    double risultato = REAL(ans)[0];

    if (conta_proteggi > 0) UNPROTECT(conta_proteggi);
    return risultato;
}
