/* *********************************************************
 * *                                                       *
 * *  SIGMET Projection related structure Definition File  *
 * *                                                       *
 * *********************************************************
 * File: include/projection.h
 *
 *            COPYRIGHT (c) 2002, 2003, 2004, 2006 BY 
 *          VAISALA INC., WESTFORD MASSACHUSETTS, U.S.A.  
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED. 
 */ 
#ifndef SIGMET_PROJECTION_H
#define SIGMET_PROJECTION_H 1

/* Using ellipsoid GRS80, also WGS84
 */
#define FEARTH_EQUATORIAL_RADIUS (6378.137)
#define FEARTH_POLAR_RADIUS      (6356.7523)

/* Height of geosynchronous height above earth in Km
 */
#define FEARTH_GEO_HEIGHT    (42155.0)

/* Internal limits on valid numbers */
#define IMAP_EARTH_MIN_RADIUS  6300   /*Earth's equatorial radius */
#define IMAP_EARTH_MAX_RADIUS  6400
#define IMAP_EARTH_MIN_FLAT    200    /* Earth's flattening */
#define IMAP_EARTH_MAX_FLAT    400

#define IMAP_EARTH_GEODE_COUNT (3)
/* --------------------------------------------------
 * Definition of a map projection.  The type of the projection is given,
 * along with any additional parameters that are necessary to define it.
 */
struct mpj_projection8 {
  UINT1 iprojection_type ;	/* Type of map projection */
  char ipad1x7[7] ;
  struct latlon8 Ref;           /* Lat/Lon (radians) of projection ref pt */
  FLT8   fStdPar1;              /* Standard parallel 1, radians */
  FLT8   fStdPar2;              /* Standard parallel 2, radians */
  FLT8   fEarthRadius;          /* Earth's equitorial radius */
  FLT8   fFlattening;           /* 1/flattening, 0 means spherical */
} ;

#define MAPROJ_AZIMUTHAL   (0)	/* Azimuthal equidistant */
#define MAPROJ_MERCATOR    (1)	/* Standard Mercator  (cylindrical)*/
#define MAPROJ_POLSTEREO   (2)	/* Polar Stereographic (azimuthal)*/
#define MAPROJ_UTM         (3)	/* Universal Transverse Mercator (cylindrical)*/
#define MAPROJ_PERSPECTIVE (4)	/* Perspective (geosynchronous satellite) (azimuthal */
#define MAPROJ_EDC         (5)	/* Equidistant cylindrical (Plate Carree, lat/lon grid) */
#define MAPROJ_GNOMONIC    (6)	/* Gnomonic (azimuthal) */
#define MAPROJ_GAUSS       (7)	/* Gauss Conformal (Gauss-Krueger, Transverse Mercator)(cylindrical) */
#define MAPROJ_LAMBERT     (8)	/* Lambert Conformal Conic */
#define MAPROJ_COUNT       (9)	/* Number of map projections defined */

/* Projection region definition.  This structure defines a patch on the
 * Earth that corresponds to a rectangular piece of a map.  The lower left,
 * center, and upper right Lat/Lon are given, along with the center-to-
 * east-edge and center-to-north-edge distances and Lat/Lon coordinates.
 * The map coordinates for each point are also included.  Note that these
 * number define a region on the earth, independent of the number of
 * pixels which may be used to draw it.  When pixelized, the lower left
 * corner is the lower left corner of the lower left pixel.  For another
 * example: the fde number is the distance from the center of the projection
 * to the right edge of the rightmost pixel of a display.
 */
struct mpj_region8 {
  /* Definitions of corner and certer points, and distances from the center
   * to the top and right map edges.
   */
  struct latlon8 Loc0;          /* Lower Left corner */
  struct latlon8 Loc1;          /* Center */
  struct latlon8 Loc2;          /* Upper right corner */

  struct latlon8 LocR;		/* Center-to-Right map intersection */
  struct latlon8 LocT;		/* Center-to-Top map intersection */

  FLT8 fdn, fde ;		/* Center-to-Top & Center-to-Right in km */

  /* All map coordinates are relative to a unit sphere Earth, but use an
   * unknown and arbitrary zero reference point that depends on the
   * projection chosen.
   */
  struct XYPoint8 Map0;      	/* Map coordinates of lower left corner */
  struct XYPoint8 Map1;		/* Map coordinates of center */
  struct XYPoint8 Map2;		/* Map coordinates of upper right corner */

