# -*- coding: utf-8 -*-
"""
Created on Fri Jul 31 16:31:36 2015

@author: Jacob Hedelius
"""

#!/bin/python
# Filename readzenofiles.py
# v - 2017-Nov-11 - JKH

__author__ = 'Jacob Hedelius'

def readusbgpsfiles(filename):


    # This function is meant to read in USB GPS files.  THis reader is specialized
    # for these formats and writes outputs to a
    # them to a "structure"/dictionary
    
    # example data
    #ex_filename = 'C:\\Users\\Jacob Hedelius\\Documents\\Research\\python\\example_data\\20141007_00_mnGPS.txt'
    #filename = ex_filename
    
    # import packages
    import numpy as np
    import re
    import egi_subs as egs
    
    # read in file
    fobj = open(filename, 'r') # gets file object for reading
    file_lines = fobj.readlines() #reads in entire file all at once, line by line
    fobj.close() #closes open file
    
    # initialize while loop
    data_check = np.zeros([20, 1]) #check vector, assumes there won't be more than 20 lines of header
    # NOTE: for your data files the first column needs be numbers
    i1 = 0
    i1a = 1
    rws_num = 10 #required number of rows with numbers (in a row) to be accepted as non-header
    while np.sum(data_check[i1a:i1]) != rws_num:
    
        line_i1 = re.split('[,|/|:|\n|^M| ]+', file_lines[i1]) #splits line based on delimiters
        line_cln = list(filter(None, line_i1)) #remove empties
        
        line_digs = np.zeros([len(line_cln),1]) #pre-allocating
        line_digs[:] = np.NAN #pre-allocating
        i2 = 0
        for field_i1 in line_cln: #checking if fields are numbers
            line_digs[i2] = egs.is_number(field_i1)
            i2 = i2+1
        
        if line_digs[0] == 1: #if first field is a number
            data_check[i1] = 1
        
        i1 = i1+1
        if i1 > rws_num:
            i1a = i1 - rws_num
        else:
            i1a = i1
    
    header_pre = re.split('[,|/|:|\n|^M| ]+', file_lines[i1a-1]) #preparing header
    header = list(filter(None, header_pre))
    
    out = {'filename': filename}
    out['header'] = header
    
    if i1a >= 1:
        info = file_lines[0:(i1a-1)]
    
    out['info'] = info
    # determine if columns are all digits or not
    
    dig_or_str = np.zeros([len(file_lines)-i1a,len(line_digs)]) #pre-allocating "logic" vector if values are strings or digits
    lpi1 = 0
    i1 = 0
    for line_i1 in file_lines:
        if lpi1 >= i1a: #not header
            line_i1_spt = re.split('[,|/|:|\n|^M| ]+', line_i1) #splits line based on delimiters
            line_cln = list(filter(None, line_i1_spt)) #remove empties
            i2 = 0
            for field_i1 in line_cln: #checking if fields are numbers
                dig_or_str[i1][i2] = np.invert(egs.is_number(field_i1)) #0 if number, 1 otherwise
                i2 = i2+1
            
            i1 = i1 + 1
        
        lpi1 = lpi1 + 1
    
    tot_col_ds = sum(dig_or_str) # 0 if entire column is digits, or some number otherwise
    
    
      
    utc_lcl = 0 #default is neither
    if all(cfld in header for cfld in ['CompDate', 'CompTime']): #if computer time is avaliable (first choice)
      utc_lcl=2 #local
    elif np.any(( all(cfld in header for cfld in ['GPSUTCDate', 'GPSUTCTime']), all(cfld in header for cfld in ['UTCDate', 'UTCTime']) )):
      utc_lcl=1 #utc
    
    
    
    # pre-allocation of lists and arrays.  Pre-allocation is important in this case
    # as it will help in converting elements to float as appropriate
    
    empt_ary = np.zeros([len(file_lines)-i1a,1])
    empt_ary[:] = np.NaN
    data_array = {'Lat': empt_ary, 'utc_lcl': utc_lcl}
    i2 = 0
    for header_i1 in header:
        if np.any((header_i1=='GPSUTCDate', header_i1=='UTCDate', header_i1=='CompDate')): #Date
            if np.any((header_i1=='GPSUTCDate', header_i1=='UTCDate')):
               pre_UC = 'U' #utc time
            elif header_i1=='CompDate': #comp time
               pre_UC = 'C' #utc time
            data_array[pre_UC + 'year'] = np.zeros([len(file_lines)-i1a,1])
            data_array[pre_UC + 'month'] = np.zeros([len(file_lines)-i1a,1])
            data_array[pre_UC + 'day'] = np.zeros([len(file_lines)-i1a,1])
            i2 = i2 + 2
        elif np.any((header_i1 == 'UTCTime', header_i1 == 'GPSUTCTime', header_i1=='CompTime')):
            if np.any((header_i1=='GPSUTCTime', header_i1=='UTCTime')):
                pre_UC = 'U' #utc time
            elif header_i1=='CompTime': #comp time
                pre_UC = 'C' #utc time
            data_array[pre_UC + 'hour'] = np.zeros([len(file_lines)-i1a,1])
            data_array[pre_UC + 'min'] = np.zeros([len(file_lines)-i1a,1])
            data_array[pre_UC + 'sec'] = np.zeros([len(file_lines)-i1a,1])
            i2 = i2 + 2
        elif tot_col_ds[i2] > 0: #strings, pre-allocating list
            data_array[header_i1] = [''] * (len(file_lines)-i1a)
        else: #all digits, pre-allocating array
            data_array[header_i1] = np.zeros([len(file_lines)-i1a,1])
        
        i2 = i2 + 1
    
    
    # loop through file, line by line
    lpi1 = 0
    i1 = 0
    for line_i1 in file_lines:
        if lpi1 >= i1a: #not header
            line_i1_spt = re.split('[,|/|:|\n|^M| ]+', line_i1) #splits line based on delimiters
            line_cln = list(filter(None, line_i1_spt)) #remove empties
            i2 = 0
            for header_i1 in header: #checking if fields are numbers
                if np.any((header_i1=='GPSUTCDate', header_i1=='UTCDate', header_i1=='CompDate')): #Date
                    if np.any((header_i1=='GPSUTCDate', header_i1=='UTCDate')):
                       pre_UC = 'U' #utc time
                    elif header_i1=='CompDate': #comp time
                       pre_UC = 'C' #utc time
                    yflt = float(line_cln[i2])
                    if yflt < 100:
                        data_array[pre_UC + 'year'][i1] = yflt + 2000
                    else:
                        data_array[pre_UC + 'year'][i1] = yflt
                    data_array[pre_UC + 'month'][i1] = line_cln[i2+1]
                    data_array[pre_UC + 'day'][i1] = line_cln[i2+2]
                    i2 = i2 + 2
                elif np.any((header_i1=='GPSUTCTime', header_i1=='UTCTime', header_i1=='CompTime')):
                    if np.any((header_i1=='GPSUTCTime', header_i1=='UTCTime')):
                       pre_UC = 'U' #utc time
                    elif header_i1=='CompTime': #comp time
                       pre_UC = 'C' #utc time
                    data_array[pre_UC + 'hour'][i1] = line_cln[i2]
                    data_array[pre_UC + 'min'][i1] = line_cln[i2+1]
                    data_array[pre_UC + 'sec'][i1] = line_cln[i2+2]
                    i2 = i2 + 2
                else:
                    data_array[header_i1][i1] = line_cln[i2]
                
                i2 = i2+1
            
            i1 = i1 + 1
        
        lpi1 = lpi1 + 1
      
    
    
    
    for param_i1 in data_array:
        out[param_i1] =  data_array[param_i1]
    
    
    return out
    
    ## may consider some sort of check at the end to ensure file was read in correctly...
    
    
