/***************************************************************************
 *
 * Project:  OpenCPN
 * Purpose:  Tide and Current Manager
 * Author:   David Register
 * Todo add original author
 *
 ***************************************************************************
 *   Copyright (C) 2010 by David S. Register                               *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program 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 this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA.         *
 **************************************************************************/

#ifndef __TCMGR_H__
#define __TCMGR_H__

#include <wx/arrstr.h>
#include <map>

#include "Station_Data.h"
#include "IDX_entry.h"
#include "TC_Error_Code.h"
#include "TCDataSource.h"

// ----------------------------------------------------------------------------
// external C linkages
// ----------------------------------------------------------------------------

//----------------------------------------------------------------------------
//   constants
//----------------------------------------------------------------------------

#define USF_REMOVE 1
#define USF_UPDATE 2
#define USF_WRITE  3

#ifndef M_PI
#define M_PI 3.141592654
#endif

#define TIDE_MAX_DERIV (2)      // Maximum derivative supported
/* TIDE_TIME_PREC
 *   Precision (in seconds) to which we will find roots
 */
#define TIDE_TIME_PREC (15)

/* TIDE_TIME_BLEND
 *   Half the number of seconds over which to blend the tides from
 *   one epoch to the next.
 */
#define TIDE_BLEND_TIME (3600)

/* TIDE_TIME_STEP
 *   We are guaranteed to find all high and low tides as long as their
 * spacing is greater than this value (in seconds).
 */
#define TIDE_TIME_STEP (TIDE_TIME_PREC)
#define TIDE_BAD_TIME   ((time_t) -1)


//----------------------------------------------------------------------------
//   Reference Station Data
//----------------------------------------------------------------------------

typedef struct {
    Station_Data      *sta_data;
    void        *next;
} mru_entry;


//----------------------------------------------------------------------------
//   TCMgr
//----------------------------------------------------------------------------

class TCMgr
{
public:
    TCMgr();
    ~TCMgr();

    TC_Error_Code LoadDataSources(wxArrayString &sources);
    wxArrayString GetDataSet( void ) {
        return m_sourcefile_array;
    }

    bool IsReady(void) {
        return bTCMReady;
    }

    bool GetTideOrCurrent(time_t t, int idx, float &value, float& dir);
    bool GetTideOrCurrent15(time_t t, int idx, float &tcvalue, float& dir, bool &bnew_val);
    bool GetTideFlowSens(time_t t, int sch_step, int idx, float &tcvalue_now, float &tcvalue_prev, bool &w_t);
    void GetHightOrLowTide(time_t t, int sch_step_1, int sch_step_2, float tide_val ,bool w_t , int idx, float &tcvalue, time_t &tctime);

    int GetStationTimeOffset(IDX_entry *pIDX);
    int GetNextBigEvent(time_t *tm, int idx);
    double GetStationLat(IDX_entry *pIDX);
    double GetStationLon(IDX_entry *pIDX);
    
    const IDX_entry *GetIDX_entry(int index) const;

    int Get_max_IDX() const
	{
        return m_Combined_IDX_array.GetCount()-1;
    }

    std::map<double, const IDX_entry*> GetStationsForLL(double xlat, double xlon) const;
    
    int GetStationIDXbyName(const wxString & prefix, double xlat, double xlon) const;
    int GetStationIDXbyNameType(const wxString & prefix, double xlat, double xlon, char type) const;

private:
    void PurgeData();

    void LoadMRU(void);
    void SaveMRU(void);
    void AddMRU(Station_Data *psd);
    void FreeMRU(void);

    bool bTCMReady;
    wxString pmru_file_name;

    ArrayOfTCDSources   m_source_array;
    wxArrayString       m_sourcefile_array;

    ArrayOfIDXEntry     m_Combined_IDX_array;

};

/* $Id: tcd.h.in 3744 2010-08-17 22:34:46Z flaterco $ */
/* tcd.h.  Generated from tcd.h.in by configure. */

#ifndef __OAML_TIDES_H__
#define __OAML_TIDES_H__


/*****************************************************************************
 *
 *                            DISTRIBUTION STATEMENT
 *
 *    This source file is unclassified, distribution unlimited, public
 *    domain.  It 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.
 *
 ******************************************************************************/


/*
 *  Data types for libtcd API
 *  Formerly nvtypes.h, NAVO Standard Data Type Definitions
 *
 *  This section may appear slightly different from one platform to the
 *  next.  The build process for libtcd generates #includes and data
 *  type definitions as needed to provide integer types of specific
 *  sizes.
 */

