# find-image-by-location.py - given an image file determine if it was taken within a certain radius of a place in the world
# kristinm and charliep (over the past couple of years)

# dependencies:
#   pip install geopy (only for vincenty?)
#   pip install vincenty (older versions of geopy seem to include vincenty, later ones do not)
#   exiftool - https://exiftool.org/index.html or yum install -y perl-Image-ExifTool

# testing data:
#   house foundation, POI 23 or so 65.29051, -13.69886 0.03 km
#   downtown = 65.259849, -14.010116
#   gas station-ish = 65.265375, -13.992487

# to do:
#   pylint
#   check /c/fs for "error" 
#   TIF support?
#   refactor to use Python exiv2 library to do the extract, using the Perl exiftool via parsed CSV is very brittle

#   provide a directory interface where it will look at all upper(DNG, PNG, JPG) files therein
#   less or more than a certain altitude (relative and absolute), range 
#   date taken, range
#   by country taken in
#   move all the display to main()

# DNG and JPG 19
    # GPSLongitude = fields[8]
    # GPSAltitude = fields[9]
    # AbsoluteAltitude = fields[10]
    # RelativeAltitude = fields[11]
    # GimbalYawDegree = fields[12]
    # FlightYawDegree = fields[13]
    # Yaw = fields[14]
    # CameraYaw = fields[15]
    # CameraPitch = fields[16]
    # CameraRoll = fields[17]
    # FocalLength35mm = fields[18]

import sys
import os
import argparse 
import mappingTools as mt

debug = False

