from dis import pretty_flags

from PySide6 import QtWidgets  # Импорт модуля QtWidgets из библиотеки PySide6
from PySide6.QtGui import QPixmap,QFont
import sys  # Импорт модуля sys для работы с системными параметрами и выходом из программы
import numpy as np
import struct
import xml.etree.ElementTree as ET
from xml.dom import minidom


def switch(metric):
    if metric == 'nS':
        return 10**-9
    elif metric == 'uS':
        return 10**-6
    elif metric == 'mS':
        return 10**-3
    elif metric == 'S':
        return 1

def set_params(period, period_metric, width, width_metric, delay1, d1_metric, delay2, d2_metric, number, sr):
    pulse_period_metric = period_metric
    pulse_period = (np.int32(period)) * switch(pulse_period_metric)

    pulse_width_metric = width_metric
    pulse_width = (np.int32(width)) * switch(pulse_width_metric)

    delay1_metric = d1_metric
    delay1 = (np.int32(delay1)) * switch(delay1_metric)

    delay2_metric = d2_metric
    delay2 = (np.int32(delay2)) * switch(delay2_metric)

    sample_freq = np.int32(sr)
    pulse_number = np.int32(number)

    print(f""" Pulse parameters:
          pulse width - {pulse_width} S
          pulse period - {pulse_period} S 
          delay 1 - {delay1} S
          delay 2 - {delay2} S
          pulse_number - {pulse_number}
          sample frequency {sample_freq} MHz""")
    #add = (pulse_width * pulse_number * sample_freq * (10**6) * 2)
    counter = 0
    n_high = round(pulse_width * sample_freq * (10 ** 6))
    print(f"high samples {n_high}")
    n_low = round((pulse_period - pulse_width) * sample_freq * (10 ** 6))
    print(f"low samples {n_low}")
    size_1 =(n_low + n_high) * 2
    print(f'rf array size_1 = {size_1}')

    size_2 = np.int32(size_1) * np.int32(pulse_number)
    print(f'rf array size_2 = {size_2}')
    rf_array = np.zeros(size_2, dtype=np.int8)

    for _ in range(0, pulse_number, 1):

        for _ in range(0, n_high, 1):

            rf_array[counter] = np.int8(127)
            rf_array[counter + 1] = np.int8(0)
            counter += 2
        for _ in range(0, n_low, 1):
            rf_array[counter] = np.int8(0)
            rf_array[counter + 1] = np.int8(0)
            counter += 2
    print(rf_array)

    f = open(f'test_linreg.bin', 'wb')  # открываем файл на чтение
