# -*- coding: utf-8 -*-
"""
Created on Thu Oct 20 17:48:05 2016

@author: Jacob Hedelius

v - 2016-10-21
"""

# import modules
import os
import warnings as warn
import numpy as np
curr_dir = os.getcwd()
os.chdir('../../python_subs')
import egi_subs as egs
os.chdir(curr_dir)



def findclosestdaily_n(x_vec, ind, n):
# findclosest
# supposed to find the closest n values of X elements in search index IND
# inputs should be vectors (indexing X to IND)
# This assumes that the inputs are in serial (matlab-type) dates and that 
# we are searching for closest indicies on a DAILY basis

## test values

#n = 3
#x_vec = [736621.15, 736621.35, 736622.15, 736622.55, 736624]
#ind = [736621.1, 736621.2, 736621.3, 736621.4, 736621.5, 736621.6, 736621.7, \
#     736622.1, 736622.2, 736622.3, 736622.4, 736622.5, 736622.6, 736622.7]

    
    # convert IND and x_vec to np arrays
    x_vec_np = np.array(x_vec)
    ind_np = np.array(ind)
    
    if type(n).__name__ != 'int':  # quick check to see that n is an integer
        print('n is NOT int')
    
    start_day = np.min(np.floor(x_vec))
    end_day = np.max(np.floor(x_vec))
    date_list = egs.frange(start_day, end_day+0.5) #list of dates
    
    n = np.min([n, len(ind_np)])  # if n is larger than the size of the index, n is set to the index length
    closest_indx = np.zeros([len(x_vec), n])  # pre-allocation for speed
    closest_indx_value = np.zeros([len(x_vec), n])  # pafs
    closest_indx_diff = np.zeros([len(x_vec), n])   # pafs
    
    # loop through each day
    se_i2 = np.array([0, 0]) #starting and ending indexes
    warn_emptyday=0
    for day_i2 in date_list: #for each date
        Xday = x_vec_np[np.floor(x_vec) == day_i2] #x-values for day
        ind_INDday = egs.find(np.floor(ind_np) == day_i2) #creates a numerical index
        INDday = ind_np[ind_INDday] #index values for given day
        
        if len(Xday)!=0:
            day_ind = egs.nan_ary([len(Xday),n]) #pre-allocating for speed, 
            day_indx_value = egs.nan_ary([len(Xday),n]) #pafs
            day_indx_diff = egs.nan_ary([len(Xday),n]) #pafs
            
            if len(INDday)!=0: #if there is both X and IND data for loop day
                
                day_n = min([n, len(INDday)]) #number of matches saved per day
                i1 = -1
                for Xday_i1 in Xday: #for every time point in day
                    i1 += 1 #increase iteration by 1
                    diff_vals = Xday_i1 - INDday # differences for all points
                    abs_diffs = np.absolute(diff_vals)
                    sortIND = np.argsort(abs_diffs,0)
                    day_indx_diff[i1, 0:day_n] = diff_vals[sortIND[0:day_n]]
                    day_ind[i1, 0:day_n] = np.array(ind_INDday)[ sortIND[0:day_n]]
                    day_indx_value[i1, 0:day_n] = np.array(INDday)[sortIND[0:day_n]]
                
            elif len(Xday)!=0: #data for Xday, but no index data
                if warn_emptyday !=1:
                    warn_emptyday=1
                    warn.warn('Some of the input X days do not have matching index days. Look for NaNs, setting to 1')
                    
                
                #default values of day_ind, day_ind, day_indx_value, day_indx_diff are NaNs
            
            se_i2[1] = se_i2[1] + len(Xday)
            closest_indx_diff[se_i2[0]:se_i2[1],:] = day_indx_diff #save to main vector
            closest_indx[se_i2[0]:se_i2[1],:]     = day_ind
            closest_indx_value[se_i2[0]:se_i2[1],:] = day_indx_value
            se_i2[0] = se_i2[1]
    
    
    #out = []
    #out.append({'closest_ind': closest_indx, 'closest_ind_diff': closest_indx_diff, 'closest_ind_val': closest_indx_value})
    out = {'closest_ind': closest_indx, 'closest_ind_diff': closest_indx_diff, 'closest_ind_val': closest_indx_value}
    #return closest_indx, closest_indx_diff, closest_indx_value
    return out

       