/* Generated includes */
#include <sys/types.h>
#ifndef __WXMSW__
#include <inttypes.h>

/* Generated data types */
#define NV_BYTE    int8_t
#define NV_INT16   int16_t
#define NV_INT32   int32_t
#define NV_INT64   int64_t
#define NV_U_BYTE  uint8_t
#define NV_U_INT16 uint16_t
#define NV_U_INT32 uint32_t
#define NV_U_INT64 uint64_t
#else
#define NV_BYTE    unsigned char
#define NV_INT16   short
#define NV_INT32   int
#define NV_INT64   long
#define NV_U_BYTE  unsigned char
#define NV_U_INT16 unsigned short
#define NV_U_INT32 unsigned int
#define NV_U_INT64 unsigned long

#endif

/* Hard-coded data types */
#define NV_BOOL    unsigned char
#define NV_CHAR    char
#define NV_U_CHAR  unsigned char
#define NV_FLOAT32 float
#define NV_FLOAT64 double

/* Defined values */
#define NVFalse         0
#define NVTrue          1
#define NV_U_INT32_MAX  4294967295
#define NV_INT32_MAX    2147483647
#define NV_U_INT16_MAX  65535
#define NV_INT16_MAX    32767


#define LIBTCD_VERSION   "PFM Software - libtcd v2.2.5 - 2010-08-17"
#define LIBTCD_MAJOR_REV 2
#define LIBTCD_MINOR_REV 2


/*
 *  COMPAT114 is defined here if and only if libtcd was compiled with
 *  --enable-COMPAT114.  COMPAT114 forces API changes to enable
 *  applications written against the v1 API to build with more recent
 *  libraries and successfully interact with v2 TCD files.  This will
 *  BREAK applications expecting the v2 API.  It is for localized use
 *  only (libraries built with this option should not be distributed).
 */
#undef COMPAT114

/* Select #warning versus #pragma message (whichever works) */
#undef USE_PRAGMA_MESSAGE

#ifdef COMPAT114
#ifdef USE_PRAGMA_MESSAGE
#pragma message("WARNING:  COMPAT114 is enabled!  See libtcd.html.")
#else
#warning COMPAT114 is enabled!  See libtcd.html.
#endif
#endif


/*  Maximum values.  */

/* One-line character strings */
#define ONELINER_LENGTH      90
/* Verbose character strings */
#define MONOLOGUE_LENGTH  10000
#define MAX_CONSTITUENTS    255


