/* *********************************************************
 * *                                                       *
 * *  SIGMET Projection related structure Definition File  *
 * *                                                       *
 * *********************************************************
 * File: include/projection.h
 *
 * COPYRIGHT (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010 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_ELLIPSE_COUNT (5)
/* --------------------------------------------------
 * Definition of a map projection.  The type of the projection is given,
 * along with any additional parameters that are necessary to define it.
 */
#define STRUCT_MPJ_PROJECTION8_DEFINED 1
struct mpj_projection8 {
    uint8_t iprojection_type ;	/* Type of map projection */
    char ipad1x7[7] ;
    struct latlon8 Ref;         /* Lat/Lon (radians) of projection ref pt */
    double   fStdPar1;          /* Standard parallel 1, radians */
    double   fStdPar2;          /* Standard parallel 2, radians */
    double   fEarthRadius;      /* Earth's equitorial radius */
    double   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
 * numbers 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 fEarthDE number is the distance from the center of the
 * projection to the right edge of the rightmost pixel of a display.
 */
#define STRUCT_MPJ_REGION8_DEFINED 1
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 */

    double fEarthDN, fEarthDE;	/* Center-to-Top & Center-to-Right in sphere km */
    double fMapDN,  fMapDE; 	/* Center-to-Top & Center-to-Right in grid km */

    /* All map coordinates use a zero false easting and false northing */
    struct XYPoint8 Map0;      	/* Map coordinates of lower left corner, km */
    struct XYPoint8 Map1;       /* Map coordinates of center, km */
    struct XYPoint8 Map2;       /* Map coordinates of upper right corner, km */

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

    /* 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.
     */
    double fxpix ;              /* Supplied by user, never modified internally */
    double 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_MAP_DN    (0x00000010)   /* Distance on projection map in km */
#define MPJ_MAP_DE    (0x00000020)
#define MPJ_EARTH_DN  (0x00000040)   /* Distance on earth surface in km */
#define MPJ_EARTH_DE  (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
{
    double fxpos, fypos;
    double fScale ;      /* Multiply the input data by this value */
};

struct rpj_table
{
    int32_t iWidth;      /* Width of table */
    int32_t iHeight;     /* Height of table */
    int32_t iTotalWidth; /* Width of target region */
    int32_t iTotalHeight;/* Height of target region */
    int32_t iSkip;       /* pixels skipped for each table element */
    uint8_t 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
{
    double 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 */
    uint8_t iFlags;         /* Flag word: */
#define OVERLAY_FLG_START      (0x01)  /* Point is first point of a segment */
#define OVERLAY_FLG_SELECT     (0x04)  /* Point is selected */
#define OVERLAY_FLG_FILL_SMALL (0x08)  /* Fill small area */
    uint8_t ilayer;         /* Index of layer, origin 0 */
    uint8_t iFillColor;     /* Color value for fill point, defined in vtv_lib.h */
    uint8_t 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];
    uint8_t 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];
    int32_t iwidth;         /* Width of icon in pixels */
    int32_t iheight;        /* Height of icon in pixels */
    int32_t ibyte_width;    /* Width of storage in bytes */
    int32_t iXHot;
    int32_t iYHot;
    uint32_t iIconPtr;      /* Offset to data in heap */
    uint32_t iMaskPtr;      /* Offset to mask in heap */
#define ICON_UNUSED_PTR (0xffffffff)
};

