#!/usr/bin/python
#
# Copyright (c) 2019 Clementine Computing LLC.
# 
# This file is part of PopuFare.
# 
# PopuFare is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# PopuFare 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 Affero General Public License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with PopuFare.  If not, see <https://www.gnu.org/licenses/>.
#

# Convert from/to different formats of GPS representations
#
# DD - decimal degree
# DMS - degree/minut/second format
# DMM - degree/decimal minute format
#

# 42.445512 -76.50726
# 42.444988 -76.506852
# 42.4444 -76.506444

# DD  example: 42.445512
# DMS example: 42 3 3
# DMM example: 42 3.1

import sys

def print_usage(fp):
  fp.write("\nusage:\n\n")
  fp.write("  convert-gps [dd|dms|dmm|dmmc][-(dd|dms|dmm|dmmc)] <gps_coord>\n\n")


infmt = ""
outfmt = "dmmc"
coord = ""


def is_float(x):
  f = False
  try:
    float(x)
    f = True
  except ValueError:
    f = False
  return f

def guess_dd_dmmc(coord):
  if not is_float(coord): return ""
  tok = coord.split(".")
  if len(tok) > 2 or len(tok)==0: return ""
  tok_i = tok[0].split("-")

  #print ">>", len(tok_i), tok_i[-1], len(tok_i[-1])

  if len(tok_i[-1]) >= 3: return "dmmc"
  return "dd"


if (len(sys.argv) < 2):
  print_usage(sys.stderr)
  sys.exit(-1)


start_idx = 1
if not is_float(sys.argv[1]):
  tok=sys.argv[1].split("-")
  if len(tok)==1:
    outfmt = tok[0]
  else:
    infmt = tok[0]
    outfmt = tok[1]
  start_idx = 2

if ((outfmt != "dd") and (outfmt != "DD") and
    (outfmt != "dms") and (outfmt != "DMS") and
    (outfmt != "dmm") and (outfmt != "DMM") and
    (outfmt != "dmmc") and (outfmt != "DMMC")):
  sys.stderr.write("output format must be one of dd, dms, dmm, dmmc\n")
  print_usage(sys.stderr)
  sys.exit(-1)

coord = []
for val in sys.argv[start_idx:]:
  coord.append(val)

if len(coord) == 1:
  if len(infmt) == 0:
    infmt = guess_dd_dmmc(coord[0])
elif len(coord) == 2:
  if is_float(coord[0]) and is_float(coord[1]):
    infmt = "dmm"
elif len(coord) == 3:
  if is_float(coord[0]) and is_float(coord[1]) and is_float(coord[2]):
    infmt = "dms"

if ((infmt != "dd") and (infmt != "DD") and
    (infmt != "dms") and (infmt != "DMS") and
    (infmt != "dmm") and (infmt != "DMM") and
    (infmt != "dmmc") and (infmt != "DMMC")):
  sys.stderr.write("input format must be one of dd, dms, dmm, dmmc\n")
  print_usage(sys.stderr)
  sys.exit(-1)

out_coord_dd = 0.0
if infmt == "dd":
  out_coord_dd = float(coord[0])
elif infmt == "dmm":
  out_coord_dd = float(coord[0]) + (float(coord[1])/60.0)
elif infmt == "dms":
  out_coord_dd = float(coord[0]) + (float(coord[1])/60.0) + (float(coord[2])/(60.0*60.0))
elif infmt == "dmmc":
  x = coord[0]
  is_neg = False
  if x[0] == '-':
    is_neg = True
    x = x[1:]
  tok = x.split(".")
  min_int_part = 0.0
  if len(tok[0][-2:])> 0:
    min_int_part = float(tok[0][-2:])
  min_rem_part = 0.0
  if (len(tok)>1):
    min_rem_part = float("0." + tok[1])
  ipart = 0.0
  if (len(tok[0][-4:-2])>0):
    ipart = float(tok[0][-4:-2])
  out_coord_dd = ipart + ((min_int_part + min_rem_part)/60.0)


out_coord = []
if outfmt == "dd":
  out_coord = [str(out_coord_dd)]
elif outfmt == "dms":
  x0 = float(int(out_coord_dd))
  x1 = float(int((out_coord_dd-x0)*60.0))
  x2 = float(int( ((out_coord_dd-x0)*60.0) - ((x1-60.0)/60.0) ))
  out_coord.append(str(x0))
  out_coord.append(str(x1))
  out_coord.append(str(x2))
elif outfmt == "dmm":
  x0 = float(int(out_coord_dd))
  x1 = float(int((out_coord_dd-x0)*60.0))
  out_coord.append(str(x0))
  out_coord.append(str(x1))
elif outfmt == "dmmc":
  x0 = float(int(out_coord_dd))
  x1 = abs(float((out_coord_dd-x0)*60.0))
  out_coord.append(str(int(x0)) + str(x1))


#print infmt, outfmt, coord, "-->", out_coord_dd, " ".join(out_coord)
print " ".join(out_coord)