#    f = open(f'test_100_pulses_10Msps_1ms.bin', 'wb')  # открываем файл на чтение

    for elem in rf_array:  # берём каждую строчку из файла f
        f.write(struct.pack('<b',elem))
    f.close()
    # write sync params in XML file

    root = ET.Element('root')


    rf = ET.SubElement(root, 'RF')
    sw = ET.SubElement(root, 'SW')
    adc = ET.SubElement(root, 'ADC')
    gru1 = ET.SubElement(root, 'GR')

    first_pulse_delay = 17 * 10 ** -6
    if int(sr) == 2:
        first_pulse_delay = 17 * 10 ** -6
    elif int(sr) == 8:
        first_pulse_delay = 4.12 * 10 ** -6
    elif int(sr) == 10:
        first_pulse_delay = 3.26 * 10 ** -6
    elif (sr) == 20:
        first_pulse_delay = 1.5 * 10 ** -6

    cl = ET.SubElement(root, 'CL')
    ET.SubElement(rf,'RF1').text = '0'
    ET.SubElement(sw,'SW1').text = '0'
    ET.SubElement(adc,'ADC1').text = '0'
    ET.SubElement(gru1,'GR1').text = '1'

    ET.SubElement(cl, 'CL1').text = str(round(first_pulse_delay/ (20*(10**-9))))

    param_count = 1

    delay1_cycles = round(delay1 / (20*(10**-9)))
    pw_cycles = round(pulse_width / (20*(10**-9)))
    low_cycles = round((pulse_period - pulse_width - 2*delay1) / (20*(10**-9)))
    delay2_cycles = round (delay2 / (20*(10**-9)))
    recieve_time = low_cycles - 2 * delay2_cycles

    param_count += 1
    ET.SubElement(rf, 'RF' + str(param_count)).text = "0"
    ET.SubElement(sw, 'SW' + str(param_count)).text = "0"
    ET.SubElement(adc, 'ADC' + str(param_count)).text = "0"
    ET.SubElement(gru1, 'GR' + str(param_count)).text = "0"
    ET.SubElement(cl, 'CL' + str(param_count)).text = str((2 * delay1_cycles + pw_cycles + recieve_time + 2 * delay2_cycles) * (pulse_number-1))

    for _ in range (0, 1):

        param_count += 1
        ET.SubElement(rf, 'RF' + str(param_count)).text = "1"
        ET.SubElement(sw, 'SW' + str(param_count)).text = "0"
        ET.SubElement(adc, 'ADC' + str(param_count)).text = "0"
        ET.SubElement(gru1, 'GR' + str(param_count)).text = "0"
        ET.SubElement(cl, 'CL' + str(param_count)).text = str(2 * delay1_cycles + pw_cycles)

        param_count += 1
        ET.SubElement(rf, 'RF' + str(param_count)).text = "0"
        ET.SubElement(sw, 'SW' + str(param_count)).text = "0"
        ET.SubElement(adc, 'ADC' + str(param_count)).text = "0"
        ET.SubElement(gru1, 'GR' + str(param_count)).text = "0"
        ET.SubElement(cl, 'CL' + str(param_count)).text = str(delay2_cycles)

        param_count += 1
        ET.SubElement(rf, 'RF' + str(param_count)).text = "0"
        ET.SubElement(sw, 'SW' + str(param_count)).text = "0"
        ET.SubElement(adc, 'ADC' + str(param_count)).text = "1"
        ET.SubElement(gru1, 'GR' + str(param_count)).text = "0"
        ET.SubElement(cl, 'CL' + str(param_count)).text = str(recieve_time)

        param_count += 1
        ET.SubElement(rf, 'RF'+ str(param_count)).text = "0"
        ET.SubElement(sw,'SW'+ str(param_count)).text = "0"
        ET.SubElement(adc, 'ADC' + str(param_count)).text = "0"
        ET.SubElement(gru1, 'GR' + str(param_count)).text = "0"
        ET.SubElement(cl, 'CL' + str(param_count)).text = str(delay2_cycles)

    for RF_END in root.iter(f'RF{param_count-3}'):
        RF_END.text = '1'

    ET.SubElement(root, 'ParamCount').text = str(param_count)
    xml_str = ET.tostring(root, encoding='utf-8', method='xml')
    parsed_str = minidom.parseString(xml_str)  # Парсим строку
    pretty_xml_str = parsed_str.toprettyxml(indent="  ")  # Добавляем отступы

    # Сохраняем форматированный XML в файл
    with open('Sync_param.xml', 'w', encoding='utf-8') as f:
        f.write(pretty_xml_str)
    
    root_pico = ET.Element('root')
    
    points = ET.SubElement(root_pico, 'points')
    noc = ET.SubElement(root_pico, 'num_of_channels')
    times = ET.SubElement(root_pico, 'times')
    sr_pico = ET.SubElement(root_pico, 'sample_freq')

    ET.SubElement(sr_pico, 'title').text = 'Sample Frequency'
    ET.SubElement(sr_pico, 'value').text = str(80000000.0 * 5) # лютые костыли

    ET.SubElement(points, 'title').text = 'Points'
    ET.SubElement(points, 'value').text = str([round(80000000 * pulse_width)]) # лютые костыли

    ET.SubElement(noc, 'title').text = 'Number of Channels'
    ET.SubElement(noc, 'value').text = '4'

    ET.SubElement(times, 'title').text = 'Times'
    ET.SubElement(times, 'value').text = str([0.021])

    xml_str = ET.tostring(root_pico, encoding='utf-8', method='xml')
    parsed_str = minidom.parseString(xml_str)  # Парсим строку
    pretty_xml_str = parsed_str.toprettyxml(indent="  ")  # Добавляем отступы

    with open('pico_params.xml', 'w', encoding='utf-8') as f:
        f.write(pretty_xml_str)


set_params(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8], sys.argv[9], sys.argv[10])