  struct XYPoint8 MapR;		/* Map coordinates of upper right corner */
  struct XYPoint8 MapT;		/* Map coordinates of upper right corner */

  /* The following variables permit a user interface using "pixels", rather
   * than map units.  Fxpix does not need to be an integer, but normally is.
   * It must be greater than zero.
   */
  FLT8 fxpix ;			/* Supplied by user, never modified internally */
  FLT8 fypix ;			/* Calculated by mpj_pin_region() */

} ;

/* Bitmask parameters to specify subsets of the set of values in the
 * map projection structure.
 */

#define MPJ_LOC0   (0x00000001)      /* Lower left corner is known */
#define MPJ_LOC1   (0x00000002)      /* center is known */
#define MPJ_LOC2   (0x00000004)      /* upper right corner is known */

#define MPJ_FSCALE (0x00000010)      /* Scale in center */
#define MPJ_FDN    (0x00000040)
#define MPJ_FDE    (0x00000080)

/* ================================================================
 * Reprojection structures.
 */  
/* Shift table element used for Reproject routines.  This is a point
 * backwards table.  Each element tells which pixel will move forward
 * to the current position.  The forecast time is thus already 
 * included in these numbers. */
struct rpj_shift
{
  FLT4 fxpos, fypos;
  FLT4 fScale ;      /* Multiply the input data by this value */
};

struct rpj_table
{
  SINT4 iWidth;      /* Width of table */
  SINT4 iHeight;     /* Height of table */
  SINT4 iTotalWidth; /* Width of target region */
  SINT4 iTotalHeight;/* Height of target region */
  SINT4 iSkip;       /* pixels skipped for each table element */
  UINT1 lOverlap;    /* TRUE if images overlap */
  char  ipad13x3[3];
  struct rpj_shift Shifts[1];  /* Actual size is different */
};

/* Weighting table for averaging two points together */
struct rpj_weight
{
  FLT4 fweight1, fweight2 ;
};

/* ===================================================================
 * Overlay Structure Definitions
 */

/* This is the structure that is there for each point to be drawn
 * If it is a overlay point, then the "itype" field applies, if it is a
 * fill point, the the "iFillColor" field applies.  Must be 8-byte aligned.
 */
#define OVERLAY_POINT_SIZE (32)
struct overlay_point8
{
  struct latlon8 Earth;   /* Location to draw the point */
  UINT1 iFlags;           /* Flag word: */
#define OVERLAY_FLG_START  (0x01)  /* Point is first point of a segment */
#define OVERLAY_FLG_SELECT (0x04)  /* Point is selected */
  UINT1 ilayer;           /* Index of layer, origin 0 */
  UINT1 iFillColor;       /* Color value for fill point, defined in vtv_lib.h */
  UINT1 ipad[5];
};

#define OVERLAY_ICON_MAX (200)
#define ICON_HEAP_SIZE (20000)
#define LAYER_NAME_SIZE (20)
struct layer_def
{
  char sname[LAYER_NAME_SIZE];
  UINT1 icolor;         /* Overlay color number, colors defined in vtv_lib.h */
  char ipad_end[3];
};

#define ICON_NAME_SIZE (20)
struct icon_def
{
  char sname[ICON_NAME_SIZE];
  SINT4 iwidth;         /* Width of icon in pixels */
  SINT4 iheight;        /* Height of icon in pixels */
  SINT4 ibyte_width;    /* Width of storage in bytes */
  SINT4 iXHot;
  SINT4 iYHot;
  UINT4 iIconPtr;       /* Offset to data in heap */
  UINT4 iMaskPtr;       /* Offset to mask in heap */
#define ICON_UNUSED_PTR (0xffffffff)
};

struct icon_inventory
{
  struct icon_def  icon[OVERLAY_ICON_MAX];
  UINT1  icon_heap[ICON_HEAP_SIZE];
  UINT4  iIconHeapUsed;           /* Count of bytes used in heap */
  char   ipad_end[4];
};

/* Size of layer_dir must be a multiple of 8-bytes */
struct layer_dir
{
  struct layer_def layer[32];
  struct icon_inventory icons;
};

struct overlay_file_header8
{
  struct latlon8 FillCenter;    /*Center of underlay filling */
  struct latlon8 DrawCenter;   	/*Center of drawing overlay in overx */
  struct latlon8 Reference;     /*Reference point of AED format */
  char  sname[12];		/*Space padded */

