@tool
extends 'res://scenes/контроль/прибор.gd'

const constants_v = {
    'POWER_UKP_1': 31,
    'POWER_UKP_2': 63,
    'DKM_BIT_4': 3,
    'DKM_BIT_5': 4,
    'BASE_ADDR_EMS_G': 0x120,
    'ADDR_UG_LITERA_1': 0x106,
    'ADDR_UG_LITERA_2': 0x108,
    'ADDR_UG_LITERA_3': 0x10A,
    'TEMP_THRESHOLD': 70,
    'POWER_THRESHOLD': 40,
    'RAY_DOU_NUM': 0x3,
    'ATT_UM_4': 0x2,
    'ATT_UM_5': 0x3,
    'POWER_UM': 100,
    'TIMER_DELAY': 10.0,
    'STATE_MASHINE_TIMER': 0.3,
}
# Конфигурация параметров для каждого прибора
const PRIBOR_CONFIG_V := {
    '1в': {'angle': 0.0, 'sectors': [12, 16]},
    '2в': {'angle': 90.0, 'sectors': [15, 19]},
    '3в': {'angle': 180.0, 'sectors': [14, 18]},
    '4в': {'angle': 270.0, 'sectors': [13, 17]},
}
# Конфигурация частот и ширин для каждого ФС
const FS_PARAMS_V := {
    4: {'freq': 1227.0, 'width': 100.0},
    5: {'freq': 1575.0, 'width': 110.0},
}
enum STATE_VAL { NONE = 0, GOOD = 1, ERROR = 2 }
var block_ip_config_v := {
    'maa2000_1': [0, false],
    'maa2000_2': [1, false],
    'ip9_50_1':  [2, false],
    'ip9_50_2':  [3, false],
    'ip12_50_1': [4, false],
    'ip5_25':    [7, false],
}
var block_kasseta_y5_prd_config_v: = {
    'yau07': false,
    'ems': false,
    'ug': false,
    'ukp1': false,
    'ukp2': false,
}

# Основные переменные
var start_litera: int = 4
var ug_work_1: int = 2  ## Аттенюация усилителей мощности
var ug_work_2: int = 3  ## Аттенюация усилителей мощности
# Флаги и таймеры
var mashine_timer: Timer = Timer.new()
var prd_v_module: Object
var unit_prd_v: Object
var control_prd_v: Object
# Результаты контроля
var control_results_v: Dictionary = {
    'block_ip': false,     # Проверка касет П1 и ИП МА2000
    'temperature': true,   # Проверка температур УМ
    'dkm_4': false,
    'dkm_5': false,
    'dou_4': false,
    'dou_5': false,
    'fs_4': 2,
    'fs_5': 2,
}
var test_control_v = preload('res://scripts/pribor-prd.gd')
var ctrl_pos = 70


func on_state_mashine() -> void:
    control_prd_v.state_control_machine()


func _ready() -> void:
    if Engine.is_editor_hint():
        return

    initialize_connections()
    setup_timer()
    set_default_state()
    find_labels(self)


func initialize_connections() -> void:
    var unit_name = get_meta('unit_name')[0]
    prd_v_module = prd.prd_dict[unit_name]
    unit_prd_v = prd_v_module.unit_yau07

    unit_prd_v.connect('line_changed', Callable(self, 'on_line_changed'))
    var power_amplifiers: Array = get_tree().get_nodes_in_group('power_amplifier')
    var init_data: Dictionary = {
        'control_label': $control_result,
        'power_amplifiers': power_amplifiers,
        'unit_prd': unit_prd_v,
        'module_prd' : prd_v_module,
        'constants': constants_v,
        'prd_config': PRIBOR_CONFIG_V,
        'fs_params': FS_PARAMS_V,
        'block_ip_prd_config': block_ip_config_v,
        'block_kasseta_y5_prd_config': block_kasseta_y5_prd_config_v,
        'control_results': control_results_v,
        'current_litera': start_litera,
    }
    control_prd_v = test_control_v.TestPRD.new(init_data)
    add_child(control_prd_v)
    control_prd_v.connect('control_is_over', Callable(self, 'on_control_result'))


func setup_timer() -> void:
    add_child(mashine_timer)
    mashine_timer.connect('timeout', Callable(self, 'on_state_mashine'))
    mashine_timer.wait_time = constants_v.STATE_MASHINE_TIMER
    mashine_timer.start()


func set_default_state() -> void:
    for group in get_tree().get_nodes_in_group('default_reset'):
        group.state = STATE_VAL.NONE

    for group in get_tree().get_nodes_in_group('power_amplifier'):
        group.state = STATE_VAL.NONE


func _enter_tree() -> void:
    if Engine.is_editor_hint():
        return
    $control_result.text = 'Выполняется ...'
    $control_result.add_theme_color_override('font_color', Color.ALICE_BLUE)
    signaller.connect('режим_работа', Callable(self, 'on_mode_changed').bind(false))
    signaller.connect('режим_журнал', Callable(self, 'on_mode_changed').bind(false))
    signaller.connect('режим_эмс', Callable(self, 'on_mode_changed').bind(false))
    signaller.connect('режим_настройки', Callable(self, 'on_mode_changed').bind(false))
    signaller.connect('режим_контроль', Callable(self, 'on_mode_changed').bind(true))



