#!@PYSHEBANG@
# -*- coding: utf-8 -*-
# @GENERATED@
# This file is Copyright 2010 by the GPSD project
# SPDX-License-Identifier: BSD-2-clause

# This code runs compatibly under Python 2 and 3.x for x >= 2.
# Preserve this property!
"""Feed location data from a running GPSD to a Google Earth instance.

This code originally by Jaroslaw Zachwieja and a guy referring
to himself/herself as TJ(http://tjworld.net)
Modified by Chen Wei <weichen302@aol.com> for use with gpsd
Cleaned up and adapted for the GPSD project by Eric S. Raymond.
"""

from __future__ import absolute_import, print_function, division

import argparse
import os
import socket     # for socket.error
import sys

# pylint wants local modules last
try:
    import gps
except ImportError as error:
    sys.stderr.write(
        "gegps: can't load Python gps libraries -- check PYTHONPATH.\n")
    sys.stderr.write("%s\n" % error)
    sys.exit(1)

gps_version = '@VERSION@'
if gps.__version__ != gps_version:
    sys.stderr.write("gegps: ERROR: need gps module version %s, got %s\n" %
                     (gps_version, gps.__version__))
    sys.exit(1)

KML_OPEN_IN_GE = '''\
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<NetworkLink>
        <name>Realtime GPS</name>
        <open>1</open>
        <Link>
                <href>Realtime_GPS.kml</href>
                <refreshMode>onInterval</refreshMode>
        </Link>
</NetworkLink>
</kml>
'''

if str is bytes:
    # This is here only because open in Python 2 throws a TypeError
    # when given an encoding argument. Do not change it until the
    # last Python 2 user dies, or someone retcons Python 2 open to
    # accept encoding. DO NOT trust anything that says it can go.
    polyopen = open
else:

    def polyopen(filename, mode):
        """Open a file with utf-8 encoding to silence linters."""
        return open(filename, mode, encoding="utf-8")


def kmlize(tpv):
    """Kmlize.

http://code.google.com/apis/kml/documentation/kmlreference.html
for official kml document.
"""
    latitude = tpv['lat']
    longitude = tpv['lon']

    # not all TPV includes speed, like when acquiring fix
    if 'speed' in tpv:
        speed_in = tpv['speed']               # meter/second
        speed = speed_in * gps.MPS_TO_KPH     # Km/h
    else:
        speed = 0

    # not all TPV includes heading, like when acquiring fix
    if 1 <= speed and 'track' in tpv:
        heading = int(round(tpv['track'], 0))
    else:
        heading = 0

    # not all TPV includes altitude
    # like ublox8 in fixed position (time) mode
    if 'alt' in tpv:
        altitude = tpv['alt']
    else:
        altitude = 0

    return """<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Placemark>
    <name>%s km/h,heading %s</name>
    <description>Realtime GPS feeding</description>
    <LookAt>
        <longitude>%s</longitude>
        <latitude>%s</latitude>
    </LookAt>
    <Point>
        <coordinates>%s,%s,%s</coordinates>
    </Point>
</Placemark>
</kml>""" % (speed, heading, longitude, latitude, longitude,
             latitude, altitude)


if __name__ == "__main__":
    description = 'Feed location data from GPSD to Google Earth.'
    usage = '%(prog)s [OPTIONS] [host[:port[:device]]]'
    epilog = ('BSD terms apply: see the file COPYING in the distribution root'
              ' for details.')

    parser = argparse.ArgumentParser(
        description=description,
        epilog=epilog,
        formatter_class=argparse.RawDescriptionHelpFormatter,
        usage=usage)
    parser.add_argument(
        '-?',
        action="help",
        help='show this help message and exit'
    )
    parser.add_argument(
        '-d', '--kmldir',
        default='.',
        dest='kmldir',
        help='Google Earth kml directory. [Default %(default)s]',
    )
    parser.add_argument(
        '-D',
        '--debug',
        default=0,
        dest='debug',
        help='Set level of debug. Must be integer. [Default %(default)s]',
        type=int,
    )
    parser.add_argument(
        '--device',
        default='',
        dest='device',
        help='The device to connect. [Default %(default)s]',
    )
    parser.add_argument(
        '--host',
        default='localhost',
        dest='host',
        help='The host to connect. [Default %(default)s]',
    )
    parser.add_argument(
        '-i', '--initialize',
        action='store_true',
        default=False,
        dest='initialize',
        help='Google Earth kml directory. [Default %(default)s]',
    )
    parser.add_argument(
        '--port',
        default=gps.GPSD_PORT,
        dest='port',
        help='The port to connect. [Default %(default)s]',
    )
    parser.add_argument(
        '-V', '--version',
        action='version',
        help='Output version to stderr, then exit',
        version="%(prog)s: Version " + gps_version + "\n",
    )
    parser.add_argument(
        'target',
        help='[host[:port[:device]]]',
        nargs='?',
    )
    options = parser.parse_args()

    # the options host, port, device are set by the defaults
    if options.target:
        # override host, port and device with target
        arg = options.target.split(':')
        len_arg = len(arg)
        if 1 == len_arg:
            (options.host,) = arg
        elif 2 == len_arg:
            (options.host, options.port) = arg
        elif 3 == len_arg:
            (options.host, options.port, options.device) = arg
        else:
            parser.print_help()
            sys.exit(0)

    if options.initialize:
        with polyopen(os.path.join(options.kmldir,
                      'Open_in_Google_Earth_RT_GPS.kml'), 'w',
                      ) as f:
            f.write(KML_OPEN_IN_GE)
        sys.exit(0)

    try:
        session = gps.gps(host=options.host, port=options.port,
                          verbose=options.debug)
    except socket.error:
        sys.stderr.write("gegps: Could not connect to gpsd daemon\n")
        sys.exit(1)

    session.stream(gps.WATCH_ENABLE)

    try:
        while 0 == session.read():
            if not hasattr(session, "data"):
                # no data yet
                continue

            if 'TPV' == session.data['class']:
                with polyopen(os.path.join(options.kmldir,
                              'Realtime_GPS.kml'), 'w') as f:
                    f.write(kmlize(session.data))
    except KeyboardInterrupt:
        print('gegps stopped ')

# end
# vim: set expandtab shiftwidth=4
