
#/*##########################################################################
# Copyright (C) 2001-2013 European Synchrotron Radiation Facility
#
#              PyHST2  
#  European Synchrotron Radiation Facility, Grenoble,France
#
# PyHST2 is  developed at
# the ESRF by the Scientific Software  staff.
# Principal author for PyHST2: Alessandro Mirone.
#
# This program is free software; you can redistribute it and/or modify it 
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option) 
# any later version.
#
# PyHST2 is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# PyHST2; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
# Suite 330, Boston, MA 02111-1307, USA.
#
# PyHST2 follows the dual licensing model of Trolltech's Qt and Riverbank's PyQt
# and cannot be used as a free plugin for a non-free program. 
#
# Please contact the ESRF industrial unit (industry@esrf.fr) if this license 
# is a problem for you.
#############################################################################*/
#undef NDEBUG
#include"Python.h"
#include <stdlib.h>

#include "py3c.h"

#define PY_ARRAY_UNIQUE_SYMBOL chst_ARRAY_API
#define NO_IMPORT_ARRAY
 
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

#include "numpy/arrayobject.h"
#include"structmember.h"
#include"cpyutils.h"


PyObject * cpyutils_get_pydic_Oval(PyObject *Odict, const char *key ) { 

  PyObject *dic_key, *Oval;
  if( !PyDict_Check(Odict)) {
    fprintf(stderr, "not a  dictionary  in  get_pydic_Oval \n");
    exit(1);   
  }
  
  dic_key   =  PyStr_FromString(key);
  Oval      =  PyDict_GetItem(Odict, dic_key);
  if( Oval ) {
    Py_DECREF(dic_key);
    return Oval;
  } else {
    fprintf(stderr, "Key: %s   was not found in dictionary in %s line %d   \n", key, __FILE__, __LINE__);
    exit(1);
  }
}
  
int cpyutils_o2i_TB(PyObject *obj , const char * callFILE, int callLINE ) {
  int res;
  if(!PyInt_Check(obj)) {
    fprintf(stderr, "failed conversion to int in %s line %d  called from %s line %d \n",  __FILE__, __LINE__, callFILE,  callLINE );
    exit(1);
  }
  res= PyInt_AsLong(obj);
  return res;
}

int cpyutils_o2i(PyObject *obj ) {
  int res;
  if(!PyInt_Check(obj)) {
    fprintf(stderr, "failed conversion to int in %s line %d \n",  __FILE__, __LINE__);
    exit(1);
  }
  res= PyInt_AsLong(obj);
  return res;
}

  
float  cpyutils_o2f_TB(PyObject *obj, const char * callFILE, int callLINE  ) {
  float res;
  if(!PyFloat_Check(obj) && !PyInt_Check(obj) ) {
    fprintf(stderr, "failed conversion to float in %s line %d   called from %s line %d  \n",  __FILE__, __LINE__, callFILE,  callLINE);
    exit(1);
  }
  res= PyFloat_AsDouble (obj);
  return res;
}



PyObject *cpyutils_getattribute(PyObject * obj ,const char * string ) {
  PyObject *res;
  res = PyObject_GetAttrString(obj, string); 
  if(!res) {
    fprintf(stderr, "attribute %s not found in object in %s line %d \n",string, __FILE__, __LINE__);
    exit(1);
  }
  Py_DECREF(res);
  return res;
}


char** cpyutils_getstringlist_from_list(PyObject *Otmp,int *listlenght) {
  int i;
  const char * strptr ;
  char ** stringlist;
  assert(PyList_Check(Otmp));
  *listlenght = PyList_Size(Otmp); 

  if ( *listlenght) {
    stringlist  = ( char **) malloc( (*listlenght)*sizeof(char *));
  } else {
    stringlist = NULL ; 
  }
  
  for(i=0; i<(*listlenght); i++) {
    assert(PyStr_Check(PyList_GetItem(Otmp,i) ));
    strptr = PyStr_AsString(PyList_GetItem(Otmp,i));
    stringlist[i] = (char *) malloc( sizeof(char)*strlen(strptr )+1 );
    memcpy( stringlist[i], strptr , strlen(strptr )+1);
  }
  return stringlist;
}


char* cpyutils_getstring(PyObject *Otmp) {
  char * string;
  const char  *strptr;

  assert(PyStr_Check(Otmp ));
  strptr = PyStr_AsString(Otmp);
  string= (char *) malloc( sizeof(char)*strlen(strptr )+1 );
  memcpy( string, strptr , strlen(strptr )+1);
  
  return string;
}

#define ASSERT(A) if(!(A) ) { printf(" in subroutine called from file:%s line:%d\n", callFILE, callLINE); assert((A));    }  