#ifdef  __cplusplus
extern "C" {
    #endif
    
    
    /*  Public portion of the database header.  */
    /* See libtcd.html for documentation */
    
    typedef struct
    {
        NV_CHAR           version[ONELINER_LENGTH];
        NV_U_INT32        major_rev;
        NV_U_INT32        minor_rev;
        NV_CHAR           last_modified[ONELINER_LENGTH];
        NV_U_INT32        number_of_records;
        NV_INT32          start_year;
        NV_U_INT32        number_of_years;
        NV_U_INT32        constituents;
        NV_U_INT32        level_unit_types;
        NV_U_INT32        dir_unit_types;
        NV_U_INT32        restriction_types;
        NV_U_INT32        datum_types;
        NV_U_INT32        countries;
        NV_U_INT32        tzfiles;
        NV_U_INT32        legaleses;
        
        /* Need this to read V1 files. */
        NV_U_INT32        pedigree_types;
    } DB_HEADER_PUBLIC;
    
    
    /*  Header portion of each station record.  */
    /* See libtcd.html for documentation */
    
    enum TIDE_RECORD_TYPE {REFERENCE_STATION=1, SUBORDINATE_STATION=2};
    
    typedef struct
    {
        NV_INT32                record_number;
        NV_U_INT32              record_size;
        NV_U_BYTE               record_type;
        NV_FLOAT64              latitude;
        NV_FLOAT64              longitude;
        NV_INT32                reference_station;
        NV_INT16                tzfile;
        NV_CHAR                 name[ONELINER_LENGTH];
    } TIDE_STATION_HEADER;
    
    
    /*  Tide station record.  */
    /* See libtcd.html for documentation */
    
    typedef struct
    {
        /* Common */
        TIDE_STATION_HEADER     header;
        NV_INT16                country;
        NV_CHAR                 source[ONELINER_LENGTH];
        NV_U_BYTE               restriction;
        NV_CHAR                 comments[MONOLOGUE_LENGTH];
        NV_CHAR                 notes[MONOLOGUE_LENGTH];
        NV_U_BYTE               legalese;
        NV_CHAR                 station_id_context[ONELINER_LENGTH];
        NV_CHAR                 station_id[ONELINER_LENGTH];
        NV_U_INT32              date_imported;
        NV_CHAR                 xfields[MONOLOGUE_LENGTH];
        NV_U_BYTE               direction_units;
        NV_INT32                min_direction;
        NV_INT32                max_direction;
        NV_U_BYTE               level_units;
        
        /* Type 1 */
        NV_FLOAT32              datum_offset;
        NV_INT16                datum;
        NV_INT32                zone_offset;
        NV_U_INT32              expiration_date;
        NV_U_INT16              months_on_station;
        NV_U_INT32              last_date_on_station;
        NV_U_BYTE               confidence;
        NV_FLOAT32              amplitude[MAX_CONSTITUENTS];
        NV_FLOAT32              epoch[MAX_CONSTITUENTS];
        
        /* Type 2 */
        NV_INT32                min_time_add;
        NV_FLOAT32              min_level_add;
        NV_FLOAT32              min_level_multiply;
        NV_INT32                max_time_add;
        NV_FLOAT32              max_level_add;
        NV_FLOAT32              max_level_multiply;
        NV_INT32                flood_begins;
        NV_INT32                ebb_begins;
        
        #ifdef COMPAT114
        /* Deprecated */
        NV_INT16                pedigree;
        NV_U_BYTE               units;
        NV_U_BYTE               avg_level_units;
        NV_FLOAT32              min_avg_level;
        NV_FLOAT32              max_avg_level;
        #endif
    } TIDE_RECORD;
    
    
    /* DWF: This value signifies "null" or "omitted" slack offsets
     *   (flood_begins, ebb_begins).  Zero is *not* the same. */
    /* Time offsets are represented as hours * 100 plus minutes.
     *   0xA00 = 2560
     *   It turns out that offsets do exceed 24 hours (long story), but we
     *   should still be safe with the 60.
     */
    #define NULLSLACKOFFSET 0xA00
    
    /* This is the level below which an amplitude rounds to zero. */
    /* It should be exactly (0.5 / DEFAULT_AMPLITUDE_SCALE). */
    #define AMPLITUDE_EPSILON 0.00005
    
    /* Rounding function. */
    #define NINT(a)   ((a)<0.0 ? (NV_INT32) ((a) - 0.5) : (NV_INT32) ((a) + 0.5))
    
    
    /*  Public function prototypes.  */
    
    /* Prints a low-level dump of the tide record to stderr. */
    void dump_tide_record (const TIDE_RECORD *rec);
    
    /* For fields in the tide record that are indices into tables of
     *   character string values, these functions are used to retrieve the
     *   character string value corresponding to a particular index.  The
     *   value "Unknown" is returned when no translation exists.  The return
     *   value is a pointer into static memory. */
    const NV_CHAR *get_country (NV_INT32 num);
    const NV_CHAR *get_tzfile (NV_INT32 num);
    const NV_CHAR *get_level_units (NV_INT32 num);
    const NV_CHAR *get_dir_units (NV_INT32 num);
    const NV_CHAR *get_restriction (NV_INT32 num);
    const NV_CHAR *get_datum (NV_INT32 num);
    const NV_CHAR *get_legalese (NV_INT32 num);
    
    /* Get the name of the constituent corresponding to index num
     *   [0,constituents-1].  The return value is a pointer into static
     *   memory. */
    const NV_CHAR *get_constituent (NV_INT32 num);
    
    /* Get the name of the station whose record_number is num
     *   [0,number_of_records-1].  The return value is a pointer into static
     *   memory. */
    const NV_CHAR *get_station (NV_INT32 num);
    
    /* Returns the speed of the constituent indicated by num
     *   [0,constituents-1]. */
    NV_FLOAT64 get_speed (NV_INT32 num);
    
    /* Get the equilibrium argument and node factor for the constituent
     *   indicated by num [0,constituents-1], for the year
     *   start_year+year. */
    NV_FLOAT32 get_equilibrium (NV_INT32 num, NV_INT32 year);
    NV_FLOAT32 get_node_factor (NV_INT32 num, NV_INT32 year);
    
    /* Get all available equilibrium arguments and node factors for the
     *   constituent indicated by num [0,constituents-1].  The return value
     *   is a pointer into static memory which is an array of
     *   number_of_years floats, corresponding to the years start_year
     *   through start_year+number_of_years-1. */
    NV_FLOAT32 *get_equilibriums (NV_INT32 num);
    NV_FLOAT32 *get_node_factors (NV_INT32 num);
    
    /* Convert between character strings of the form "[+-]HH:MM" and the
     *   encoding Hours * 100 + Minutes.  ret_time pads the hours with a
     *   leading zero when less than 10; ret_time_neat omits the leading
     *   zero and omits the sign when the value is 0:00.  Returned pointers
     *   point into static memory. */
    NV_INT32 get_time (const NV_CHAR *string);
    NV_CHAR *ret_time (NV_INT32 time);
    NV_CHAR *ret_time_neat (NV_INT32 time);
    
    /* Convert the encoding Year * 10000 + Month [1, 12] * 100 + Day [1,
     *   31] to a character string of the form "YYYY-MM-DD", or "NULL" if
     *   the value is zero.  The returned pointer points into static memory.
     *   (The compact form, without hyphens, is obtainable just by printing
     *   the integer.) */
    NV_CHAR *ret_date (NV_U_INT32 date);
    
    /* When invoked multiple times with the same string, returns record
     *   numbers of all stations that have that string anywhere in the
     *   station name.  This search is case insensitive.  When no more
     *   records are found it returns -1. */
    NV_INT32 search_station (const NV_CHAR *string);
    
    /* Inverses of the corresponding get_ operations.  Return -1 for not
     *   found. */
    NV_INT32 find_station (const NV_CHAR *name);
    NV_INT32 find_tzfile (const NV_CHAR *name);
    NV_INT32 find_country (const NV_CHAR *name);
    NV_INT32 find_level_units (const NV_CHAR *name);
    NV_INT32 find_dir_units (const NV_CHAR *name);
    NV_INT32 find_restriction (const NV_CHAR *name);
    NV_INT32 find_datum (const NV_CHAR *name);
    NV_INT32 find_constituent (const NV_CHAR *name);
    NV_INT32 find_legalese (const NV_CHAR *name);
    
    /* Add the value of name to the corresponding lookup table and return
     *   the index of the new value.  If db is not NULL, the database header
     *   struct pointed to will be updated to reflect the changes. */
    NV_INT32 add_restriction (const NV_CHAR *name, DB_HEADER_PUBLIC *db);
    NV_INT32 add_tzfile (const NV_CHAR *name, DB_HEADER_PUBLIC *db);
    NV_INT32 add_country (const NV_CHAR *name, DB_HEADER_PUBLIC *db);
    NV_INT32 add_datum (const NV_CHAR *name, DB_HEADER_PUBLIC *db);
    NV_INT32 add_legalese (const NV_CHAR *name, DB_HEADER_PUBLIC *db);
    
    /* Add the value of name to the corresponding lookup table if and
     *   only if it is not already present.  Return the index of the value.
     *   If db is not NULL, the database header struct pointed to will be
     *   updated to reflect the changes. */
    NV_INT32 find_or_add_restriction (const NV_CHAR *name, DB_HEADER_PUBLIC *db);
    NV_INT32 find_or_add_tzfile (const NV_CHAR *name, DB_HEADER_PUBLIC *db);
    NV_INT32 find_or_add_country (const NV_CHAR *name, DB_HEADER_PUBLIC *db);
    NV_INT32 find_or_add_datum (const NV_CHAR *name, DB_HEADER_PUBLIC *db);
    NV_INT32 find_or_add_legalese (const NV_CHAR *name, DB_HEADER_PUBLIC *db);
    
    /* Set the speed for the constituent corresponding to index num
     *   [0,constituents-1]. */
    void set_speed (NV_INT32 num, NV_FLOAT64 value);
    
    /* Set the equilibrium argument and node factor for the constituent
     *   corresponding to index num [0,constituents-1], for the year
     *   start_year+year. */
    void set_equilibrium (NV_INT32 num, NV_INT32 year, NV_FLOAT32 value);
    void set_node_factor (NV_INT32 num, NV_INT32 year, NV_FLOAT32 value);
    
    /* Opens the specified TCD file.  If a different database is already
     *   open, it will be closed.  libtcd maintains considerable internal
     *   state and can only handle one open database at a time.  Returns
     *   false if the open failed. */
    NV_BOOL open_tide_db (const NV_CHAR *file);
    
    /* Closes the open database. */
    void close_tide_db ();
    
    /* Creates a TCD file with the supplied constituents and no tide
     *   stations.  Returns false if creation failed.  The database is left
     *   in an open state. */
    NV_BOOL create_tide_db (const NV_CHAR *file, NV_U_INT32 constituents,
                            NV_CHAR const * const constituent[], const NV_FLOAT64 *speed,
                            NV_INT32 start_year, NV_U_INT32 num_years,
                            NV_FLOAT32 const * const equilibrium[],
                            NV_FLOAT32 const * const node_factor[]);
    
    /* Returns a copy of the database header for the open database. */
    DB_HEADER_PUBLIC get_tide_db_header ();
    
    /* Gets "header" portion of tide record for the station whose
     *   record_number is num [0,number_of_records-1] and writes it into
     *   rec.  Returns false if num is out of range.  num is preserved in
     *   the static variable current_index. */
    NV_BOOL get_partial_tide_record (NV_INT32 num, TIDE_STATION_HEADER *rec);
    
    /* Invokes get_partial_tide_record for current_index+1.  Returns the
     *   record number or -1 for failure. */
    NV_INT32 get_next_partial_tide_record (TIDE_STATION_HEADER *rec);
    
    /* Invokes get_partial_tide_record for a station that appears closest
     *   to the specified lat and lon in the Cylindrical Equidistant
     *   projection.  Returns the record number or -1 for failure. */
    NV_INT32 get_nearest_partial_tide_record (NV_FLOAT64 lat, NV_FLOAT64 lon,
                                              TIDE_STATION_HEADER *rec);
    
    /* Gets tide record for the station whose record_number is num
     *   [0,number_of_records-1] and writes it into rec.  num is preserved
     *   in the static variable current_record.  Returns num, or -1 if num is
     *   out of range. */
    NV_INT32 read_tide_record (NV_INT32 num, TIDE_RECORD *rec);
    
    /* Invokes read_tide_record for current_record+1.  Returns the record
     *   number or -1 for failure. */
    NV_INT32 read_next_tide_record (TIDE_RECORD *rec);
    
    /* Add a new record, update an existing record, or delete an existing
     *   record.  If the deleted record is a reference station, all
     *   dependent subordinate stations will also be deleted.  Add and
     *   update return false if the new record is invalid; delete and update
     *   return false if the specified num is invalid.  If db is not NULL,
     *   the database header struct pointed to will be updated to reflect
     *   the changes. */
    NV_BOOL add_tide_record (TIDE_RECORD *rec, DB_HEADER_PUBLIC *db);
    #ifdef COMPAT114
    /* Omission of db parameter was a bug. */
    NV_BOOL update_tide_record (NV_INT32 num, TIDE_RECORD *rec);
    #else
    NV_BOOL update_tide_record (NV_INT32 num, TIDE_RECORD *rec, DB_HEADER_PUBLIC *db);
    #endif
    NV_BOOL delete_tide_record (NV_INT32 num, DB_HEADER_PUBLIC *db);
    
    /* Computes inferred constituents when M2, S2, K1, and O1 are given
     *   and fills in the remaining unfilled constituents.  The inferred
     *   constituents are developed or decided based on Article 230 of
     *   "Manual of Harmonic Analysis and Prediction of Tides," Paul
     *   Schureman, C&GS Special Publication No. 98, October 1971.  Returns
     *   false if M2, S2, K1, or O1 is missing. */
    NV_BOOL infer_constituents (TIDE_RECORD *rec);
    
    
    #ifdef COMPAT114
    /* Deprecated stuff. */
    #define NAME_LENGTH         ONELINER_LENGTH
    #define SOURCE_LENGTH       ONELINER_LENGTH
    #define COMMENTS_LENGTH     MONOLOGUE_LENGTH
    NV_CHAR *get_pedigree (NV_INT32 num);
    NV_INT32 find_pedigree (const NV_CHAR *name);
    NV_INT32 add_pedigree (const NV_CHAR *name, const DB_HEADER_PUBLIC *db);
    NV_BOOL check_simple (TIDE_RECORD rec);
    #endif
    
    #ifdef  __cplusplus
}
#endif

