#
# This file is part of:
#
#  gpsman --- GPS Manager: a manager for GPS receiver data
#
#  Copyright (c) 1998-2013 Miguel Filgueiras migfilg@t-online.de
#
#    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 3 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.
#
#  File: metadata.tcl
#  Last change:  6 October 2013
#

# abstract data used in command-mode, in configuring the graphical interface,
#  and in parsing files

         # year from which seconds are reckoned; MUST BE < 1990
         #     not necessarily a leap year
         #     dates with years less than YEAR0 will not be accepted
         #     NB: Garmin protocol dates start at 1990 January 1st
         #         Lowrance dates start at 1992 January 1st
set YEAR0 1988

##### properties of known file formats
#   indices as NAME,PROPERTY  where PROPERTY is
#
#    mode         I/O mode in {in, out, {in out}}
#    depends      optional dependencies as evaluable code (globals must be
#                  declared), returning 0 on failure
#    filetype     in {unique, single, data} meaning: only one possible type,
#                 several types but each file has only one, other situations
#    types        to be used only if there is a single mode or the types are
#                 the same for in and out: admissible types as a subset of
#                 $TYPES-{GR}; the order must be that imposed by the format
#                 on the data in the file, if there is such an order
#    io_types     to be used if the mode is {in out} and the admissible types
#                 for in and out are different: pair with list of in types
#                 and list of out types as described for "types"
#    GREls        defined if there is support for dealing with GR elements
#    MODE,params  list of parameter names
#    MODE,pdefts  list of default values (or "ERROR" if value must be supplied)
#                  aligned with	list of parameter names; missing default
#                  values treated as ""; to get the value of a global
#                  variable use global:VARNAME
#    param,PNAME  list with global variable to set, conversion code from
#                  (external) $val to (internal) $val, constraint on possible
#                  values using $val as local variable and global variables
#                  of previous parameters (in the order given in the list of
#                  names), and, except for Shapefile, widget description as
#                  used by proc GMSetupParams (gendials.tcl); parameters are
#                  first converted in the order of occurrence in the list;
#                  each constraint and global variable are then checked/set
#                  in the same order

# includes VR contributions

