#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Oct 18 14:38:37 2016

Library to read/write .sel files for signalPlant

Ing.,Mgr. (MSc.) Jan Cimbálník
Biomedical engineering
International Clinical Research Center
St. Anne's University Hospital in Brno
Czech Republic
&
Mayo systems electrophysiology lab
Mayo Clinic
200 1st St SW
Rochester, MN
United States
"""

import re
import pandas as pd

def read_sel(file_path):
    """
    Function to read .sel file into pandas dataframe
    
    Parameters:
    -----------
    file_path - path to file\n
    
    Returns:
    --------
    sel_df - dataframe with read values\n
    channel_df - dataframe with channel_validity info\n
    data_source - name of the data source file\n
    """

    #Initiate dataframe
    sel_df = pd.DataFrame(columns=('start','stop','group','validity','ch_idx','ch_name','info'))
    channel_df = pd.DataFrame(columns=('channel_name','validity'))
    df_i = 0
    chdf_i = 0
    
    #Open the file for reading
    fid = open(file_path,'r')
    #Read the data_source
    while True:
        line_text = fid.readline()
        if re.match('%Selection export from file:',line_text):
            data_source = fid.readline()[1:-1]
        
        elif re.match('%CHANNELS_VALIDITY',line_text):
            while True:
                line_text = fid.readline()
                if re.match('%---',line_text):
                    break
                #Parse the line
                tab_pos = [m.start() for m in re.finditer('\t', line_text)]
                channel_name = line_text[1:tab_pos[0]]
                validity = line_text[tab_pos[0]+1:tab_pos[0]+2]
                
                channel_df.loc[chdf_i] = [channel_name, validity] 
                chdf_i += 1
                                    
        elif re.match('%DATA',line_text):
            while True:
                line_text = fid.readline()
                if line_text == '':
                    break
                #Parse the line
                tab_pos = [m.start() for m in re.finditer('\t', line_text)]
                event_start = int(line_text[tab_pos[0]+1:tab_pos[1]])
                event_stop = int(line_text[tab_pos[1]+1:tab_pos[2]])
                group = int(line_text[tab_pos[2]+1:tab_pos[3]])
                validity = float(line_text[tab_pos[3]+1:tab_pos[4]])
                ch_idx = int(line_text[tab_pos[4]+1:tab_pos[5]])
                ch_name = line_text[tab_pos[5]+2:tab_pos[6]]
                info = line_text[tab_pos[6]+1:-1]
    
                sel_df.loc[df_i] = [event_start, event_stop, 
                                    group, validity,
                                    ch_idx, ch_name,
                                    info]
                df_i += 1
    
        if line_text == '':
            break
        
    return sel_df, channel_df, data_source

#def read_sel(file_path): # previous version
#    """
#    Function to read .sel file into pandas dataframe
#    
#    Parameters:
#    -----------
#    file_path - path to file\n
#    
#    Returns:
#    --------
#    sel_df - dataframe with read values\n
#    data_source - name of the data source file\n
#    """
#
#    #Initiate dataframe
#    sel_df = pd.DataFrame(columns=('start','stop','group','validity','ch_idx','ch_name','info'))
#    df_i = 0
#    
#    #Open the file for reading
#    fid = open(file_path,'r')
#    #Read the data_source
#    while True:
#        line_text = fid.readline()
#        if re.match('%Selection export from file:',line_text):
#            data_source = fid.readline()[1:-1]
#        elif re.match('%DATA',line_text):
#            while True:
#                line_text = fid.readline()
#                if line_text == '':
#                    break
#                #Parse the line
#                tab_pos = [m.start() for m in re.finditer('\t', line_text)]
#                event_start = int(line_text[tab_pos[0]+1:tab_pos[1]])
#                event_stop = int(line_text[tab_pos[1]+1:tab_pos[2]])
#                group = int(line_text[tab_pos[2]+1:tab_pos[3]])
#                validity = float(line_text[tab_pos[3]+1:tab_pos[4]])
#                ch_idx = int(line_text[tab_pos[4]+1:tab_pos[5]])
#                ch_name = line_text[tab_pos[5]+2:tab_pos[6]]
#                info = line_text[tab_pos[6]+1:-1]
#
#                sel_df.loc[df_i] = [event_start, event_stop, 
#                                    group, validity,
#                                    ch_idx, ch_name,
#                                    info]
#                                    
#                df_i += 1
#    
#        if line_text == '':
#            break
#        
#        
#    return sel_df, data_source
    
def write_sel(file_path, df, fs, original_name = None):
    """
    Function to write .sel file for SignalPlant
    
    Parameters:
    -----------
    file_path - path to writhe the sel file\n
    df - dataframe with the same fields as in .sel file. compulsory fields:
         [start,stop,ch_idx,ch_name]\n
    fs - sampling frequency\n
    original_name - original file name (None = name is derived from file_name)
    
    Returns:
    --------
    0 - on success
    1 - if error
    """
    
    # Check the input
    if 'start' not in df.keys():
        print('"start" field is missing')
        return 1
    if 'stop' not in df.keys():
        print('"stop" field is missing')
        return 1
    if 'ch_idx' not in df.keys():
        print('"ch_idx" field is missing')
        return 1
    if 'ch_name' not in df.keys():
        print('"ch_name" field is missing')
        return 1
    if 'validity' not in df.keys():
        df['validity'] = 0.0
    if 'group' not in df.keys():
        df['group'] = 1
    if 'info' not in df.keys():
        df['info'] = ''
        
    if not original_name:
        sel_idx = file_path.index('.sel')
        slash_idx = file_path.rindex('/')
        file_name = file_path[slash_idx+1:sel_idx]+'.d'
    else:
        file_name = original_name

    # Add percent to channel name
    df['ch_name'] = '%'+df['ch_name']
        
    # Create and open the file
    f = open(file_path,'w')
    
    # Write initial lines
    f.write('%SignalPlant ver.:0.2.8.0\r\n')
    f.write('%Selection export from file:\r\n')
    f.write('%'+file_name+'\r\n')
    f.write('%SAMPLING_FREQ [Hz]:'+str(int(fs))+'\r\n')
    f.write('%----------------------------------------\r\n')
    f.write('%Structure:\r\n')
    f.write('%Index[-], Start[sample], End[sample], Group[-], Validity[-], Channel Index[-], Channel name[string], Info[string]\r\n')
    f.write('%Divided by: ASCII char no. 9\r\n')
    f.write('%DATA------------------------------------\r\n')
    
    # Start writing rows
    for row in df.iterrows():
        f.write(str(row[0]+1)+'\t'+
                str(int(row[1]['start']))+'\t'+
                str(int(row[1]['stop']))+'\t'+
                str(int(row[1]['group']))+'\t'+
                str(row[1]['validity'])+'\t'+
                str(int(row[1]['ch_idx']))+'\t'+
                row[1]['ch_name']+'\t'+
                row[1]['info']+'\r\n')
        
    