/* ---------------------------------------------------------------- */
/* Some classes to facilitate GPX interaction:                      */
/*                                                                  */
/*   GeoPoint - a definition of a GPX <trkpt>, <rtept> or <wpt>     */
/*   GeoSegment - an array of GeoPoints defining a GPX <trkseg>     */
/*   GeoRoute - an array of GeoPoints defining a GPX <rte>          */
/*   GeoWaypoints - an array of GeoPoints defining the GPX <wpt>'s  */
/*   GeoTrack - a list of GeoSegments defining a GPX <trk>          */
/*                                                                  */
/* ---------------------------------------------------------------- */
/*                                                                  */
/* Originally by Ruurd J. Idenburg                                  */
/*                                                                  */
/* No copyright, no licence, no guarantees or warrantees, be it     */
/* explicit, implicit or whatever. Usage is totally and completely  */
/* at the users own risk, the author shall not be liable for any    */
/* damages whatsoever, for any reason whatsoever.                   */
/*                                                                  */
/* Please keep this comment block intact when modifying this code   */
/* and add a note with date and a description.                      */
/*                                                                  */
/* ---------------------------------------------------------------- */
/* 2014/01/26 - Initial version approximately                       */
/* ---------------------------------------------------------------- */
::class "geoPoint" public

::attribute latlon get    -- latitude and longitude in decimal degrees
::attribute elevation     -- elevation in meters of the point
::attribute time          -- creation/modification timestamp in UTC
::attribute name          -- name for the point
::attribute comment       -- comment for the point
::attribute description   -- description of the point
::attribute source        -- the source of it to indicate reliability
::attribute link          -- a link to additional info on the point 
::attribute symbol        -- text of a GPS symbol name
::attribute type          -- type/classification of the point
::attribute fix           -- the type of fix for this point
::attribute geoidheight     -- height (in meters) of geoid (mean sea level) 
                            -- above WGS84 earth ellipsoid, as defined in
                            -- NMEA GGA message.
                           
::method init
  expose latlon
  use strict arg lat,lon
  latlon = .geoloc~new(lat,lon)
exit

::method lat
  expose latlon
  return latlon~latitude
exit

::method lon
  expose latlon
  return latlon~longitude
exit

::method makeGPX
  use arg indent, gpxTag='wpt'
  say indent || '<'gpxTag 'lat="' || self~lat || '" lon="' || self~lon || '" >'
  say indent'</'gpxTag'>'
exit  

 
::class "geoArray" private subclass array inherit restrictable

::attribute type get

-- geoArray is a one-dimensional array in one of 3 types; routepoints,
-- trackpoints or waypoints, which all three can have only geoPoints as
-- members of the collection.
-- @param One of "R(outepoints), Trackpoints, W(aypoints), first character suffices.
-- @result A newly created empty array of the type specified   
::method init
expose type
  use arg type
  type = type~subchar(1)~upper
  if "RTW"~pos(type)==0 
    then raise syntax 93.914 array(1,"R(outepoints),T(rackpoints),W(aypoints)",type)
  self~init:super
exit  

::method isAllowed 
  use arg item
  return (item~class~id==.geoPoint~id)
exit

::method makeGPX
  expose type
  use arg indent
  arrayTag = "rte trkseg"~word("RTW"~pos(type)) 
  -- the <wpt> parent tag is <gpx>, which is not (yet) implemented
  pointTag = "rtept trkpt wpt"~word("RTW"~pos(type))
  if arrayTag\=="" then do
    say indent'<'arrayTag'>'
  end
  do i=1 to self~items
    self[i]~makeGPX(indent'  ',pointTag)
  end
  if arrayTag\=="" then do
    say indent'</'arrayTag'>'
  end
exit

::class "geoSegment" public subclass geoArray 

::method init
  if arg()>0
    then raise syntax 93.902 array(0)
  self~init:super('T')
exit
  
::class "geoRoute" public subclass geoArray

::method init
  if arg()>0
    then raise syntax 93.902 array(0)
  self~init:super('R')
exit

::class "geoWaypoints" public subclass geoArray

::method init
  if arg()>0
    then raise syntax 93.902 array(0)
  self~init:super('W')
exit
  
::class "geoTrack" public subclass geoArray 
 
::method isAllowed
  use arg item
  return (item~class~id==.geoSegment~id)

::method makeGPX
  indent = ''
  say '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>'
  say '<gpx version="1.1" creator="RJI" >'  
  indent = indent'  '
  say indent'<trk>'
  do i=1 to self~items
    self[i]~makeGPX(indent'  ')
  end
  say indent'</trk>'
  say '</gpx>'
exit

::requires "restrictable.cls"
::requires "geoloc.cls"