#endif


/* $Id: tide_db_header.h 1092 2006-11-16 03:02:42Z flaterco $ */

/*****************************************************************************\
 * 
 *                            DISTRIBUTION STATEMENT
 * 
 *    This source file is unclassified, distribution unlimited, public
 *    domain.  It 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.
 * 
 * \*****************************************************************************/




/***************************************************************************\
 * 
 *    Module Name:        TIDE DB option header file
 * 
 *    Programmer(s):      Jan C. Depner
 * 
 *    Date Written:       July 2002
 * 
 *    Purpose:            This header file defines all of the format options
 *                        that are stored in the TIDE DB file header.  To add a
 *                        new option you simply add it to the header_data
 *                        structure, then put a definition in the keys structure.
 *                        The keys structure contains a keyphrase such as
 *                        "[DATE]", a format like "%s", a datatype (see the
 *                        union in the TIDE_HEADER_DATA structure, a pointer to
 *                        the location at which to store the value(s), a count
 *                        if it is a repeating field (array), and a version
 *                        dependency flag (major.minor * 10).
 * 
 * 
 * 
 *****************************************************************************
 
 This header file uses the NAVO standard data types.  You must set one of
 the following options on the compile command line:
 
 NVDOS, NVHPUX, NVIRIX, NVCLIX, NVLinux, NVSUNOS, NVWINNT, or NVWIN3X
 
 The only one referenced in libtcd is NVWIN3X. -- DWF, 2004-09-29
 
 \***************************************************************************/


