import numpy
import os
import sys
if sys.version_info.major>=3:
    import configparser 
else:
    import ConfigParser as configparser
import pySAXS
CFGFILE=pySAXS.__path__[0]+os.sep+"filefilters"+os.sep+"file_type.ini"

class fileImport():
        
    def __init__(self,filtername=None,extension='txt',description='data',\
                 icon='',comments='#',qcol=0,icol=1,errcol=2,skiprows=0,sep=None,xfactor=1.0):
        #------------- values which can be modified in ini file
        self.extension=extension#'txt'
        self.description=description#'datas in 2 columns (or 3 with error)'
        self.icon=icon#''
        self.comments=comments#'#'
        self.qcol=qcol#0
        self.icol=icol#1
        self.errcol=errcol#-1 #if is -1, is not read
        self.skiprows=skiprows#0 
        self.sep=sep#None
        #if self.sep is None:
        #    self.sep=" "
        self.xfactor=xfactor
        #-------------- No dynamic values here
        self.q=None
        self.i=None
        self.err=None
        self.data=None
        #
        if filtername is not None:
            self._import_fileformat_(filtername)

    def get_header_size(self,filename,sep=None):
        if sep is None:
            sep=' '
        with open(filename, 'r') as file:
            header_size = 0
            for line in file:
                values = line.strip().split(sep)
                try:
                    # Essayer de convertir toutes les valeurs en float
                    [float(value) for value in values]
                    # Si la conversion réussit, on a atteint les données
                    break
                except ValueError:
                    # Si une conversion échoue, c'est une ligne d'en-tête
                    header_size += 1

        return header_size

    def determine_separater(self,file_path,header_size=1):
        # Ouvrir le fichier en mode lecture
        with open(file_path, 'r') as file:
            # Lire les 5 premières lignes
            lines=file.readlines()
            line=lines[header_size]
            #for _ in range(1):
            line = file.readline()
            # Trouver le séparateur
            if ',' in line:
                return ','
            elif ';' in line:
                return ';'
            elif ' ' in line:
                return ' '
        # Si aucun séparateur n'est trouvé dans les premières lignes, retourner None
        return None

        
    def read(self,filename):
        '''
        read a file
        '''
        #read
        useCols=[self.qcol,self.icol]
        if self.errcol >=0 :
            useCols.append(self.errcol)
        #print(filename,useCols)

        try:
            self.data=numpy.loadtxt(filename, comments=self.comments, skiprows=self.skiprows, \
                                    usecols=useCols,delimiter=self.sep)# Load data from a text file.
        except IndexError:
            #there is an error of columns (no error columns)
            #print useCols
            useCols=useCols[:-1]
            self.errcol=-1
            self.data=numpy.loadtxt(filename, comments=self.comments, skiprows=self.skiprows,\
                                     usecols=useCols,delimiter=self.sep)# Load data from a text file.
        except ValueError:
            self.data = numpy.genfromtxt(filename,dtype='float')
        except:
            print('Error when reading file %s '%filename)
            print(f'trying to get the header size with seperator is {self.sep}')
            header_size=self.get_header_size(filename,self.sep)
            print(f'found {header_size} lines on the header')
            separator=self.determine_separater(filename,header_size)
            print(f'found {header_size} lines on the header with separator is {separator}')
            try:
                self.data = numpy.loadtxt(filename, skiprows=header_size,delimiter=separator)
            except:
                print('Error when reading file %s ' % filename)

        #print(self.data)
        self.data=numpy.transpose(numpy.array(self.data))
        self.q=self.data[0]*self.xfactor
        self.i=self.data[1]
        #nan values management
        isnotNan=numpy.where(~numpy.isnan(self.i))
        print(self.q,self.i)
        self.q=self.q[isnotNan]
        self.i=self.i[isnotNan]
        if self.errcol >=0 :
            self.err=self.data[2]
            self.err=self.err[isnotNan]
            isnotNan=numpy.where(~numpy.isnan(self.err))
            self.err=self.err[isnotNan]
            self.q=self.q[isnotNan]
            self.i=self.i[isnotNan]
        #print self.q,self.i,self.err    
        return self.q,self.i,self.err
    
    def _import_fileformat_(self,filtername):
        '''
        import the file format from the config file
        '''
        rpt = configparser.ConfigParser()
        rpt.read(CFGFILE)
        if rpt.has_section(filtername):
            list_of_options=rpt.options(filtername)
            for option in list_of_options:
                option=option.lower()
                value=rpt.get(filtername,option)
                #print option,value
                #print type(getattr(self, option))
                if option == 'sep':
                    #print "sep="+str(value)+"-"
                    self.sep=value
                else:
                    setattr(self, option,type(getattr(self, option))(value))
        else :
            print("filter not found")

def import_list():
    '''
    List all data file format
    '''
    rpt = configparser.ConfigParser()
    rpt.read(CFGFILE)
    return rpt.sections()

def import_dict():
    '''
    List all data file format
    and return a dictionary
    '''
    rpt = configparser.ConfigParser()
    rpt.read(CFGFILE)
    d={}
    for section in rpt.sections():
       d[section]=[rpt.get(section,'description'),rpt.get(section,'extension')]
    return d 
    
    
        