def filterByLocation(filePath, latitudeOrigin, longitudeOrigin, radius):
    filePath = filePath.replace(" ", "\\ ")
    (root, extension) = os.path.splitext(filePath)

    command = 'exiftool -csv -coordFormat "%.6f" -Filename -Directory -CreateDate -GPSLatitudeRef -GPSLongitudeRef -GPSAltitudeRef -GPSLatitude -GPSLongitude  -GPSAltitude -AbsoluteAltitude -RelativeAltitude -GimbalYawDegree -FlightYawDegree -Yaw -CameraYaw -CameraPitch -CameraRoll -FocalLengthIn35mmFormat ' + filePath
    
    output = os.popen(command, 'r').read()
    lines = output.splitlines()
    fields = lines[1].split(',')

    if debug:
        print('len(fields):', len(fields), 'extension:', extension, 'filename:', filename)
        print("fields:", fields)
        print("")

    if (extension.upper() == '.PNG') and len(fields) < 8:
        if debug:
            print('skipping, PNG with < 8 fields:', len(fields), fields[1])
        return

    elif (extension.upper() == '.PNG') and len(fields) == 8:
        if debug:
            print('will process', len(fields), fields[1], fields[3:])

    elif (extension.upper() == '.PNG') and len(fields) == 10:
        if debug:
            print('will process', len(fields), fields[1], fields[3:])

    elif (extension.upper() == '.PNG') and len(fields) == 11:
        if debug:
            print('will process', len(fields), fields[1], fields[3:])


    elif (extension.upper() == '.JPG') and len(fields) < 9:
        if debug:
            print('skipping, JPG with < 9 fields:', len(fields), fields[1])
        return

    elif (extension.upper() == '.JPG') and len(fields) == 9:
        if debug:
            print('will process', len(fields), fields[1], fields[3:])

    elif (extension.upper() == '.JPG') and len(fields) == 10:
        if debug:
            print('will process', len(fields), fields[1], fields[3:])

    elif (extension.upper() == '.JPG') and len(fields) == 11:
        if debug:
            print('will process', len(fields), fields[1], fields[3:])

    elif (extension.upper() == '.JPG') and len(fields) == 15:
        if debug:
            print('will process', len(fields), fields[1], fields[3:])

    elif (extension.upper() == '.JPG') and len(fields) == 19:
        if debug:
            print('will process', len(fields), fields[1], fields[3:])


    elif (extension.upper() == '.DNG') and len(fields) < 19:
        if debug:
            print('skipping, DNG with < 19 fields:', len(fields), fields[1])
        return

    elif (extension.upper() == '.DNG') and len(fields) == 19:
        if debug:
            print('will process', len(fields), fields[1], fields[3:])

    else:
        print('error, unknown filetype/EXIF structure', len(fields), extension, fields, file=sys.stderr)
        return 

    # PNG
    if (extension.upper() == '.PNG') and len(fields) == 8:
        SourceFile = fields[0]
        CreateDate = fields[3]
        GPSLatitudeRef = fields[4]
        GPSLongitudeRef = fields[5]
        GPSLatitude = fields[6]
        GPSLongitude = fields[7]
    
        print('PNG', len(fields), SourceFile, CreateDate, GPSLatitudeRef, GPSLongitudeRef, GPSLatitude, GPSLongitude)

    elif (extension.upper() == '.PNG') and (len(fields) == 10 or len(fields) == 11):
        SourceFile = fields[0]
        CreateDate = fields[3]
        GPSLatitudeRef = fields[4]
        GPSLongitudeRef = fields[5]
        GPSLatitude = fields[7]
        GPSLongitude = fields[8]

        print('PNG', len(fields), SourceFile, CreateDate, GPSLatitudeRef, GPSLongitudeRef, GPSLatitude, GPSLongitude)

    # JPG
    elif (extension.upper() == '.JPG') and len(fields) == 9:
        SourceFile = fields[0]
        CreateDate = fields[3]
        GPSLatitudeRef = fields[4]
        GPSLongitudeRef = fields[5]
        GPSLatitude = fields[6]
        GPSLongitude = fields[7]

        print('JPG', len(fields), SourceFile, CreateDate, GPSLatitudeRef, GPSLongitudeRef, GPSLatitude, GPSLongitude)

    elif (extension.upper() == '.JPG') and (len(fields) == 10 or len(fields) == 11 or len(fields) == 15 or len(fields) == 19):
        SourceFile = fields[0]
        CreateDate = fields[3]
        GPSLatitudeRef = fields[4]
        GPSLongitudeRef = fields[5]
        GPSLatitude = fields[7]
        GPSLongitude = fields[8]

        print('JPG', len(fields), SourceFile, CreateDate, GPSLatitudeRef, GPSLongitudeRef, GPSLatitude, GPSLongitude)

    # DNG
    elif (extension.upper() == '.DNG') and len(fields) == 19:
        SourceFile = fields[0]
        CreateDate = fields[3]
        GPSLatitudeRef = fields[4]
        GPSLongitudeRef = fields[5]
        GPSLatitude = fields[7]
        GPSLongitude = fields[8]

        print('DNG', len(fields), SourceFile, CreateDate, GPSLatitudeRef, GPSLongitudeRef, GPSLatitude, GPSLongitude)


    else:
        print('unknown:', len(fields), fields)
        return

    GPSLat = 0.0
    GPSLon = 0.0

    GPSLat = float(GPSLatitude.split()[0])
    GPSLon = float(GPSLongitude.split()[0])

    if (GPSLatitudeRef == 'South'):
        GPSLat = GPSLat * -1.0 

    if (GPSLongitudeRef == 'West'):
        GPSLon = GPSLon * -1.0 

    distance = mt.distanceBetweenPoints(latitudeOrigin, longitudeOrigin, GPSLat, GPSLon) * mt.earthRadiusKm

    if debug:
        print('debug:', SourceFile, GPSLat, GPSLon, distance)

    if (distance <= radius):
        print('in range:', SourceFile, GPSLat, GPSLon, distance, sep = ' * * ')

    return 


if __name__=="__main__":
    parser = argparse.ArgumentParser(description='determine if an image was taken within a certain radius of a place in the world')
    parser.add_argument('-f', '--filePath', type=str, help='input file of values to hash', required=True)
    parser.add_argument('-lat', '--latitudeOrigin', type=float, help='latitude of the origin (decimal)', required=True)
    parser.add_argument('-lon', '--longitudeOrigin', type=float, help='longitude of the origin (decimal)', required=True)
    parser.add_argument('-r', '--radius', type=float, help='radius of the search zone (float, KM)', required=True)
    args = parser.parse_args()

    if not(os.path.isfile(args.filePath)):
        print("error, find-image-by-location.py,", args.filePath, "does not exist, is not readable, etc.", file=sys.stderr)
        exit(-1)

    filterByLocation(args.filePath, args.latitudeOrigin, args.longitudeOrigin, args.radius)
    
    exit(0)