#NAME:
#  SortWaypoints.py
#
#PUPORSE:
#  To sort a list of waypoints by date. Some Garmin apps to choose to sort 
#  the waypoints by the first digit in the waypoint number, which is very 
#  annoying.
#
#INPUTS:
#  filename: string
#    The name of the file containing the waypoints. It should be an 
#    xml or GPX extension.
#
#KEYWORDS:
#  GetElevation: bool
#    0 - Calculate elevation from lat, lon; 1 - get elevation from tag
#  UTCSub: int
#    Subtract this number from the hours in the time tag of each element
# 
from ReturnElevationFromLatLon import *
from datetime import *
import xml.etree.ElementTree as ET
import re
import json
import pdb
import getopt
import sys

# PARSE KEYWORDS
keywords    = ['GetElevation=', 'UTCSub=']

# DEFAULT VALUES FOR KEYWORDS
GetElevation     = 0
UTCSub           = 7

# NOW PARSE KEYWORDS
opts, extraparams = getopt.getopt(sys.argv[2:],'',keywords)
for o,p in opts:
  if o in ['--GetElevation']:
    GetElevation = int(p)
  if o in ['--UTCSub']:
    UTCSub = int(p)

# Get the file from the command line
FileName = sys.argv[1]
print('Extracting Data for : ' + FileName)
F = open(FileName,'r')
XMLHeader1 = F.readline()
XMLHeader2 = F.readline()
F.close()
F = open(FileName,'r')
FileCont = F.read()
F.close()

# Get the XML object from the waypoint file
xmlob = ET.fromstring(FileCont)

# Create some tracking variables and the array to hold our tuples 
wptNum   = 0
WptArr   = []

# Now go through and get all of the relevant data
for child in xmlob:
  if (child.tag.find('wpt') != -1):
    wptNum += 1
    Lat=child.get('lat')
    Lon=child.get('lon')
    Ele=ReturnElevationFromLatLon(float(Lat), float(Lon))
    for grandchild in child:
      if grandchild.tag.find('time') != -1:
        Time = grandchild.text
      if grandchild.tag.find('name') != -1:
        Name = grandchild.text
        Num = int(Name[9:])

    # Print out what we found
    print('Name = ' + str(Name))
    print('Num  = ' + str(Num))
    print('Lat  = ' + str(Lat)) 
    print('Lon  = ' + str(Lon)) 
    print('Ele  = ' + str(3.26*Ele))
    print('Time = ' + str(Time))
    print('')
           
    # Create a tuple 
    Wpt = (Num, Time, Lat, Lon, Ele)
    WptArr.append(Wpt)

  # Break for testing 
  #if wptNum > 10:
  #  break

# Now sort the tuple
WptArrSort=sorted(WptArr, key=lambda wpt: wpt[1])

# Figure out the day number
FirstDay  = 0
DayNumArr = []
for WptTup in WptArrSort:
  Date = WptTup[1]
  # Get the after subtracting a UTC time
  if (Date.find('.') != -1):
    Date, frac = Date.split('.')
    dt=datetime.strptime(Date, "%Y-%m-%dT%H:%M:%S")
  else:
    dt=datetime.strptime(Date, "%Y-%m-%dT%H:%M:%SZ")
  dt=dt-timedelta(hours=UTCSub)
  if (FirstDay == 0):
    FirstDay = dt.day
  DayNum = dt.day - FirstDay + 1  
  DayNumArr.append(DayNum)

# Save the file with a different name
if FileName.find('.xml') != -1:
  FileBase = FileName[0:FileName.find('.xml')]
  NewFileName = FileBase + 'WithElevation.xml'
else:
  FileBase = FileName[0:FileName.find('.GPX')]
  NewFileName = FileBase + 'WithElevation.GPX'

# Indicate we are writing the new file
print('Writing sorted waypoints array to file : ' + NewFileName)

# Open the new file and write to it
ind = 0
F = open(NewFileName,'w')
F.write(XMLHeader1)
F.write(XMLHeader2)
F.write('\n')

for WptTup in WptArrSort:
  F.write('<wpt lat="'+str(WptTup[2]) + '" lon="'+str(WptTup[3])+'">\n')
  F.write('  <ele>'+str(3.26*WptTup[4])+'</ele>\n')
  F.write('  <cmt>Day '+str(DayNumArr[ind])+'</cmt>\n')
  F.write('  <time>'+WptTup[1]+'</time>\n')
  F.write('  <name>'+str(WptTup[0])+'</name>\n')
  F.write('</wpt>\n\n')
  ind+=1
F.write('</gpx>')
F.close()
print('Finished writing file.')
