'''
Version 1! Yay.

Basics:
* all distances should be in meters
* all geocodes are converted to decimals
* current root directory is uav-dump in the Iceland image folder

Still to fix or check:
* make sure all file paths are actually collected, parsed, passed, and checked
* make sure conversions between geocodes and distances are correct
* JPG vs PNG vs other file types? doesn't account for that now

Credit:
* recursive directory search thanks to https://stackoverflow.com/questions/3207219/how-to-list-all-files-of-a-directory-in-python

lat: 63.31.58 N
long: 19.22.10 W
distance: 2000

'''

from os import listdir, walk
from os.path import isfile, join
import sys
import exifread
import argparse

mypath = "/media/r10_vol/Iceland/clean"

# x is in meters, I assume we can convert to angular decimal because of the small area
def to_angular(x):
# Thanks to http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates for an overview of problems like this
	earthradius = 6371000 #meters
	r = x/earthradius
	r = r*57.296 # radians to decimal part of degrees
	return r

def get_filepaths(directory):
    """
    This function will generate the file names in a directory 
    tree by walking the tree either top-down or bottom-up. For each 
    directory in the tree rooted at directory top (including top itself), 
    it yields a 3-tuple (dirpath, dirnames, filenames).
    """
    file_paths = []  # List which will store all of the full filepaths.

    # Walk the tree.
    for root, directories, files in walk(directory):
        for filename in files:
            # Join the two strings in order to form the full filepath.
            filepath = join(root, filename)
            file_paths.append(filepath)  # Add it to the list.

    return file_paths  # Self-explanatory.

def within_some_distance(coord_to_check, coord_ref, howfar):
	if (coord_to_check[0] < coord_ref[0]+howfar and coord_to_check[0] > coord_ref[0] - howfar):
		if (coord_to_check[1] < coord_ref[1]+howfar and coord_to_check[1] > coord_ref[1] - howfar):
			return True
		else:
			return False
	else:
		return False

def convert_to_decimal(geostring):
	if debug:
		print geostring
	# clean up the geostring
	geostring = geostring.replace(", ",",")
	geostring = geostring.replace(".",",")
	geostring = geostring.strip("[")
	geostring = geostring.strip("]")
	geostring = geostring.split(",",3)
	
	if debug:
		print geostring[0] + " " + geostring[1] + " " + geostring[2]

	# convert strings to floats
	degrees = float(geostring[0])
	# parse the literal division in the geostring seconds column
	if "/" in geostring[1]:
		minutes_parse = geostring[1].split("/",2)
		minutes = float(minutes_parse[0])/float(minutes_parse[1])
	else:
		minutes = float(geostring[1])
	minutes = minutes /60

	# parse the literal division in the geostring seconds column
	if "/" in geostring[2]:
		seconds_parse = geostring[2].split("/",2)
		seconds = float(seconds_parse[0])/float(seconds_parse[1])
	else:
		seconds = float(geostring[2])
	seconds = seconds / 3600.0
	
	if debug:
		print str(degrees) + " deg " + str(minutes) + " min " + str(seconds) + " sec "

	# combine into a single number and return
	mydecimal = degrees + minutes + seconds
	
	if debug:
		print mydecimal
	
	return mydecimal

parser = argparse.ArgumentParser(description='Image Geo Search')

parser.add_argument(action="store", dest="a")
parser.add_argument(action="store", dest="b")
parser.add_argument(action="store", dest="c", type=float)
parser.add_argument("-d", action="store", dest="d", type=float)
args = parser.parse_args()

debug = args.d

ref_lat = convert_to_decimal(str(args.a))
ref_lon = convert_to_decimal(str(args.b))
distanceFrom = args.c # in meters

if debug:
	print ref_lat
	print ref_lon
	print distanceFrom

ref_coord = [ref_lat,ref_lon]

# vars to store the picture geocodes
mylatitude = 0
mylongitude = 0
mycoord = [mylatitude,mylongitude]

deg_from_ref = to_angular(distanceFrom)

# get all the files
full_file_paths = get_filepaths(mypath)

save_file = 'loc_' + str(ref_lat) + '_' + str(ref_lon) + '_'  + str(distanceFrom).replace('.','') + '.txt'
s = open(save_file, "a")
# s.write("Location: " + str(ref_coord) + "+/-" + str(distanceFrom) + "m\n")

# check the files
for file in full_file_paths:
	file = join(mypath,file)
	
	if debug:
		print file
	
	f = open(file, 'rb')
	tags = exifread.process_file(f)

	mycoord = [0,0]

	for tag in tags.keys():
		if (tag=="GPS GPSLongitude"):
			mytags = str(tags[tag])
			mylongitude = convert_to_decimal(mytags)

		if (tag=="GPS GPSLatitude" ):
			mytags = str(tags[tag])
			mylatitude = convert_to_decimal(mytags)
		mycoord = [mylatitude, mylongitude]
	
	if debug:
		print mycoord
		print ref_coord
		print deg_from_ref

	# check the coordinate and print if it's within the distance
	if within_some_distance(mycoord, ref_coord, deg_from_ref):
			s.write(file)
			s.write("\n")

s.write("\n\n")
s.close()