#ifndef __TIDE_HEADER__
#define __TIDE_HEADER__

//#include "tcd.h"


typedef struct
{
    const NV_CHAR                    *keyphrase;
    const NV_CHAR                    *datatype;
    union
    {
        const NV_CHAR                *cstr;
        NV_INT32               *i32;
        NV_U_INT32             *ui32;
    } address;
} KEY;


typedef struct
{
    DB_HEADER_PUBLIC  pub;
    NV_CHAR           **constituent;
    NV_FLOAT64        *speed;
    NV_FLOAT32        **equilibrium;
    NV_FLOAT32        **node_factor;
    NV_CHAR           **level_unit;
    NV_CHAR           **dir_unit;
    NV_CHAR           **restriction;
    NV_CHAR           **tzfile;
    NV_CHAR           **country;
    NV_CHAR           **datum;
    NV_CHAR           **legalese;
    NV_U_INT32        header_size;
    NV_U_INT32        speed_bits;
    NV_U_INT32        speed_scale;
    NV_INT32          speed_offset;
    NV_U_INT32        equilibrium_bits;
    NV_U_INT32        equilibrium_scale;
    NV_INT32          equilibrium_offset;
    NV_U_INT32        node_bits;
    NV_U_INT32        node_scale;
    NV_INT32          node_offset;
    NV_U_INT32        amplitude_bits;
    NV_U_INT32        amplitude_scale;
    NV_U_INT32        epoch_bits;
    NV_U_INT32        epoch_scale;
    NV_U_INT32        constituent_bits;
    NV_U_INT32        record_type_bits;
    NV_U_INT32        latitude_scale;
    NV_U_INT32        latitude_bits;
    NV_U_INT32        longitude_scale;
    NV_U_INT32        longitude_bits;
    NV_U_INT32        record_size_bits;
    NV_U_INT32        station_bits;
    NV_U_INT32        level_unit_bits;
    NV_U_INT32        dir_unit_bits;
    NV_U_INT32        restriction_bits;
    NV_U_INT32        max_restriction_types;
    NV_U_INT32        tzfile_bits;
    NV_U_INT32        max_tzfiles;
    NV_U_INT32        country_bits;
    NV_U_INT32        max_countries;
    NV_U_INT32        datum_bits;
    NV_U_INT32        max_datum_types;
    NV_U_INT32        legalese_bits;
    NV_U_INT32        max_legaleses;
    NV_U_INT32        datum_offset_bits;
    NV_U_INT32        datum_offset_scale;
    NV_U_INT32        date_bits;
    NV_U_INT32        months_on_station_bits;
    NV_U_INT32        confidence_value_bits;
    NV_U_INT32        time_bits;
    NV_U_INT32        level_add_bits;
    NV_U_INT32        level_add_scale;
    NV_U_INT32        level_multiply_bits;
    NV_U_INT32        level_multiply_scale;
    NV_U_INT32        direction_bits;
    NV_U_INT32        constituent_size;
    NV_U_INT32        level_unit_size;
    NV_U_INT32        dir_unit_size;
    NV_U_INT32        restriction_size;
    NV_U_INT32        tzfile_size;
    NV_U_INT32        country_size;
    NV_U_INT32        datum_size;
    NV_U_INT32        legalese_size;
    NV_U_INT32        end_of_file;
    
    /* Need these to read V1 files. */
    NV_U_INT32        pedigree_bits;
    NV_U_INT32        pedigree_size;
} TIDE_HEADER_DATA;