array set FILEFORMAT {
    GPSMan,mode           {in out}
    GPSMan,filetype       data
    GPSMan,types          {WP RT TR LN LAP GR}
    GPStrans,mode         {in out}
    GPStrans,filetype     single
    GPStrans,types        {WP RT TR}
    GPStrans,GREls        1
    Shapefile,mode     {in out}
    Shapefile,depends  { global GSHPVersion ; string compare $GSHPVersion "" }
    Shapefile,filetype single
    Shapefile,types    {WP RT TR LN}
    Shapefile,GREls    1
    Shapefile,in,params   {dim pformat zone datum dunit aunit}
    Shapefile,in,pdefts   {3 DDD "" {WGS 84} m m}
    Shapefile,out,params  {dim pformat datum dunit aunit}
    Shapefile,out,pdefts  {3 DDD {WGS 84} m m}
    Shapefile,param,dim   {SHPDim Ignore
	{ expr [lsearch -exact {3 2} $val] != -1 }
    }
    Shapefile,param,pformat {SHPPFormt
	{ global INVTXT ; set val $INVTXT($val) }
	{ global NNUMPFORMATS
          expr [lsearch -exact $NNUMPFORMATS $val] == -1
	}
    }
    Shapefile,param,zone   {SHPZone Ignore
	{ global SHPPFormt ZGRID
	  expr ! $ZGRID($SHPPFormt) || \
	      {[CheckZone GMMessage $val $SHPPFormt]} ? 1 : 0
	}
    }
    Shapefile,param,datum  {SHPDatum Ignore
	{ global SHPPFormt SHPDatum
	  expr [BadDatumFor $SHPPFormt $SHPDatum GMMessage] == 0
	}
    }
    Shapefile,param,dunit  {SHPDUnit
	{ global INVTXT
	  if { [regexp {[a-z]} $val] } { set val $INVTXT($val) }
	}
	{ global SHPPFormt ZGRID
	  expr ! $ZGRID($SHPPFormt) || \
		   [lsearch -exact {M FT} $val] != -1 ? 1 : 0
	}
    }
    Shapefile,param,aunit  {SHPAUnit
	{ global INVTXT
	    if { [regexp {[a-z]} $val] } { set val $INVTXT($val) }
	}
	{ global SHPDim
	  expr $SHPDim == 2 || [lsearch -exact {M FT} $val] != -1 ? 1 : 0
	}
    }

    BGA,mode              in
    BGA,filetype          unique
    BGA,types             WP
    BGA,in,params         {feature findability air_activity}
    BGA,in,pdefts         {}
    BGA,param,feature     {BGAfeature Ignore { expr 1 } =$TXT(BGAfeature)}
    BGA,param,findability {BGAfindblty Ignore
	{ expr [regexp -nocase {^[A-DG]?$} $val] }
	=$TXT(BGAfindblty)
    }
    BGA,param,air_activity {BGAairact Ignore
	{ expr [string length $val] < 3 }
	=$TXT(BGAairact)
    }
    EasyGPS,mode          in
    EasyGPS,filetype      unique
    EasyGPS,types         WP
    EasyGPS,GREls         1
    Fugawi,mode           in
    Fugawi,filetype       unique
    Fugawi,types          WP
    Fugawi,GREls          1
    GD2,mode              in
    GD2,filetype          single
    GD2,types             {WP RT TR}
    GD2,GREls             1
    GPX,mode              {in out}
    GPX,filetype          data
    GPX,types             {WP RT TR}
    GPX,GREls             1
    GTrackMaker,mode      in
    GTrackMaker,filetype  data
    GTrackMaker,types     {WP RT TR}
    IGC,mode              in
    IGC,filetype          unique
    IGC,types             TR
    IGC,in,params         {alt}
    IGC,in,pdefts         {gps}
    IGC,param,alt         {GFOption Ignore
	{ expr [lsearch -exact "gps baro" $val]+1 }
	{/$TXT(alt)|gps baro}
    }
    Kismet,mode           in
    Kismet,filetype       unique
    Kismet,types          WP
    Kismet,in,params      {group}
    Kismet,in,pdefts      {0}
    Kismet,param,group    {GFOption Ignore { expr 1 } {@$TXT(nameGR)}}
    KML,mode              {in out}
    KML,filetype          data
    KML,io_types          {WP  {WP RT TR}}
    KML,GREls             1
    MapEdit,mode          in
    MapEdit,filetype      unique
    MapEdit,types         WP
    MapGuide,mode         in
    MapGuide,filetype     unique
    MapGuide,types        RT
    MapGuide,in,params    {version idno commt rem}
    MapGuide,in,pdefts    {global:MapGuideVersion "" "" ""}
    MapGuide,param,version {GFVersion Ignore
	{ expr [lsearch -exact "2002 03/04" $val]+1 }
	{/$TXT(version)|2002 03/04}
    }
    MapGuide,param,idno   {GFItemId Ignore { expr 1 } =$TXT(numberid)}
    MapGuide,param,commt  {GFItemCommt Ignore
	{ CheckComment GMMessage $val }
	=$TXT(cmmt)
    }
    MapGuide,param,rem    {GFItemNB Ignore { expr 1 } =$TXT(rmrk)}
    MapSend,mode          {in out}
    MapSend,filetype      single
    MapSend,types         {WP RT TR}
    Meridian,mode         {in out}
    Meridian,depends      { global GPSREC
                            expr ! [string compare $GPSREC "Magellan"] }
    Meridian,filetype     single
    Meridian,types        {WP RT TR}
    NMEA,mode             in
    NMEA,depends          { global GPSREC
                            expr ! [string compare $GPSREC "Garmin"] }
    NMEA,filetype         unique
    NMEA,types            TR
    Ozi,mode              {in out}
    Ozi,filetype          single
    Ozi,io_types          {WP {WP TR}}
    Ozi,GREls             1
    SimpleText,mode       {in out}
    SimpleText,filetype   unique
    SimpleText,types      TR
}

# compute names of defined formats

set ffs ""

foreach n [array names FILEFORMAT *,mode] {
    regsub {,mode$} $n "" n
    lappend ffs $n
}

set FILEFORMAT(names) [lsort -dictionary $ffs]

### receiver protocols with external and internal representations

array set RECPROTS {
    Garmin        garmin
    Garmin,Garmin garmin
    {Garmin,Garmin_USB}  garmin_usb
    Garmin,NMEA   nmea
    Garmin,SText  stext
    Garmin,simul  simul
}

### known map transformations

   # number of points needed to define each transformation
array set MAPTRANSFNPTS {
    Affine     3
    AffineConf 2
    NoRot      3
    LeastSquares   >=3
}

# LeastSquares not added to MAPKNOWNTRANSFS as it is not practical to
#  give a large number of points in the command line

set MAPKNOWNTRANSFS {Affine AffineConf NoRot}

### source files that are not encoded in ascii

array set ENCODED {
    isolatin1.tcl   iso8859-1
    i18n-utf8.tcl   utf-8
    langdeutsch.tcl iso8859-1
    langes.tcl      iso8859-1
    langfr.tcl      iso8859-1
    langit.tcl      iso8859-1
    langnl.tcl      iso8859-1
    langport.tcl    iso8859-1
    langru.tcl      utf-8
}
