// This is a "copy" of the file ~magics/c/proj_braz.h .
// The reason for this duplicity is to avoid to call
// Magics routines within libUtil.
// For the new Magics version, both files should be 
// replaced by a single C++ version.

#ifndef proj_braz_DEFINED
#define proj_braz_DEFINED

#ifdef REAL_IS_DOUBLE
typedef double Real;
#else
typedef float Real;
#endif

typedef struct CPoint
{
	Real	X,Y;		/*  point location */
} CPoint;


typedef struct
{
        CPoint Bll, Bur;

} BBox;

#ifdef FORTRAN_NO_UNDERSCORE
#define pimii1_ pimii1
#define pimii2_ pimii2
#define pimin1_ pimin1
#define pimind_ pimind
#define pimp1_ pimp1
#define pimp2_ pimp2
#define pimg1_ pimg1
#define pimg2_ pimg2
#define pims1_ pims1
#define pims2_ pims2
#define pl2p1_ pl2p1
#define pl2p2_ pl2p2
#define pp2l1_ pp2l1
#define pp2l2_ pp2l2
#define pmvimg_ pmvimg
#define premap_ premap
#define pdeal_ pdeal
#define penqi_ penqi
#define penqc_ penqc
#define penq1i_ penq1i
#endif


#ifndef TRUE
#define	TRUE		1
#endif

#ifndef FALSE
#define FALSE		0
#endif

#ifndef NULL
#define NULL		0
#endif

#ifndef ABS
#define ABS(x) 	( ((x) >= 0) ? (x) : -(x) )
#endif

#ifndef MIN
#define MIN(x, y) 	( ((x) < (y)) ? (x) : (y) )
#endif

#ifndef MAX
#define MAX(x, y) 	( ((x) > (y)) ? (x) : (y) )
#endif

#ifndef MAXFLOAT
#define MAXFLOAT 3.4E+35
#endif

#ifndef BIGFLOAT
#define BIGFLOAT 3.4E+35
#endif

/*  Plotting modes for DigitalModel */

#define M_NAME_MAX	100
#define CONTOUR		1
#define SHADING		2
#define GRID_VALUES	4
#define WIND_ARROWS	8
#define WIND_FLAGS	16
#define WIND_STREAM	32
#define WIND_ISOTACHS 	64

#define	PI  3.14159265358979323846
#define	CDR 0.017453293	/*  Conversion factor: degrees to radians */
#define	CRD 57.295779513	/*  Conversion factor: radians to degrees */
#define	EARTH_RADIUS  6378160.
#define	FLATTENING  0.0033528
#define NSTEPS  16.
#define PROJNONE  0
#define PROJUTM  2
#define PROJMERCATOR  3
#define PROJGAUSS  4
#define PROJLAMBERTMILLION  5
#define PROJLAMBERT  6
#define PROJPOLYCONIC  7
#define PROJCYLINDRICAL  0
#define PROJPOLAR  9
#define PROJBIPOLAR  10
#define PROJALBERS  11
#define PROJMILLER  12
#define PROJSATELLITE  90
#define PROJPOLY  254
#define GENERALPROJ  255



#define PDATUM  0x1 
#define PHEMISPHERE  0x2 
#define PLATITUDE  0x4 
#define PLONGITUDE  0x8 
#define PFIRSTLAT  0x10 
#define PSECDLAT  0x20 

//F
#if 0
#define MAGEnqi(par,iv) penqi_(par,iv,strlen(par))
#define MAGEnqc(par,cv) \
        {       int i;                                          \
                memset(cv, '\0', sizeof(cv));                   \
                penqc_(par,cv,strlen(par),(sizeof(cv)-1));      \
                for (i = sizeof(cv)-1; i > 0; i--)              \
                        if (cv[i] == ' ') cv[i] = '\0';         \
        }

#define MAGEnq1i(paramtr, iarray, size, out_size) \
	{							\
		int vsize = size;				\
		penq1i_(paramtr, iarray, &vsize, out_size, strlen(paramtr));\
	}
