#!/usr/bin/python
#import geocoding_for_kml
import csv
import xml.dom.minidom
import sys
import re
debug = 0

#def extractAddress(row):
#  # This extracts an address from a row and returns it as a string. This requires knowing
#  # ahead of time what the columns are that hold the address information.
#  return '%s,%s,%s,%s,%s' % (row['Address1'], row['Address2'], row['City'], row['State'], row['Zip'])

def pesGenCoord(gps):
  # m = re.search('(?<=abc)def', 'abcdef')
  # "S25 32 30.7 E27 11 04.2"
  #\s(d+)\sE(\d+)\s(\d+)\s(\d+)
  m = re.split("(\S)(\d+)\s(\d+)\s(\d+.\d)\s(\S)(\d+)\s(\d+)\s(\d+.\d).*", gps)
  s = 0.0
  e = 0.0
  if len(m) == 10 : #e.g. m= ['', 'S', '25', '41', '23.1', 'E', '27', '36', '46.2', '']
     s = float(m[2])+ (float(m[3])+float(m[4])/60)/60
     e = float(m[6])+ (float(m[7])+float(m[8])/60)/60
     if m[1] == "S" or m[1] == "s":
        s = -s    
     if m[5] == "W" or m[5] == "w":
        e = -e
     #print "m=",m," gps=",gps," len(m)=",len(m),"s=%10.4f  e=%10.4f, 0" % (s,e)
     return "%10.4f, %10.4f, 0" % (e,s)
  return "0"

def createPlacemark(kmlDoc, row, order):
  # This creates a <Placemark> element for a row of data.
  # A row is a dict.
  placemarkElement = kmlDoc.createElement('Placemark')
  ppc = kmlDoc.createTextNode( row["from"])
  ppe = kmlDoc.createElement('name')
  ppe.appendChild(ppc)
  placemarkElement.appendChild(ppe)
  #placemarkElement.appendChild(kmlDoc.createElement('nameXX').appendChild( ))
  extElement = kmlDoc.createElement('ExtendedData')
  placemarkElement.appendChild(extElement)
  
  # Loop through the columns and create a <Data> element for every field that has a value.
  for key in order:
    if row[key] and not (key == "x"):  ##Skip fields marked "x"
      dataElement = kmlDoc.createElement('Data')
      dataElement.setAttribute('name', key)
      valueElement = kmlDoc.createElement('value')
      dataElement.appendChild(valueElement)
      valueText = kmlDoc.createTextNode(row[key])
      valueElement.appendChild(valueText)
      extElement.appendChild(dataElement)
  
  pointElement = kmlDoc.createElement('Point')
  placemarkElement.appendChild(pointElement)
  #coordinates = geocoding_for_kml.geocode(extractAddress(row))
  coordinates = row['gps'] #fixed during pesReadFile
  coorElement = kmlDoc.createElement('coordinates')
  coorElement.appendChild(kmlDoc.createTextNode(coordinates))
  pointElement.appendChild(coorElement)
  if coordinates == "0":
    print " skip dud .."
    return "0"
  if debug > 2: print coordinates
  return placemarkElement

def createLink(kmlDoc, data, name):
  # This creates a <LineString> element for a row of data.
  # A data is a list(dict).
  if len(data) <> 2:
    print "Error Link data wrong data=",data
    return 0
    sys.exit(1)
  placemarkElement = kmlDoc.createElement('Placemark')
  ppc = kmlDoc.createTextNode( name )
  ppe = kmlDoc.createElement('name')
  ppe.appendChild(ppc)
  placemarkElement.appendChild(ppe)
  #placemarkElement.appendChild(kmlDoc.createElement('nameXX').appendChild( ))
  extElement = kmlDoc.createElement('LineString')
  placemarkElement.appendChild(extElement)
  
  # Loop through the columns and create a <Data> element for every field that has a value.
  coordinates = ""
  for place in data:
      coordinates += place[1]
  if len(coordinates) > 1:
      dataElement = kmlDoc.createElement('coordinates')
      valueText = kmlDoc.createTextNode(coordinates)
      dataElement.appendChild(valueText)
      extElement.appendChild(dataElement)
  
  #coorElement = kmlDoc.createElement('coordinates')
  #coorElement.appendChild(kmlDoc.createTextNode(coordinates))
  #extElement.appendChild(coorElement)
  #print "Line extElement=",extElement 
  return placemarkElement