  /* This variable holds the maximum range of the overlay in km.  This is to help
   * with the underlay drawing.  If there is no maximum range known, then
   * regions at the edge of the map will fill around the edge of the world.
   * Zero means no line drawn.
   */
  FLT4  fFillRange;
  SINT4 itextcnt;		/*Number of text strings */
  SINT4 itextptr;
  SINT4 ifillcnt;		/*Number of fill points */
  SINT4 ifillptr;
  SINT4 ipointcnt;		/*Number of points following */
  SINT4 ipointptr;
  SINT4 igifcnt;                /*Number of gifs following */
  SINT4 igifptr;
  SINT4 iHeadCommentCnt;        /*Number of bytes of Header comments */
  SINT4 iHeadCommentPtr;
  SINT4 iLayerCommentCnt;       /*Number of bytes of Layer comments */
  SINT4 iLayerCommentPtr;
  SINT4 iTextCommentCnt;        /*Number of bytes of Text comments */
  SINT4 iTextCommentPtr;
  SINT4 iFillCommentCnt;        /*Number of bytes of Fill comments */
  SINT4 iFillCommentPtr;
  SINT4 iPointCommentCnt;       /*Number of bytes of Point comments */
  SINT4 iPointCommentPtr;
  SINT4 iGifCommentCnt;         /*Number of bytes of Gif comments */
  SINT4 iGifCommentPtr;
  UINT4 lAedFormat;

  UINT1 ipad[4];		/*Pad the structure to make it the correct length */
};

/* This is the structure that defines a gif underlay image.
   Must be 8-byte aligned.
 */
/* #define OVERLAY_GIF_SIZE (88) */
struct overlay_gif8
{
  struct latlon8         center;       /* Center location of gif file */
  struct mpj_projection8 projection;   /* Projection of gif file */
  FLT8                   fXScale;      /* Projection X scale in km/pixel */
  FLT8                   fYScale;      /* Projection Y scale in km/pixel */
  char                   sFilename[24];/* Name of gif file. ${IRIS_OVERLAY} */
  UINT1                  ilayer;       /* Index of layer, origin 0 */
  UINT1                  iFlags;       /* Flag word: */
  UINT1                  ipad[6];
/*  struct PICINFO         picinfo;   */
};


/*
 * This is the structure for each icon and text string to be drawn. 
 * Locations are specified with the overlay_point structure defined above.
 * Screen relative locations are specified relative to the display screen
 * where 0.0 means the left, or lower side, and 1.0 means the right or top.
 * Left means left justified, thus the string extends from the specified
 * point to the right.
 */
#define OVERLAY_TEXT_SIZE (OVERLAY_POINT_SIZE + 80 + 16)
struct overlay_text8
{
  struct overlay_point8 point;
  char  string[40];   /* String to draw */
  char  string_full[40];
  FLT4  fRotation;   /* Icon rotation angle CW in radians */
  UINT2 isize;       /* Height of text in pixels */
  UINT1 icon;        /* Index of icon, origin 0 */
  UINT1 iTextFlags;
  UINT1 iTextLayer;  /* Used when the text is in a different layer from the icon */
  char  ipad_end[7];

  /* Low four bits of the iTextFlags field are defined by these #defines: */
#define ITEXT_LEFT     (1)          /*left justified */
#define ITEXT_MIDDLE   (2)          /*centered */
#define ITEXT_RIGHT    (3)          /*right justified */
#define ITEXT_TOP      (4)          /*top justified*/
#define ITEXT_BOTTOM   (5)          /*bottom justified*/

  /* These flags can be added to those above: */
#define ITEXT_SCN_REL     ( 64)     /*Position is screen relative*/
#define ITEXT_HIGHLIGHT   (128)     /*Highlight the text*/
#define ITEXT_ICON        ( 32)     /*This is an icon, with optional text*/
#define ITEXT_TEXT_ONLY   ( 16)     /*"Icon text", skip drawing the icon*/
};

/*
 * The maximum number of overlay features allowed
 */
#define OVERLAY_POINT_MAX (500000)
#define OVERLAY_TEXT_MAX  (400)
#define OVERLAY_FILL_MAX  (4000)
#define OVERLAY_GIF_MAX   (10)


/* ===================================================================
 * Catchment Structure Definitions
 */
#define CATCHMENT_MAX       (512)