#endif

typedef struct
{
	short		Dproj;	/* projection code */
	char*		Dname;	/* planimetric datum name */

	Real		Ddx,	/* ellipsoid translation along x axis */
	Ddy,	/* ellipsoid translation along y axis */
	Ddz;	/* ellipsoid translation along z axis */

	double		Drd,	/* earth equatorial radius */
	Dflt;	/* earth flattening */

} Datum ;

typedef struct
{
	short		GPhemis;	/* hemisphere : polar stereo*/
	/* all these parameters must be in*/
	/* radians*/
	double		GPlat0,		/* origin parallel    */ 
			GPlon0,		/* origin meridian*/
	GPstlat1,	/* standard parallel*/
	GPstlat2;	/* standard parallel	*/
} GeneralProjection ;

typedef GeneralProjection PolarStereo;
typedef GeneralProjection CylindEquid;
typedef GeneralProjection NoProjection;
typedef GeneralProjection Mercartor;

typedef struct
{
	double		SPri,	/* Sensor angle resolution (y axis, radians)*/
	SPrj,	/* Sensor angle resolution (x axis, radians)*/
	SPis,	/* Y-coordinate of sub-satellite point */
	SPjs,	/* X-coordinate of sub-satellite point*/
	SPla0,	/* Latitude of sub-satellite point  (radians)*/
	SPlo0,	/* Longitude of sub-satellite point (radians)*/
	SPrs,	/* Radii of satellite (meters)*/
	SPscn,	/* Scaning mode: 0-WE/NS, 1-SN/EW*/
	SPyaw;	/* The orientation of the grid i.e. the angle*/
	/* in radians between the increasing y axis*/
	/* and the meridian of the sub-satellite point */
	/* in the direction of increasing latitude.*/
} Satellite;

typedef struct SProjection
{

	char*		Pname;		/* projection name */
	char*		Pdname;		/* datum name */
	int		Pid;		/* projection id on database */
	short		Pcode,		/* projection code */
	Pgbcode,	/* grib projection code */
	Pgbcode1,	/* grib internal general projection code */
	Pbits,		/* mask of necessary parameters */
	Pdatum;		/* planimetric datum */

	Real		Pdx,		/* ellipsoid translation along x axis */
	Pdy,		/* ellipsoid translation along y axis */
	Pdz;		/* ellipsoid translation along z axis*/

	double		Prd,		/* earth equatorial radius in meters. */
	Pflt;		/* earth flattening*/

	double		Poffx,		/* x offset*/
	Poffy;		/* y offset*/

	struct SProjection 	*Pout;		/* projection output*/

	union {
		GeneralProjection*	Gp;		/* General Projectioon*/
		Satellite*			Sat;	/* Satellite Projectioon */
		PolarStereo*		Ps;
		Mercartor*			Mc;
		NoProjection*		Np;
		CylindEquid*		Ce;
	} Proj;
		
} SProjection;


 typedef struct
{
	char	id[13];		/* image identifier */

	short	satellite,	/* satellite identifier xxxx */
	band,		/* spectral band */
	year,	
	month,
	day,
	hour,
	minutes,
	seconds,
	nx,		/* number of columns */
	ny,		/* number of lines */
	xp,		/* column of sub-satellite point */
	yp,		/* line of sub-satellite point */
	x0,		/* image origin column */
	y0,		/* image origin line */
		path,		/*  orbit number xxxx */
	row,		/*  image number xxxx */
	plevel,		/* processing level */
	vc,
	ac;

	Real	lap,		/*  latitude of sub-satellite point */
	lop,		/*  longitude of sub-satellite point */
	yaw,		/* orientation angle ... definir grau ou rad */
	nr,		/*  altitude or radius of satellite in meters */
	rx,		/* / horizontal resolution in meters */
	ry;		/*  vertical resolution in meters */
} ImageDoc;

