/*************************************************************************
*									 *
*	 YapR Module for Yap Prolog 					 *
*									 *
*	YapR Prolog was developed at FEUP - Universidade do Porto	 *
*									 *
* Copyright Joao Azevedo and Universidade do Porto 2010-2011  		 *
*									 *
**************************************************************************
*									 *
* File:		interface.c						 *
* Last rev:								 *
* mods:									 *
* comments:	C code to interface R-project software with Yap		 *
*									 *
*************************************************************************/
#include <YapR.h>
#include <string.h>


// predicate: given a string, obtain a float
static int float_val(void)
{
    YAP_Term in = YAP_ARG1;
    YAP_Term out = YAP_ARG2;
    char buffer[BUFSIZE];

    YAP_StringToBuffer(in, buffer, BUFSIZE);
    YAP_Term res = YAP_MkFloatTerm(get_double(buffer));

    return YAP_Unify(out, res);
}

// predicate: given a string, obtain a int
static int int_val(void)
{
    YAP_Term in = YAP_ARG1;
    YAP_Term out = YAP_ARG2;
    char buffer[BUFSIZE];
    char *nbuf = buffer;
    YAP_Int sz = BUFSIZE;

    while (!YAP_StringToBuffer(in, nbuf, sz)) {
      sz = YAP_ListLength(in)+1;
      nbuf = malloc(sizeof(char)*(sz+1));
      if (!nbuf)
	return FALSE;
    }
    YAP_Term res = YAP_MkIntTerm(get_int(nbuf));
    if (nbuf != buffer)
      free(nbuf);
    return YAP_Unify(out, res);
}

static int list_val(void)
{
    YAP_Term in = YAP_ARG1;
    YAP_Term out = YAP_ARG2;
    char buffer[BUFSIZE];
    char *nbuf = buffer;
    YAP_Int sz = BUFSIZE;

    while (!YAP_StringToBuffer(in, nbuf, sz+1)) {
      sz = YAP_ListLength(in)+1;
      nbuf = malloc(sizeof(char)*(sz+1));
      if (!nbuf)
	return FALSE;
    }
    YAP_Term res = get_list(nbuf);
    if (nbuf != buffer)
      free(nbuf);
    return YAP_Unify(out, res);
}

// transform 
static int send_r_command(void)
{
    YAP_Term in = YAP_ARG1;
    char *buf = NULL;
    YAP_Int len = YAP_ListLength(in);
    if (!len) return FALSE;
    buf = malloc(len+1);
    if (!buf)
      return 0;
    if (!YAP_StringToBuffer(in, buf, len+1)) {
      return 0;
    }
    send_command(buf);
    free(buf);
    return 1;
}

static int init_r(void)
{
    init_R();

    return 1;
}

void init_my_predicates(void)
{
    YAP_UserCPredicate("float_val", float_val, 2);
    YAP_UserCPredicate("int_val", int_val, 2);
    YAP_UserCPredicate("list_val", list_val, 2);
    YAP_UserCPredicate("init_r", init_r, 0);
    YAP_UserCPredicate("send_r_command", send_r_command, 1);
}