struct icon_inventory
{
    struct icon_def  icon[OVERLAY_ICON_MAX];
    uint8_t  icon_heap[ICON_HEAP_SIZE];
    uint32_t  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.
     */
    float  fFillRange;
    int32_t itextcnt;             /*Number of text strings */
    int32_t itextptr;
    int32_t ifillcnt;             /*Number of fill points */
    int32_t ifillptr;
    int32_t ipointcnt;            /*Number of points following */
    int32_t ipointptr;
    int32_t igifcnt;              /*Number of gifs following */
    int32_t igifptr;
    int32_t iHeadCommentCnt;      /*Number of bytes of Header comments */
    int32_t iHeadCommentPtr;
    int32_t iLayerCommentCnt;     /*Number of bytes of Layer comments */
    int32_t iLayerCommentPtr;
    int32_t iTextCommentCnt;      /*Number of bytes of Text comments */
    int32_t iTextCommentPtr;
    int32_t iFillCommentCnt;      /*Number of bytes of Fill comments */
    int32_t iFillCommentPtr;
    int32_t iPointCommentCnt;     /*Number of bytes of Point comments */
    int32_t iPointCommentPtr;
    int32_t iGifCommentCnt;       /*Number of bytes of Gif comments */
    int32_t iGifCommentPtr;
    uint32_t lAedFormat;

    uint8_t 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 */
    double                   fXScale;    /* Projection X scale in km/pixel */
    double                   fYScale;    /* Projection Y scale in km/pixel */
    char                   sFilename[24];/* Name of gif file. ${IRIS_OVERLAY} */
    uint8_t                  ilayer;     /* Index of layer, origin 0 */
    uint8_t                  iFlags;     /* Flag word: */
    uint8_t                  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];
    float fRotation;    /* Icon rotation angle CW in radians */
    uint16_t isize;     /* Height of text in pixels */
    uint8_t icon;       /* Index of icon, origin 0 */
    uint8_t iTextFlags;
    uint8_t 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 (1000000)
#define OVERLAY_TEXT_MAX  (5000)
#define OVERLAY_FILL_MAX  (4000)
#define OVERLAY_GIF_MAX   (10)


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

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

struct one_catch_header8
{
    char  sName[16];       /* Name of the catchment */
    int32_t iNumber;       /* Number of the catchment */
    int32_t iPointCount;   /* Number of points which follow */
    struct overlay_point8 Label; /* Location of the label */
    uint16_t iAlertLevel;  /* Alert if rain above this level */
    uint16_t 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 */
    int32_t iInvSize;
    /* Count of the number of catchment headers available in the array above: */
    int32_t iFileCount;
    /* Size of the heap in bytes */
    int32_t iHeapSize;

    /* Heap must be 8-byte aligned */
#define CATCH_HEAP_PAD (8)
#ifdef __GNUC__
    uint8_t iheap8[CATCH_HEAP_PAD] __attribute__ ((aligned (8)));
#else
    char  pad12x4[4];
    uint8_t iheap8[CATCH_HEAP_PAD]; 
#endif
};


/* 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 */
    int32_t iInvSize;
    /* Count of the number of catchment headers available in the array above: */
    int32_t iFileCount;
    /* Size of the heap in bytes */
    int32_t iHeapSize;
    char  pad12x4[4];

    /* Heap must be 8-byte aligned */
#define OVERLAY_HEAP_PAD (8)
#ifdef __GNUC__
    uint8_t iheap8[CATCH_HEAP_PAD] __attribute__ ((aligned (8)));
#else
    char  pad12x4[4];
    uint8_t iheap8[CATCH_HEAP_PAD]; 
#endif
};

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

struct block_sweep_header
{
    BIN2   iElevationAngle;
    uint16_t  iAzResolution; /* Azimuth resolution, expressed in # rays/sweep */
    int32_t  iNextSweepIncrement;  /* Byte increment to the next sweep header (0 if none) */
    int32_t  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 */
    int32_t  iNextSiteIncrement;   /* Byte increment to the next site header (0=none)*/
    int32_t  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 */
    int32_t  iNextSiteOffset;   /* Byte offset to the next site header (0=none)*/
    uint32_t  iAzResolution;    /* Azimuth resolution, expressed in # rays/sweep */
    uint32_t  iRangeBinCount;   /* Number of range bins per azimuth */
    float  fRangeResolution;    /* Range resolution of heights array in km */
    int16_t  iHeights[2];       /* Height array.  Index by [Az*iRangeCount + Range] */
};

#endif /* #ifndef SIGMET_PROJECTION_H */
