# -*- coding: utf-8 -*-
"""
Created on Wed Jul 29 13:58:24 2015
v 2017-Nov-11

@author: Jacob Hedelius
"""
#!/bin/python
# Filename readzenofiles.py

__author__ = 'Jacob Hedelius'

def readzenofiles(filename):
    
    
    # This function is meant to read in zeno files in their various formats and write 
    # them to a "structure"/dictionary
    
    # example data
    #ex_filename = 'C:\\Users\\Jacob Hedelius\\Documents\\Research\\python\\example_data\\cn_cmb_zeno.zno'
    #ex_filename = 'pl_cmb_zeno.zno'
    #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()
    
    # 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|\t|^M| ]+', file_lines[i1]) #splits line
        line_cln = list(filter(None, line_i1)) #remove empties
        
        line_digs = np.zeros([len(line_cln),1])
        line_digs[:] = np.NAN
        i2 = 0
        for field_i1 in line_cln:
            line_digs[i2] = egs.is_number(field_i1)
            i2 = i2+1
        
        if line_digs[0] == 1:
            data_check[i1] = 1
            
        
        i1 = i1+1
        if i1 > rws_num:
            i1a = i1 - rws_num
        else:
            i1a = i1        
            
    header_pre = re.split('[,|/|:|\n|\r|\t|^M| ]+', file_lines[i1a-1])
    header = list(filter(None, header_pre))
    
    out = {'filename': filename}
    out['header'] = header
    
    if i1a >= 1:
        info = file_lines[0:(i1a-1)]
    
    out['info'] = info
    
    
    
    
    bitind = -99
    UDind = -1
    UTind = -1
    CDind = -1
    CTind = -1
    try: bitind = header.index('Bit'); #note, "Bit may contain strings. Finds what column it's in
    except(ValueError): pass  #if no "Bit" header, passes
    try: UDind = header.index('UTCDate'); #finding if UTCDate header exists and where
    except(ValueError): pass  
    try: UTind = header.index('UTCTime'); #finding if UTCTime header exists and where
    except(ValueError): pass
    try: CDind = header.index('CompDate'); #finding if UTCDate header exists and where
    except(ValueError): pass  
    try: CTind = header.index('CompTime'); #finding if UTCTime header exists and where
    except(ValueError): pass 
    
    if np.all((UDind < bitind, UDind!=-1)):
        bitind = bitind + 2
    if np.all((UTind < bitind, UTind!=-1)):
        bitind = bitind + 2
    if np.all((CDind < bitind, CDind!=-1)):
        bitind = bitind + 2
    if np.all((CTind < bitind, CTind!=-1)):
        bitind = bitind + 2
    
    
        
    utc_lcl = 0 #default is neither
    if np.all((CDind>-1,CTind>-1)): #if computer time is avaliable (first choice)
      utc_lcl=2 #local
    elif np.all((UDind>-1,UTind>-1)):
      utc_lcl=1 #utc
    
    
    
    #if header[-1] == 'Bit': #note, "Bit" may contain strings
    #    biton = 1
    #else:
    #    biton = 0
    
    # pre-allocate arrays.  Currently NOT the best because pre-allocating as zeros and not NANs
    empt_ary = np.zeros([len(file_lines)-i1a,1])
    empt_ary[:] = np.NaN
    data_array = {'Pout': empt_ary, 'utc_lcl': utc_lcl}
    for header_i1 in header:
        if np.any((header_i1 == 'CompDate', header_i1 == 'UTCDate')):
            data_array['year'] = np.zeros([len(file_lines)-i1a,1])
            data_array['month'] = np.zeros([len(file_lines)-i1a,1])
            data_array['day'] = np.zeros([len(file_lines)-i1a,1])
        elif np.any((header_i1 == 'CompTime', header_i1 == 'UTCTime')):
            data_array['hour'] = np.zeros([len(file_lines)-i1a,1])
            data_array['min'] = np.zeros([len(file_lines)-i1a,1])
            data_array['sec'] = np.zeros([len(file_lines)-i1a,1])
        elif header_i1 == 'Bit':
            data_array[header_i1] = [None] * (len(file_lines)-i1a) #pre-allocate as list, not array
        else:
            data_array[header_i1] = np.zeros([len(file_lines)-i1a,1])
    
    
    # loop through and save data    
    lpi1 = 0
    i1 = 0
    for line_i1 in file_lines:
        if lpi1 >= i1a: #not header
            
            line_sptp = re.split('[,|/|:|\n|\r|\t|^M| ]+', line_i1)
            line_spt = list(filter(None, line_sptp))
        
            if bitind < -1:
                line_flt = [float(x) for x in line_spt]
            elif bitind >= 0:
                bit_i1 = line_spt[bitind] #saves Bit value
    #                line_fltp = line_spt[0:-1]
                line_flt = [egs.flt_or_str(x) for x in line_spt]
            
            i2 = 0
            for header_i1 in header: #write individual fields
                if np.any(( np.all((header_i1=='CompDate',utc_lcl==2)), np.all((header_i1=='UTCDate',utc_lcl==1)) )):
                    if line_flt[i2] < 100:
                        data_array['year'][i1] = line_flt[i2] + 2000
                    else:
                        data_array['year'][i1] = line_flt[i2]
                    data_array['month'][i1] = line_flt[i2+1]
                    data_array['day'][i1] = line_flt[i2+2]
                    i2 = i2 + 2
                elif np.any((np.all((header_i1=='CompTime',utc_lcl==2)), np.all((header_i1=='UTCTime',utc_lcl==1)) )):
                    data_array['hour'][i1] = line_flt[i2]
                    data_array['min'][i1] = line_flt[i2+1]
                    data_array['sec'][i1] = line_flt[i2+2]
                    i2 = i2 + 2
                elif header_i1 == 'Bit':
                    data_array[header_i1][i1] = bit_i1
                else: #everything else...
                    data_array[header_i1][i1] = line_flt[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...







