from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals





# low level methods
def coordinate_in_path(latitude,longitude, p):

    return p.contains_points([(latitude,longitude)])[0]

class InvalidTrajectoryError(Exception):
    def __init__(self,value):
        self.value=value

    def __str__(self):
        return repr(self.value)

def time_in_path(df,p,maxmin='max',getall=False):

    if df.empty:
        return 0

    latitude = df.latitude
    longitude = df.longitude

    f = lambda x: coordinate_in_path(x['latitude'],x['longitude'],p)

    df['inpolygon'] = df.apply(f,axis=1)

    if maxmin=='max':
        b = (~df['inpolygon']).shift(-1)+df['inpolygon']
    else:
        b = (~df['inpolygon']).shift(1)+df['inpolygon']


    if len(df[b==2]):
        if getall:
            return df[b==2]['time'],df[b==2]['cum_dist']
        else:
            return df[b==2]['time'].min(),df[b==2]['cum_dist'].min()

    raise InvalidTrajectoryError("Trajectory doesn't go through path")


    return 0


def coursetime_first(data,paths):

    entrytime = data['time'].max()
    entrydistance = data['cum_dist'].max()
    coursecompleted = False

    try:
        entrytime,entrydistance = time_in_path(data,paths[0],maxmin='max')
        coursecompleted = True
    except InvalidTrajectoryError:
        entrytime = data['time'].max()
        entrydistance = data['cum_dist'].max()
        coursecompleted = False
    return entrytime, entrydistance, coursecompleted

def coursetime_paths(data,paths,finalmaxmin='min'):

    entrytime = data['time'].max()
    entrydistance = data['cum_dist'].max()
    coursecompleted = False

    # corner case - empty list of paths
    if len(paths) == 0:
        return 0,True

    # end - just the Finish polygon
    if len(paths) == 1:
        try:
            (
                entrytime,
                entrydistance
            ) = time_in_path(data,paths[0],maxmin=finalmaxmin)
            coursecompleted = True
        except InvalidTrajectoryError:
            entrytime = data['time'].max()
            entrydistance = data['cum_dist'].max()
            coursecompleted = False
        return entrytime,entrydistance,coursecompleted

    if len(paths) > 1:
        try:
            time,dist = time_in_path(data, paths[0])
            data = data[data['time']>time]
            data['time'] = data['time']-time
            data['cum_dist'] = data['cum_dist']-dist
            (
                timenext,
                distnext,
                coursecompleted
                ) = coursetime_paths(data,paths[1:])
            return time+timenext, dist+distnext,coursecompleted
        except InvalidTrajectoryError:
            entrytime = data['time'].max()
            entrydistance = data['cum_dist'].max()
            coursecompleted = False

    return entrytime, entrydistance, coursecompleted
