/*\file FetchData.cpp:
 * \brief: general I/O interface to fetch data in python
 */

#ifdef HAVE_CONFIG_H
	#include <config.h>
#else
#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
#endif

#define PY_ARRAY_UNIQUE_SYMBOL PythonIOSymbol
#define NO_IMPORT

#include "../../toolkits/toolkits.h"
#include "../../include/include.h"
#include "../../shared/shared.h"
#include "../../io/io.h"

/*Primitive data types*/
/*FUNCTION FetchData(double* pscalar,PyObject* py_float){{{*/
void FetchData(double* pscalar,PyObject* py_float){

	double scalar;

	/*return internal value: */
	scalar=PyFloat_AsDouble(py_float);

	/*output: */
	*pscalar=scalar;
}
/*}}}*/
/*FUNCTION FetchData(int* pinteger,PyObject* py_long){{{*/
void FetchData(int* pinteger, PyObject* py_long){

	int integer;

	/*return internal value: */
	integer=(int)PyLong_AsLong(py_long);

	/*output: */
	*pinteger=integer;
}
/*}}}*/
/*FUNCTION FetchData(bool* pboolean,PyObject* py_boolean){{{*/
void FetchData(bool* pboolean,PyObject* py_boolean){

	bool boolean;
	
	/*check this is indeed a subtype of long type: */
	if(!PyBool_Check(py_boolean))_error2_("expecting a boolean in input!");

	/*extract boolean: */
	boolean=(bool)PyLong_AsLong(py_boolean);

	/*simple copy: */
	*pboolean=boolean;
	
}
/*}}}*/
/*FUNCTION FetchData(double** pmatrix,int* pM, int* pN, PyObject* py_matrix){{{*/
void FetchData(double** pmatrix,int* pM,int *pN,PyObject* py_matrix){

	/*output: */
	double* matrix=NULL;
	int M,N;
	int ndim;
	npy_intp*  dims=NULL;

	/*retrive dimensions: */
	ndim=PyArray_NDIM((const PyArrayObject*)py_matrix);
	if(ndim!=2)_error2_("expecting an MxN matrix in input!");
	dims=PyArray_DIMS((PyArrayObject*)py_matrix);
	M=dims[0]; N=dims[1];
	
	/*retrieve internal value: */
	matrix=(double*)PyArray_DATA((PyArrayObject*)py_matrix);

	/*output: */
	if(pM)*pM=M;
	if(pN)*pN=N;
	if(pmatrix)*pmatrix=matrix;
}
/*}}}*/
/*FUNCTION FetchData(int** pmatrix,int* pM, int* pN, PyObject* py_matrix){{{*/
void FetchData(int** pmatrix,int* pM,int *pN,PyObject* py_matrix){

	/*output: */
	double* dmatrix=NULL;
	int* matrix=NULL;
	int M,N;

	/*intermediary:*/
	int i;
	int ndim;
	npy_intp*  dims=NULL;

	/*retrive dimensions: */
	ndim=PyArray_NDIM((const PyArrayObject*)py_matrix);
	if(ndim!=2)_error2_("expecting an MxN matrix in input!");
	dims=PyArray_DIMS((PyArrayObject*)py_matrix);
	M=dims[0]; N=dims[1];
	
	/*retrieve internal value: */
	dmatrix=(double*)PyArray_DATA((PyArrayObject*)py_matrix);

	/*transform into integer matrix: */
	matrix=xNew<int>(M*N);
	for(i=0;i<M*N;i++)matrix[i]=(int)dmatrix[i];

	/*output: */
	if(pM)*pM=M;
	if(pN)*pN=N;
	if(pmatrix)*pmatrix=matrix;
}
/*}}}*/
/*FUNCTION FetchData(double** pvector,int* pM, PyObject* py_vector){{{*/
void FetchData(double** pvector,int* pM,PyObject* py_vector){

	/*output: */
	double* vector=NULL;
	int M;
	int ndim;
	npy_intp*  dims=NULL;

	/*retrive dimensions: */
	ndim=PyArray_NDIM((const PyArrayObject*)py_vector);
	if(ndim!=1)_error2_("expecting an Mx1 vector in input!");
	dims=PyArray_DIMS((PyArrayObject*)py_vector);
	M=dims[0]; 
	
	/*retrieve internal value: */
	vector=(double*)PyArray_DATA((PyArrayObject*)py_vector);

	/*output: */
	if(pM)*pM=M;
	if(pvector)*pvector=vector;
}
/*}}}*/
/*FUNCTION FetchData(Options** poptions,int istart, int nrhs,PyObject* arguments){{{*/
void FetchData(Options** poptions,int istart, int nrhs,PyObject* arguments){

	/*Initialize output*/
	Options* options=new Options();

	_pprintLine_("FetchData for Options not implemented yet, ignoring them!");

	/*Assign output pointers:*/
	*poptions=options;

}
/*}}}*/

/*Python version dependent: */
#if _PYTHON_MAJOR_ >= 3 
/*FUNCTION FetchData(char** pstring,PyObject* py_unicode){{{*/
void FetchData(char** pstring,PyObject* py_unicode){

	PyObject* py_bytes;
	char* string=NULL;

	
	/*convert to bytes format: */
	PyUnicode_FSConverter(py_unicode,&py_bytes);

	/*convert from bytes to string: */
	string=PyBytes_AS_STRING(py_bytes);
	
	*pstring=string;
}
/*}}}*/
#else
/*FUNCTION FetchData(char** pstring,PyObject* py_string){{{*/
void FetchData(char** pstring,PyObject* py_string){

	char* string=NULL;

	/*extract internal string: */
	string=PyString_AsString(py_string);
	
	*pstring=string;
}
/*}}}*/
#endif