void  *cpyutils_PyArray1D_as_array_TB(PyObject *OtmpA, int *listlenght,int  pyarraytype, const char * callFILE, int callLINE  ) {
  PyObject *Otmp;
  void  *res ; 
  ASSERT(PyArray_Check(OtmpA ));
  // ASSERT(  ((PyArrayObject *)OtmpA)  ->descr->type_num ==  pyarraytype   );
  ASSERT(  PyArray_DESCR(((PyArrayObject *)OtmpA) ) ->type_num ==  pyarraytype   );


  
  ASSERT(      PyArray_NDIM ((PyArrayObject*) OtmpA)    ==1 ); 
 
  // tmp = PyArray_ContiguousFromObject(OtmpA, PyArray_NOTYPE, 1, 1);
  Otmp = PyArray_ContiguousFromAny(OtmpA,  pyarraytype   , 1, 1);


  *listlenght = PyArray_DIMS(((PyArrayObject *)  Otmp) )[0];

  res = (void *) malloc( (*listlenght) *PyArray_ITEMSIZE((PyArrayObject *) Otmp)   )  ; 

  memcpy(  res, PyArray_DATA((PyArrayObject*) Otmp) ,   (*listlenght)*PyArray_ITEMSIZE((PyArrayObject *) Otmp) );

  Py_DECREF(Otmp);
  return  res; 
}
void  *cpyutils_PyArray2D_as_array(PyObject *OtmpA, int *dim2, int *dim1,int  pyarraytype ) {
  PyObject *Otmp;
  void *res ; 
  assert(PyArray_Check(OtmpA ));
  assert(  PyArray_DESCR((PyArrayObject *)OtmpA)->type_num == pyarraytype ); 
  assert( PyArray_NDIM((PyArrayObject*) OtmpA)   ==2 ); 
  Otmp = PyArray_ContiguousFromObject(OtmpA, pyarraytype , 2, 2);

  *dim2 = PyArray_DIMS((PyArrayObject *)  Otmp)[0];
  *dim1 = PyArray_DIMS((PyArrayObject *)  Otmp)[1];

/* #define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m)) */
/* #define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m)) */

  res = (void  *) malloc( (*dim2)*(*dim1) *PyArray_ITEMSIZE((PyArrayObject *) Otmp)  )  ; 

  memcpy(  res , PyArray_DATA((PyArrayObject*) Otmp),   (*dim2)*(*dim1)*PyArray_ITEMSIZE((PyArrayObject *) Otmp)    );

  Py_DECREF(Otmp);
  return  res; 
}

void  *cpyutils_PyArray3D_as_array(PyObject *OtmpA,int *dim3, int *dim2, int *dim1,int  pyarraytype ) {
  PyObject *Otmp;
  void *res ; 
  assert(PyArray_Check(OtmpA ));
  assert(  PyArray_DESCR((PyArrayObject *)OtmpA)->type_num == pyarraytype ); 
  assert( PyArray_NDIM((PyArrayObject*) OtmpA)   ==3 ); 
  Otmp = PyArray_ContiguousFromObject(OtmpA, pyarraytype , 3, 3);

  *dim3 = PyArray_DIMS((PyArrayObject *)  Otmp)[0];
  *dim2 = PyArray_DIMS((PyArrayObject *)  Otmp)[1];
  *dim1 = PyArray_DIMS((PyArrayObject *)  Otmp)[2];

  res = (void  *) malloc( (*dim2)*(*dim2)*(*dim1) *PyArray_ITEMSIZE((PyArrayObject *) Otmp)  )  ; 
  
  memcpy(  res , PyArray_DATA((PyArrayObject*) Otmp),   (*dim2)*(*dim1)*PyArray_ITEMSIZE((PyArrayObject *) Otmp)    );

  Py_DECREF(Otmp);
  return  res; 
}

void *cpyutils_PyArray5D_as_array(PyObject *OtmpA,int *dim5,
				  int *dim4, int *dim3,
				  int *dim2, int *dim1,int  pyarraytype ){
  PyObject *Otmp;
  void *res ; 
  assert(PyArray_Check(OtmpA ));
  assert(  PyArray_DESCR((PyArrayObject *)OtmpA) ->type_num == pyarraytype ); 
  assert( PyArray_NDIM((PyArrayObject*) OtmpA)  ==5 ); 
  Otmp = PyArray_ContiguousFromObject(OtmpA, pyarraytype, 5, 5);

  *dim5 = PyArray_DIMS((PyArrayObject *)  Otmp)[0];
  *dim4 = PyArray_DIMS((PyArrayObject *)  Otmp)[1];
  *dim3 = PyArray_DIMS((PyArrayObject *)  Otmp)[2];
  *dim2 = PyArray_DIMS((PyArrayObject *)  Otmp)[3];
  *dim1 = PyArray_DIMS((PyArrayObject *)  Otmp)[4];

/* #define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m)) */
/* #define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m)) */

  res = (void  *) malloc( (*dim5)*(*dim4)*(*dim3) *(*dim2)*(*dim1) *PyArray_ITEMSIZE((PyArrayObject *) Otmp)  )  ; 

  memcpy(  res , PyArray_DATA((PyArrayObject*) Otmp),   (*dim5)*(*dim4)*(*dim3) *(*dim2)*(*dim1) * PyArray_ITEMSIZE((PyArrayObject *) Otmp)    );

  Py_DECREF(Otmp);
  return  res; 
}


  