static TIDE_HEADER_DATA        hd;

/* "The initializer for a union with no constructor is either a single
 *   expression of the same type, or a brace-enclosed initializer for
 *   the first member of the union." -- Ellis & Stroustrup, The Annotated
 *   C++ Reference Manual, 1990, Section 8.4.1. */

static KEY                     keys[] =
{
    {
        "[VERSION]",
        "cstr",
        {(NV_CHAR *) hd.pub.version},
    },
    {
        "[MAJOR REV]",
        "ui32",
        {(NV_CHAR *) &hd.pub.major_rev},
    },
    {
        "[MINOR REV]",
        "ui32",
        {(NV_CHAR *) &hd.pub.minor_rev},
    },
    {
        "[LAST MODIFIED]",
        "cstr",
        {(NV_CHAR *) hd.pub.last_modified},
    },
    {
        "[NUMBER OF RECORDS]",
        "ui32",
        {(NV_CHAR *) &hd.pub.number_of_records},
    },
    {
        "[START YEAR]",
        "i32",
        {(NV_CHAR *) &hd.pub.start_year},
    },
    {
        "[NUMBER OF YEARS]",
        "ui32",
        {(NV_CHAR *) &hd.pub.number_of_years},
    },
    {
        "[CONSTITUENTS]",
        "ui32",
        {(NV_CHAR *) &hd.pub.constituents},
    },
    {
        "[LEVEL UNIT TYPES]",
        "ui32",
        {(NV_CHAR *) &hd.pub.level_unit_types},
    },
    {
        "[DIRECTION UNIT TYPES]",
        "ui32",
        {(NV_CHAR *) &hd.pub.dir_unit_types},
    },
    {
        "[RESTRICTION TYPES]",
        "ui32",
        {(NV_CHAR *) &hd.pub.restriction_types},
    },
    {
        "[PEDIGREE TYPES]",
        "ui32",
        {(NV_CHAR *) &hd.pub.pedigree_types},
    },
    {
        "[TZFILES]",
        "ui32",
        {(NV_CHAR *) &hd.pub.tzfiles},
    },
    {
        "[COUNTRIES]",
        "ui32",
        {(NV_CHAR *) &hd.pub.countries},
    },
    {
        "[DATUM TYPES]",
        "ui32",
        {(NV_CHAR *) &hd.pub.datum_types},
    },
    {
        "[LEGALESES]",
        "ui32",
        {(NV_CHAR *) &hd.pub.legaleses},
    },
    {
        "[HEADER SIZE]",
        "ui32",
        {(NV_CHAR *) &hd.header_size},
    },
    {
        "[SPEED BITS]",
        "ui32",
        {(NV_CHAR *) &hd.speed_bits},
    },
    {
        "[SPEED SCALE]",
        "ui32",
        {(NV_CHAR *) &hd.speed_scale},
    },
    {
        "[SPEED OFFSET]",
        "i32",
        {(NV_CHAR *) &hd.speed_offset},
    },
    {
        "[EQUILIBRIUM BITS]",
        "ui32",
        {(NV_CHAR *) &hd.equilibrium_bits},
    },
    {
        "[EQUILIBRIUM SCALE]",
        "ui32",
        {(NV_CHAR *) &hd.equilibrium_scale},
    },
    {
        "[EQUILIBRIUM OFFSET]",
        "i32",
        {(NV_CHAR *) &hd.equilibrium_offset},
    },
    {
        "[NODE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.node_bits},
    },
    {
        "[NODE SCALE]",
        "ui32",
        {(NV_CHAR *) &hd.node_scale},
    },
    {
        "[NODE OFFSET]",
        "i32",
        {(NV_CHAR *) &hd.node_offset},
    },
    {
        "[AMPLITUDE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.amplitude_bits},
    },
    {
        "[AMPLITUDE SCALE]",
        "ui32",
        {(NV_CHAR *) &hd.amplitude_scale},
    },
    {
        "[EPOCH BITS]",
        "ui32",
        {(NV_CHAR *) &hd.epoch_bits},
    },
    {
        "[EPOCH SCALE]",
        "ui32",
        {(NV_CHAR *) &hd.epoch_scale},
    },
    {
        "[CONSTITUENT BITS]",
        "ui32",
        {(NV_CHAR *) &hd.constituent_bits},
    },
    {
        "[LEVEL UNIT BITS]",
        "ui32",
        {(NV_CHAR *) &hd.level_unit_bits},
    },
    {
        "[DIRECTION UNIT BITS]",
        "ui32",
        {(NV_CHAR *) &hd.dir_unit_bits},
    },
    {
        "[RESTRICTION BITS]",
        "ui32",
        {(NV_CHAR *) &hd.restriction_bits},
    },
    {
        "[PEDIGREE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.pedigree_bits},
    },
    {
        "[TZFILE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.tzfile_bits},
    },
    {
        "[COUNTRY BITS]",
        "ui32",
        {(NV_CHAR *) &hd.country_bits},
    },
    {
        "[DATUM BITS]",
        "ui32",
        {(NV_CHAR *) &hd.datum_bits},
    },
    {
        "[LEGALESE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.legalese_bits},
    },
    {
        "[RECORD TYPE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.record_type_bits},
    },
    {
        "[LATITUDE SCALE]",
        "ui32",
        {(NV_CHAR *) &hd.latitude_scale},
    },
    {
        "[LATITUDE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.latitude_bits},
    },
    {
        "[LONGITUDE SCALE]",
        "ui32",
        {(NV_CHAR *) &hd.longitude_scale},
    },
    {
        "[LONGITUDE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.longitude_bits},
    },
    {
        "[RECORD SIZE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.record_size_bits},
    },
    {
        "[STATION BITS]",
        "ui32",
        {(NV_CHAR *) &hd.station_bits},
    },
    {
        "[DATUM OFFSET BITS]",
        "ui32",
        {(NV_CHAR *) &hd.datum_offset_bits},
    },
    {
        "[DATUM OFFSET SCALE]",
        "ui32",
        {(NV_CHAR *) &hd.datum_offset_scale},
    },
    {
        "[DATE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.date_bits},
    },
    {
        "[MONTHS ON STATION BITS]",
        "ui32",
        {(NV_CHAR *) &hd.months_on_station_bits},
    },
    {
        "[CONFIDENCE VALUE BITS]",
        "ui32",
        {(NV_CHAR *) &hd.confidence_value_bits},
    },
    {
        "[TIME BITS]",
        "ui32",
        {(NV_CHAR *) &hd.time_bits},
    },
    {
        "[LEVEL ADD BITS]",
        "ui32",
        {(NV_CHAR *) &hd.level_add_bits},
    },
    {
        "[LEVEL ADD SCALE]",
        "ui32",
        {(NV_CHAR *) &hd.level_add_scale},
    },
    {
        "[LEVEL MULTIPLY BITS]",
        "ui32",
        {(NV_CHAR *) &hd.level_multiply_bits},
    },
    {
        "[LEVEL MULTIPLY SCALE]",
        "ui32",
        {(NV_CHAR *) &hd.level_multiply_scale},
    },
    {
        "[DIRECTION BITS]",
        "ui32",
        {(NV_CHAR *) &hd.direction_bits},
    },
    {
        "[CONSTITUENT SIZE]",
        "ui32",
        {(NV_CHAR *) &hd.constituent_size},
    },
    {
        "[LEVEL UNIT SIZE]",
        "ui32",
        {(NV_CHAR *) &hd.level_unit_size},
    },
    {
        "[DIRECTION UNIT SIZE]",
        "ui32",
        {(NV_CHAR *) &hd.dir_unit_size},
    },
    {
        "[RESTRICTION SIZE]",
        "ui32",
        {(NV_CHAR *) &hd.restriction_size},
    },
    {
        "[PEDIGREE SIZE]",
        "ui32",
        {(NV_CHAR *) &hd.pedigree_size},
    },
    {
        "[TZFILE SIZE]",
        "ui32",
        {(NV_CHAR *) &hd.tzfile_size},
    },
    {
        "[COUNTRY SIZE]",
        "ui32",
        {(NV_CHAR *) &hd.country_size},
    },
    {
        "[DATUM SIZE]",
        "ui32",
        {(NV_CHAR *) &hd.datum_size},
    },
    {
        "[LEGALESE SIZE]",
        "ui32",
        {(NV_CHAR *) &hd.legalese_size},
    },
    {
        "[END OF FILE]",
        "ui32",
        {(NV_CHAR *) &hd.end_of_file},
    }
};
#endif



#endif
