//
//  matfpConv.cpp
//  fp
//
//  Created by Robert Delaney on 2/1/17.
//
//

#include "matfp.hpp"
#include "matfpConv.hpp"
#include "fpConv.h"
#include "stringUtils.h"

extern INT32 decPrec;

static char* matNULL()
{
    char    *z;
    
    z = (char*)malloc(5*sizeof(char));
    strcpy(z, "NULL");
    return z;
    
}/* matNULL */

void init(matfp& z, INT32 nr, INT32 nc)
{
    INT32   i, j;
    z.nr = nr;
    z.nc = nc;
    z.array = (fp**)malloc(z.nr*sizeof(fp*));
    for(i=0;i<z.nr;i++)
        z.array[i] = (fp*)malloc(z.nc*sizeof(fp));
    
    for(i=0;i<z.nr;i++)
        for(j=0;j<z.nc;j++)
            init(z.array[i][j]);
    
}/* init */

// fills matrix with fp
// in xString row elements seperated by commas and rows seperated by semicolons
bool matfpConvFromStr(matfp& z, const char *xString)
{
    INT32		i, j, k;
    char		*rowString, *numString;
    char		*zString, ch;
    INT32		length, nr, nc;
    
    length = strlen(xString);
    
    if(!xString || !length)
    {
        z.nr = z.nc = 0;
        z.array = NULL;
        return false;
    }
    
    zString = (char*)malloc((length+1)*sizeof(char));
    zString[0] = 0;
    
    strcpy(zString, xString);
    
    // trim non-numerics from end of xtString
    i = length - 1;
    ch = zString[i];
    while((ch<'0' || ch>'9') && i>0)
    {
        ch = zString[--i];
    }
    zString[i+1] = 0;
    
    nr = CountFields(zString, ";");
    
    rowString = NthField(zString, ";", 1);
    
    nc = CountFields(rowString, ",");
    
    init(z, nr, nc);
    
    for(i=0;i<nr;i++)
    {
        for(j=0;j<nc;j++)
        {
            numString = NthField(rowString, ",", j+1);
            if(!fpConvFromString(z.array[i][j], numString))
            {
                for(k=0;k<nr;k++)
                    free(z.array[k]);
                free(z.array);
                z.nr = z.nc = 0;
                z.array = NULL;
                return false;
            }
            free(numString);
        }
        
        free(rowString);
        if(i<(nr-1))
            rowString = NthField(zString, ";", i+2);
    }
    
    free(zString);
    
    return true;
    
}/* matfpConvFromStr */


void matfpConvToStr(char*& matfpStr, const matfp& x)
{
    INT32		i, j;
    char		*numStr;
    INT32		allNumLen;
    
    if(!x)
    {
        matfpStr = matNULL();
        return;
    }
    
    allNumLen = 0;
    
    for(i=0;i<x.nr;i++)
        for(j=0;j<x.nc;j++)
        {
            numStr = fpToStr(x.array[i][j], decPrec);
            allNumLen = allNumLen + strlen(numStr);
            free(numStr);
        }
    // account for commas and semicolons
    allNumLen = allNumLen + x.nr*x.nc + x.nr + 20;
    matfpStr = (char*)malloc(allNumLen*sizeof(char));
    matfpStr[0] = 0;
    
    for(i=0;i<x.nr;i++)
    {
        for(j=0;j<x.nc;j++)
        {
            numStr = fpToStr(x.array[i][j], decPrec);
            strcat(matfpStr, numStr);
            if(j<(x.nc-1))
                strcat(matfpStr, ",");
            free(numStr);
        }
        if(i<(x.nr-1))
            strcat(matfpStr, ";");
    }
    
}/* matfpConvToStr */

