import Movements
import Initialization
import Data_acquisition
import Find_scan_range
import Spectral_calibration
import Get_spectrum_dft
import Close_connection
import Get_calibrated_position_axis
import matplotlib.pyplot as plt
import os
from datetime import datetime
import numpy as np
import pandas as pd


def start_scan(start_wave,end_wave, resolution, sampling_factor,system_index, channel_index):

    P_freq2wave, P_wave2freq = Spectral_calibration.spectral_calibration()
    lambda_mean = (start_wave+end_wave)/2
    start_position, end_position = Find_scan_range.scan_range(lambda_mean, resolution)
    freq = np.polyval(P_wave2freq, 1 / start_wave)
    freq_mm = 1 / freq
    number_steps = np.ceil((abs(start_position - end_position)) / (freq_mm / sampling_factor))
    step = (end_position - start_position) / number_steps

    items = os.listdir(".")
    for names in items:
        if names.endswith("parameters_scale.txt"):
            filename = names

    ref = pd.read_csv(filename, sep="\t", header=None)
    first_row = (ref.iloc[0])
    scale = first_row.to_numpy(dtype='float64')

    # Check that the start_postion and end_position are inside the positioner's travel range
    items = os.listdir(".")
    for names in items:
        if names.endswith("parameters_int.txt"):
            filename = names

    ref = pd.read_csv(filename, sep="\t", header=None)
    first_row = (ref.iloc[0])
    second_row = (ref.iloc[1])

    position_ref = first_row.to_numpy(dtype='float64')

    if start_position < position_ref[0]:
        start_position = position_ref[0]

    if end_position < position_ref[-1]:
        end_position = position_ref[-1]

    '''Data acquisition'''

    next_position = start_position
    Movements.move_absolute(system_index, channel_index, int(next_position*1000000))
    data_acquired = [Data_acquisition.data_acquisition()]
    positions = [start_position]

    fig = plt.figure()
    ax1 = fig.add_subplot(1,1,1)

    for i in range(0, int(number_steps)):
        next_position = next_position + step
        Movements.move_absolute(system_index, channel_index, int(next_position*1000000))
        while True:
            status = Movements.get_status(system_index, channel_index)
            if status.value == 0 or status.value == 3:
                break
        data_acquired.append(Data_acquisition.data_acquisition())   # substitute the code inside the parentesis with your data acquisition system, this is for NI's DAQ
        positions.append(next_position)


    signal = np.array(data_acquired)
    signal = signal.flatten()
    position_axis = np.array(positions)

    '''Calculation part: calibration of position axis, fourier transform'''

    # scale = Movements.get_scale(system_index, channelIndex)

    calibrated_positions = Get_calibrated_position_axis.get_calibrated_position_axis(position_axis,scale)
    spectrum, wave, freq = Get_spectrum_dft.get_spectrum(signal, calibrated_positions, start_wave, end_wave, spectral_points, apodization_width)
    # spectrum, wave, freq = Get_spectrum_dft.get_spectrum(signal, position_axis, start_wave, end_wave, spectral_points, apodization_width)

    '''Plots of the spectra'''

    fig, axs = plt.subplots(2)
    fig.suptitle('Spectrum as a function of wavelength and frequency')
    axs[0].plot(wave, spectrum)
    axs[1].plot(freq, spectrum)
    axs[0].set_ylabel('Amplitude')
    axs[0].set_xlabel('Wavelength [nm]')
    axs[1].set_ylabel('Amplitude')
    axs[1].set_xlabel('Spatial frequency [mm^-1]')
    plt.show()


    '''Possibility to save the interferogram in a txt file'''

    file_name = input("Name of saving file: ")
    if not os.path.exists('Measurements'):
        os.mkdir('Measurements')

    if not os.path.exists("Measurements/"+datetime.today().strftime('%Y-%m-%d')):
        os.mkdir("Measurements/"+datetime.today().strftime('%Y-%m-%d'))

    np.savetxt("Measurements/"+datetime.today().strftime('%Y-%m-%d')+"/"+file_name+".txt", np.stack((position_axis, signal)))

    #Close_connection.close_connection(system_index) # This close the connection to the interferometer