func _exit_tree() -> void:
    if Engine.is_editor_hint():
        return
    prd_v_module.cmd_array.append([unit_prd_v.CmdCode.WRITE_ISA, [constants_v.ADDR_UG_LITERA_1, ug_work_1, constants_v.ADDR_UG_LITERA_2, ug_work_2]])


func on_line_changed(unit_pribor: Object) -> void:
    if not unit_pribor.online:
        set_default_state()


func on_mode_changed(in_tree: bool) -> void:
    if not in_tree:
        mashine_timer.stop()
        prd_v_module.cmd_array.append([unit_prd_v.CmdCode.WRITE_ISA, [constants_v.ADDR_UG_LITERA_1, ug_work_1, constants_v.ADDR_UG_LITERA_2, ug_work_2]])
        signaller.emit_signal('interfer_off_all')
    else:
        set_default_state()
        control_prd_v.state = control_prd_v.STATE_MASHINE.INIT
        mashine_timer.start()


func power_fill(pow_dic: Dictionary, fs_result: Dictionary) -> void:
    var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier')
    for i_powapm in power_amplifier:
        var powamp_meta: String = i_powapm.get_meta('um')
        var status = STATE_VAL.GOOD if pow_dic else STATE_VAL.NONE
        if pow_dic[powamp_meta].size() < 6:
            status = STATE_VAL.ERROR
        else:
            if powamp_meta in ['um_1', 'um_2', 'um_3', 'um_4', 'um_5', 'um_6'] and not fs_result.fs_4: return
            if powamp_meta in ['um_7', 'um_8', 'um_9', 'um_10', 'um_11', 'um_12'] and not fs_result.fs_5: return
            i_powapm.value0 = pow_dic[powamp_meta]
            for i_p in pow_dic[powamp_meta]:
                if i_p < constants_v.POWER_THRESHOLD:
                    status = STATE_VAL.ERROR
        i_powapm.state = status


func on_control_result(result_dic: Dictionary, power_dic: Dictionary) -> void:
    mashine_timer.stop()
    block_kasseta_y5_prd_config_v = control_prd_v.block_kasseta_y5_config
    var nodes_y5: Array = get_tree().get_nodes_in_group('y-5')
    for node_y5 in nodes_y5:
        var meta_y5  = node_y5.get_meta('y5')
        if block_kasseta_y5_prd_config_v.has(meta_y5):
            if block_kasseta_y5_prd_config_v['yau07'] == false:
                node_y5.state = STATE_VAL.ERROR if meta_y5 == 'yau07' else STATE_VAL.NONE
                break
            node_y5.state = STATE_VAL.GOOD if block_kasseta_y5_prd_config_v[meta_y5] else STATE_VAL.ERROR

    block_ip_config_v = control_prd_v.block_ip_config
    var node_ip_power_arr: Array = get_tree().get_nodes_in_group('power_supply')
    for power_supply in node_ip_power_arr:
        var meta_ip  = power_supply.get_meta('ip')
        if block_ip_config_v.has(meta_ip) and block_kasseta_y5_prd_config_v.ug:
            power_supply.state = STATE_VAL.GOOD if block_ip_config_v[meta_ip][1] else STATE_VAL.ERROR

    var fs_nodes: Array = get_tree().get_nodes_in_group('fs_group')
    for f in fs_nodes:
            var fs_meta: String = f.get_meta('fs')
            if result_dic.has(fs_meta):
                var new_state = result_dic[fs_meta]
                f.state = new_state
                result_dic[fs_meta] = new_state

    if result_dic.fs_5 == 1:
        $kasseta_FS_VD/ref_A2.state = STATE_VAL.GOOD if result_dic.dkm_5 else STATE_VAL.ERROR
        $dou5_A6.state = STATE_VAL.GOOD if result_dic.dou_5 else STATE_VAL.ERROR
    else:
        result_dic.fs_5 = 0
    if result_dic.fs_4 == 1:
        $kasseta_FS_VD/ref_A6.state = STATE_VAL.GOOD if result_dic.dkm_4 else STATE_VAL.ERROR
        $dou4_A5.state = STATE_VAL.GOOD if result_dic.dou_4 else STATE_VAL.ERROR
    else:
        result_dic.fs_4 = 0
    power_fill(power_dic, result_dic)

    var result = true
    for device in result_dic.values():
        if not device:
            result = false

    var name_prd = control_prd_v.self_name
    if result:
        $control_result.text = 'Прибор ПРД-%s исправен' % name_prd
        $control_result.add_theme_color_override('font_color', Color.GREEN)
    else:
        $control_result.text = 'Прибор ПРД-%s неисправен' % name_prd
        $control_result.add_theme_color_override('font_color', Color.RED)


func find_labels(node1: Node):
    if node1 is Label:
        if node1.name in ["lbl_rname", "rname"]:
            if not node1.has_meta("tooltip_set"):
                ctrl_pos += 1
                var box_number = ceili(float(ctrl_pos) / 10.0)
                var position_number = ctrl_pos % 10
                if position_number == 0:
                    position_number = 10
                node1.tooltip_text = "Ящик - %d, Позиция - %d" % [box_number, position_number]
                node1.mouse_filter = Control.MOUSE_FILTER_STOP
                node1.set_meta("tooltip_set", true)
    for child in node1.get_children():
        find_labels(child)