typedef struct
{
        SProjection*    IProj;  /* pointer to projection */
        BBox*            IBBox;   /* image bounding area*/
        short           Inx,    /* no. of columns*/
        Iny;    /* no. of lines*/
        Real            Irx,    /* horizontal resolution*/
        Iry;    /* vertical resolution*/

        /* Internal controls of the image*/

        unsigned long   pixel;          /* pixel out of image*/
        unsigned long   outsidevalue;   /* Default value to pixels outside Image
*/
        unsigned char   *tbuf;          /* buffer for transfer data*/

} SImage;


// Functions definitions
Real pWidth(BBox*);
Real pHeight(BBox*);
short pContains(BBox*, CPoint*);
short pIntersects(BBox*, BBox*);
void pInitBBox(BBox*, Real, Real, Real, Real);
void pBBoxRemapInOut (SProjection*, SProjection*, BBox*);
void pBBoxRemap (SProjection*, BBox*);
void pimii1_(Real, Real, Real, Real, int, int, Real, Real, int, int, unsigned char*);
void pimii2_(Real, Real, Real, Real, int, int, Real, Real, int, int, unsigned char*);
void pll2ic(Real&, Real&);
void pl2p1_(Real*, Real*);
void pl2p2_(Real*, Real*);
void pp2l1_(Real*, Real*);
void pp2l2_(Real*, Real*);
void premap_();
void pdeal_();
void pimin1_();
void pimind_(int, char*, Real, Real, Real, double, double);
void pimp1_(char*, char*, int, int, int, int, Real, Real, Real, double, double, double, double);
void pimp2_(char*, char*, int, int, int, int, Real, Real, Real, double, double, double, double);
void pimg1_(int, double, double, double, double);
void pimg2_(int, double, double, double, double);
void pims1_(double, double, double, double, double, double, double, double, double);
void pims2_(double, double, double, double, double, double, double, double, double);

short pTooBig(CPoint*);
short pPointOnLine(SImage*, CPoint*, CPoint*, CPoint*);
CPoint pMaxPoint(CPoint*, CPoint*);
CPoint pMinPoint(CPoint*, CPoint*);
void pInitPoint(CPoint*, Real, Real);
void pInitDatum(Datum*, short, char*, Real, Real, Real,double, double);
void pInitProj(SProjection*, char*, char*, int, short, short, Real, Real, Real, double, double, double, double);
short pProjEq(SProjection*, SProjection*);
void pInitGen(GeneralProjection*, short, double, double, double, double);
void pInitSat(Satellite*, double, double, double, double, double, double, double, double, double);
CPoint pLL2PC(SProjection*, CPoint);
CPoint pPC2LL(SProjection*, CPoint);
void ChangeLL(SProjection*, double*, double*);	
CPoint pSatLL2PC(SProjection*, CPoint);
CPoint pSatPC2LL(SProjection*, CPoint);
CPoint pCylLL2PC(SProjection*, CPoint);
CPoint pCylPC2LL(SProjection*, CPoint);
CPoint pPolLL2PC(SProjection*, CPoint);
CPoint pPolPC2LL(SProjection*, CPoint);
CPoint pMerLL2PC(SProjection*, CPoint);
CPoint pMerPC2LL(SProjection*, CPoint);
void pInitImage(SImage*, BBox*, short, short, Real, Real, unsigned long, unsigned long, unsigned char*, SProjection*);
void pInterpolateIn (SImage*, SImage*, CPoint, CPoint, CPoint, CPoint, CPoint, CPoint, CPoint, CPoint);
unsigned char pInterAt(SImage*, CPoint*);
void pPut(SImage*, short, short, unsigned char);
unsigned char pGet(SImage*, short, short);
CPoint pCoord2Index (SImage*, CPoint*);
void pRemapI (SImage*, SImage*);
void pInitRemap(SImage*, BBox*, SProjection*, Real, Real, unsigned char**, SImage*);

#endif
// proj_braz_DEFINED
