/*   Manipulation et conversion des types de bases     */
/*          E. Aubourg, E. Lesquoy                     */

// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#ifndef DATATYPES_H_SEEN
#define DATATYPES_H_SEEN

#include "machdefs.h"


enum PBaseDataTypes {kpbdt_unknown=-1, kuint_1=1, kint_1=2, 
                     kuint_2=3, kint_2=4, kuint_4=5, kint_4=6, 
                     kr_4=7, kr_8=8};

inline PBaseDataTypes DataType(uint_1) {return kuint_1;}
inline PBaseDataTypes DataType(int_1)  {return kint_1;}
inline PBaseDataTypes DataType(uint_2) {return kuint_2;}
inline PBaseDataTypes DataType(int_2)  {return kint_2;}
inline PBaseDataTypes DataType(uint_4) {return kuint_4;}
inline PBaseDataTypes DataType(int_4)  {return kint_4;}
inline PBaseDataTypes DataType(r_4)    {return kr_4;}
inline PBaseDataTypes DataType(r_8)    {return kr_8;}

const char * DataName(PBaseDataTypes);
const char * DataLongName(PBaseDataTypes);
int    DataSize(PBaseDataTypes);

// Limites des types

inline double   MinRange(uint_1) {return  0.0;}
inline double   MaxRange(uint_1) {return  255.0;}
inline double   MinRange(uint_2) {return  0.0;}
inline double   MaxRange(uint_2) {return  65535.0;}
inline double   MinRange(int_2)  {return -32768.0;}
inline double   MaxRange(int_2)  {return  32767.0;}
inline double   MinRange(int_4)  {return -2147483648.0;}
inline double   MaxRange(int_4)  {return  2147483647.0;}
inline double   MinRange(r_4)    {return -3.40282347e+38f;}
inline double   MaxRange(r_4)    {return  3.40282347e+38f;}

// reduction range donnee si on va du type 1 au type 2 (y/n)
// ReducRange(type 1 , type 2 )
// retour:

enum {t_same,t_up,t_spe,t_down}; 
//         t_same: meme type
//         t_up  : ascendant   (I,U2)->(I4,R4), I4->R4 
//         t_spe:  speciaux    I2->U2 , U2->I2 
//         t_down: descendants R4->I4, (R4,I4)->(U2,I2) 

inline int ConvType(uint_1 , uint_1 ) {return  t_same;}
inline int ConvType(uint_1 , uint_2 ) {return  t_up;}
inline int ConvType(uint_1 , int_2 )  {return  t_up;}
inline int ConvType(uint_1 , int_4 )  {return  t_up;}
inline int ConvType(uint_1 , r_4 )    {return  t_up;}
inline int ConvType(uint_2 , uint_1 ) {return  t_down;}
inline int ConvType(uint_2 , uint_2 ) {return  t_same;}
inline int ConvType(uint_2 , int_2 )  {return  t_spe;}
inline int ConvType(uint_2 , int_4 )  {return  t_up;}
inline int ConvType(uint_2 , r_4 )    {return  t_up;}
inline int ConvType(int_2 , uint_1 )  {return  t_down;}
inline int ConvType(int_2 , uint_2 )  {return  t_spe;}
inline int ConvType(int_2 , int_2 )   {return  t_same;}
inline int ConvType(int_2 , int_4 )   {return  t_up;}
inline int ConvType(int_2 , r_4 )     {return  t_up;}
inline int ConvType(int_4 , uint_1 )  {return  t_down;}
inline int ConvType(int_4 , uint_2 )  {return  t_down;}
inline int ConvType(int_4 , int_2 )   {return  t_down;}
inline int ConvType(int_4 , int_4 )   {return  t_same;}
inline int ConvType(int_4 , r_4 )     {return  t_up;}
inline int ConvType(r_4 , uint_1 )    {return  t_down;}
inline int ConvType(r_4 , uint_2 )    {return  t_down;}
inline int ConvType(r_4 , int_2 )     {return  t_down;}
inline int ConvType(r_4 , int_4 )     {return  t_down;}
inline int ConvType(r_4 , r_4 )       {return  t_same;}

/*
template <class T> 
inline T PutInRange(double x,T t) {
           return (T)( x < MinRange(t) ? MinRange(t) : \
		      (x > MaxRange(t) ? MaxRange(t) : x));
	 }
// BUG GCC 2.6.1. Unresolved: xxx..ng
*/

inline uint_1 PutInRange(double x, uint_1 t) {
  return (uint_1)( x < MinRange(t) ? MinRange(t) : \
	     (x > MaxRange(t) ? MaxRange(t) : x));
	 }
inline uint_2 PutInRange(double x, uint_2 t) {
  return (uint_2)( x < MinRange(t) ? MinRange(t) : \
	     (x > MaxRange(t) ? MaxRange(t) : x));
	 }
inline int_2 PutInRange(double x, int_2 t) {
  return (int_2)( x < MinRange(t) ? MinRange(t) : \
	     (x > MaxRange(t) ? MaxRange(t) : x));
	 }
inline int_4 PutInRange(double x, int_4 t) {
  return (int_4)( x < MinRange(t) ? MinRange(t) : \
	     (x > MaxRange(t) ? MaxRange(t) : x));
	 }
inline r_4 PutInRange(double x  , r_4)  {return x;} 

/*
template <class T> 
inline T SharePix(double x, T t, double cutmin, double cutmax)
         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
          ( MaxRange(t)-MinRange(t)))+MinRange(t);
	   return PutInRange(tmp, t);
	 }
// BUG GCC 2.6.1. Unresolved: xxx..ng
*/
inline double SharePix(double x, uint_1 t, double cutmin, double cutmax)
         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
          ( MaxRange(t)-MinRange(t)))+MinRange(t);
	   return PutInRange(tmp, t);
	 }
inline double SharePix(double x, uint_2 t, double cutmin, double cutmax)
         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
          ( MaxRange(t)-MinRange(t)))+MinRange(t);
	   return PutInRange(tmp, t);
	 }
inline double SharePix(double x, int_2 t, double cutmin, double cutmax)
         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
          ( MaxRange(t)-MinRange(t)))+MinRange(t);
	   return PutInRange(tmp, t);
	 }
inline double SharePix(double x, int_4 t, double cutmin, double cutmax)
         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
          ( MaxRange(t)-MinRange(t)))+MinRange(t);
	   return PutInRange(tmp, t);
	 }
inline double SharePix(double x, r_4 t, double cutmin, double cutmax)
         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
          ( MaxRange(t)-MinRange(t)))+ MinRange(t);
	   return PutInRange(tmp, t);
	 }

#endif