def pesReadFile(csvReader,order):
  ''' Read csv file
    expect following fields.
    gps, to, from  to create links'''
  d_points = {}
  d_links = {}
  linenum=0
  skipstrnum =""
  skipstr=""
  for row in csvReader:
    linenum += 1
    gps = pesGenCoord(row['gps'])  ##Correct gps string format.
    if not gps == "0":  ##Skip if no Coord
      name_from = row['from']
      name_to = row['to']
      row['gps'] = gps ##Set to correct format.
      d_points[name_from] = dict(row)  ##will give error on duplicate from
      #print "d_points[name_from]=",d_points[name_from]
      #for key in order:
        #if row[key]:
          #d_points.append(key : row[key])
      #now links
      if name_from > name_to:
        name_link = name_from +"-"+ name_to
      else:
        name_link = name_to +"-"+ name_from
      #Had to eventualy had to add a list of list to dict.
      d_links.setdefault(name_link.strip(),[]).append( [name_from , gps] ) 
      #d_links[name_link.strip()] = {name_from : gps} #Dict of combined name with dict of gps. 
    else:
      if row == skipstr:
        skipstrnum = "".join((skipstrnum," ",str(linenum))) #dont print duplicates
      else:
        if skipstrnum == "":
          print "Skip line",linenum,row
          skipstr = row
        else:
          print "same lines",skipstrnum
          skipstrnum = ""
          skipstr = ""
  if not skipstrnum == "":
      print "same lines",skipstrnum
  #print d_links
  return d_points,d_links


def createKML(d_points,d_links, fileName, order, iconmap):
  # This constructs the KML document from the CSV file.
  kmlDoc = xml.dom.minidom.Document()
  
  kmlElement = kmlDoc.createElementNS('http://earth.google.com/kml/2.2', 'kml')
  kmlElement.setAttribute('xmlns', 'http://earth.google.com/kml/2.2')
  kmlElement = kmlDoc.appendChild(kmlElement)
  documentElement = kmlDoc.createElement('Document')
  documentElement = kmlElement.appendChild(documentElement)

  # Skip the header line.
  #csvReader.next()
  for name_from in d_points:
       row = d_points[name_from]  
       #print "row=",row     
       placemarkElement = createPlacemark(kmlDoc, row, order)
       documentElement.appendChild(placemarkElement)
  for name_link in d_links:
       linkElement = createLink(kmlDoc, d_links[name_link], name_link)
       if linkElement: documentElement.appendChild(linkElement)

  kmlFile = open(fileName, 'w')
  kmlFile.write(kmlDoc.toprettyxml('  ', newl = '\n', encoding = 'utf-8'))

def pesGetOrder(fname):
  count = 0 #loop through first 2 lines
  file = csv.reader(open(fname))
  while count < 3:
    count += 1
    found = 0
    firstline = file.next()
    order = []
    #replace header with standard names.
    match = { "gps":"gps", "GPS":"gps", 
              "Site Name":"from","Site Description":"from", 
              "Remote Name":"to","Remote Description":"to" }
    for row in firstline:
       colname = row
       for word in match.keys():
          if len(row) and (row.find(word)>-1): 
	    colname = match[word]
            found += 1
            print 'found word="%s"in colname="%s" at="%s" replaced with "%s"' % (word,row,row.find(word),colname)
            break
       order.append(colname)
       
    if found > 2: count = 3 ##We got a header
    print "order=",order
  return order

def main():
  # This reader opens up 'google-addresses.csv', which should be replaced with your own.
  # It creates a KML file called 'google.kml'.
  
  # If an argument was passed to the script, it splits the argument on a comma
  # and uses the resulting list to specify an order for when columns get added.
  # Otherwise, it defaults to the order used in the sample.
  #filename="WelkomRegionalRadioConfigs"
  filename="RustenburgRad"
  filein ="".join((filename,".csv"))
  fileout="".join((filename,".kml"))
  iconmap={ "bank":"#msn_euro", "Shaft":"#msn_S", "Mast":"#msn_M" }
  #<styleUrl>#msn_euro</styleUrl>
  print "len(sys.argv)",len(sys.argv)
  if len(sys.argv) >1:
     filein = sys.argv[1].split('.')[0]
     print "filein=",filein,"  in +.csv  out +.kml"
     filein ="".join((filename,".csv"))
     fileout="".join((filename,".kml"))
     ##order = ['from','to','brtype','ip','gps','distance']
     #  order = ['from','to','Freq','SSID','brtype','ip','x','x','x','RadType','SN','Dist','x','gps','distance']
     order = pesGetOrder(filein) ## try and match header and gps to from col.
  csvreader = csv.DictReader(open(filein),order)
  d_points,d_links = pesReadFile(csvreader,order)
  kml = createKML(d_points,d_links, fileout, order , iconmap)
  print "Done.",fileout

if __name__ == '__main__':
  main()