struct catch_file_header8
{
  char   sName[16];	     /* Name of catchment definition file, Null terminated */
  struct latlon8 DrawCenter; /* Draw center */
  SINT4  iCommentPointer;    /* Header comment pointer */
  SINT4  iCommentSize;       /* Size of comments in bytes */
  SINT4  iCatchCount;        /* Number of catchments in the file */
  char   pad44x4[4];
  SINT4  iCatchPointer[CATCHMENT_MAX];  /* Offsets (origin1) of each catchment from start of heap */
};

struct one_catch_header8
{
  char  sName[16];       /* Name of the catchment */
  SINT4 iNumber;         /* Number of the catchment */
  SINT4 iPointCount;     /* Number of points which follow */
  struct overlay_point8 Label;  /* Location of the label */
  UINT2 iAlertLevel;     /* Alert if rain above this level */
  UINT2 iSize;           /* Size of label text */
  char  pad_52x4[4];    /* force to multiple of 8 bytes */
  struct overlay_point8 Points[1];
};

/* Maximum number of different catchment files loaded into memory.
 */
#define MAX_CATCHMENT_FILES    (20)

/* Catch inventory structure */
struct catch_inventory8
{
  /* Array of catchment headers descriptors: */
  struct catch_file_header8 List[MAX_CATCHMENT_FILES];
  /* Size of the whole inventory */
  SINT4 iInvSize;
  /* Count of the number of catchment headers available in the array above: */
  SINT4 iFileCount;
  /* Size of the heap in bytes */
  SINT4 iHeapSize;
  char  pad12x4[4];

#define CATCH_HEAP_PAD (8)

  UINT1 iheap8[CATCH_HEAP_PAD];  /* Heap must be 8-byte aligned */
};


/* Overlay inventory structure */
struct overlay_inventory8
{
  /* Array of catchment headers descriptors: */
  struct overlay_file_header8 List[MAX_OVERLAYS];
  struct layer_dir Layers;
  /* Size of the whole inventory in bytes */
  SINT4 iInvSize;
  /* Count of the number of catchment headers available in the array above: */
  SINT4 iFileCount;
  /* Size of the heap in bytes */
  SINT4 iHeapSize;
  char  pad12x4[4];

#define OVERLAY_HEAP_PAD (8)

  UINT1 iheap8[CATCH_HEAP_PAD];  /* Heap must be 8-byte aligned */

};

/* ====================================================================
 * Beam Blockage related structures.
 */
struct block_azimuth_entry
{
  BIN2  iAzimuthAngle;
  UINT2 iAzimuthIndex;  /* Index is  (( AZ * RES ) + 0x8000) >> 16 */
  UINT2 iRange1;        /* Range of blockage in 1/10 of km */
  UINT2 iCorrection1;   /* Correction factor in 1/10 of dB (0 means none) */
  UINT2 iRange2;        /* Range of blockage in 1/10 of km (FFFF if no second range)*/
  UINT2 iCorrection2;   /* Correction factor in 1/10 of dB (0 means none) */
};

struct block_sweep_header
{
  BIN2   iElevationAngle;
  UINT2  iAzResolution;        /* Azimuth resolution, expressed in # rays/sweep */
  SINT4  iNextSweepIncrement;  /* Byte increment to the next sweep header (0 if none) */
  SINT4  iAzCount;
  struct block_azimuth_entry Azimuth[1];
};

/* Header for a single site.  The complete blockage table consists of
 * a linked list of these.
 */
struct block_site_header
{
  char   sSiteName16[20];        /* Name of the site, Null terminated */
  SINT4  iNextSiteIncrement;     /* Byte increment to the next site header (0=none)*/
  SINT4  iFirstSweepIncrement;   /* Byte increment to the first sweep (0=none) */
};

/* Header for a single site.  The complete terrain blockage table consists of
 * a linked list of these.
 */
struct terrain_site_header
{
  char   sSiteName16[20];     /* Name of the site, Null terminated */
  SINT4  iNextSiteOffset;     /* Byte offset to the next site header (0=none)*/
  UINT4  iAzResolution;       /* Azimuth resolution, expressed in # rays/sweep */
  UINT4  iRangeBinCount;      /* Number of range bins per azimuth */
  FLT4   fRangeResolution;    /* Range resolution of heights array in km */
  SINT2  iHeights[2];         /* Height array.  Index by [Az*iRangeCount + Range] */
};

#endif /* #ifndef SIGMET_PROJECTION_H */
