/****************************************************************************
 * OBIDMS_column_str functions                                              *
 ****************************************************************************/

/**
 * @file obidsmcolumn_str.c
 * @author Celine Mercier
 * @date October 28th 2015
 * @brief Functions handling OBIColumns containing data in the form of indices referring to character strings.
 */


#include <stdlib.h>
#include <stdio.h>

#include "obidmscolumn.h"
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
#include "obiarray.h"


#define DEBUG_LEVEL 0	// TODO has to be defined somewhere else (cython compil flag?)


/**********************************************************************
 *
 * D E F I N I T I O N   O F   T H E   P U B L I C   F U N C T I O N S
 *
 **********************************************************************/

int obi_column_set_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, char* value)
{
	byte_t* value_b;
	index_t idx;

	// Check that the line number is not greater than the maximum allowed
	if (line_nb >= MAXIMUM_LINE_COUNT)
	{
		obi_set_errno(OBICOL_UNKNOWN_ERROR);
		obidebug(1, "\nError trying to set a value at a line number greater than the maximum allowed");
    	return -1;
	}

	// Check if the file needs to be enlarged
	while ((line_nb+1) > (column->header)->line_count)
	{
		// Enlarge the file
		if (obi_enlarge_column(column) < 0)
	    	return -1;
	}

	// Update lines used
	if ((line_nb+1) > (column->header)->lines_used)
		(column->header)->lines_used = line_nb+1;

	// Encode the value on a byte array with a header
	value_b = obi_str_to_obibytes(value);
	if (value_b == NULL)
		return -1;

	// Add in the obiarray
	idx = obi_array_add(column->array, value_b);
	if (idx == -1)
		return -1;

	// Add the value's index in the column
	*(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx) = idx;

	free(value_b);

	return 0;
}


const char* obi_column_get_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
	index_t idx;
	byte_t* value_b;

	if ((line_nb+1) > (column->header)->lines_used)
	{
		obi_set_errno(OBICOL_UNKNOWN_ERROR);
		obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
		return "\0";		// TODO
	}

	idx = *(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);

	// Check NA
	if (idx == OBIIdx_NA)
		return "\0";		// TODO

	value_b = obi_array_get(column->array, idx);
	return obi_obibytes_to_str(value_b);
}


int obi_column_set_obistr_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name, char* value)
{
	index_t element_idx;
	element_idx = obi_column_get_element_index_from_name(column, element_name);
	if (element_idx == OBIIdx_NA)
		return -1;
	if (obi_column_set_obistr_with_elt_idx(column, line_nb, element_idx, value) < 0)
		return -1;
	return 0;
}


const char* obi_column_get_obistr_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
	index_t element_idx;

	element_idx = obi_column_get_element_index_from_name(column, element_name);
	if (element_idx == OBIIdx_NA)
		return "\0";
	return obi_column_get_obistr_with_elt_idx(column, line_nb, element_idx);
}