extends Node

var id_array: Array                 # Массив id целей
var treats : Dictionary             # Словарь целей
var msg_counter : int = 0           # Счётчик отправленных пакетов

var g_table: GridContainer

const TableCellType1 = preload('res://ячейка-1.tscn')
const TableCellType2 = preload('res://кнопка-3.tscn')
const TableCellType3 = preload('res://кнопка-4.tscn')
const TableCellType4 = preload('res://заголовок.tscn')
const TableCellType5 = preload('res://ячейка-2.tscn')
const TableCellType6 = preload('res://кнопка-5.tscn')
const TableHeader = preload('res://table/header.tscn')

# Индекс колонки:                 0                1                2                3                4                5                 6               7               8                9               10                11                   12                   13                14                     15
const TABLE_HEADERS           = ['ID Цели',        'Курc.град',      'Частота',      'Ш. диап.',      'Ампл.',         'T обновл.',       'Мод.',         'Реж. см. F',    'Ск. пер.',     'Протокол',     'Ст. дол.',      'Ст. шир.',           'Cт. выс.',          'Тек. дол.',      'Тек. шир.',          'Тек. выс.', ]
const TABLE_HEADER_TYPES      = [ TableHeader,  TableHeader,  TableHeader,  TableHeader,  TableHeader,  TableHeader,  TableHeader, TableHeader,  TableHeader,  TableHeader, TableHeader,  TableHeader,       TableHeader,      TableHeader,   TableHeader,      TableHeader]
const TABLE_HEADER_ALIGNMENTS = [ HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,  HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,  HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,  HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,  HORIZONTAL_ALIGNMENT_CENTER]
const TABLE_ROW_TYPES         = [ TableCellType1,                TableCellType5,                TableCellType5,                TableCellType5,                TableCellType5,                TableCellType5,                TableCellType6,               TableCellType6,                TableCellType5,                TableCellType6,               TableCellType5,                TableCellType5,               TableCellType5,                TableCellType5,                TableCellType5,               TableCellType5]
const TABLE_ROW_ALIGNMENTS    = [ HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_LEFT,     HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,  HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,  HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,  HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,   HORIZONTAL_ALIGNMENT_CENTER,  HORIZONTAL_ALIGNMENT_CENTER]
const TABLE_COLUMN_SIZES      = [ 82,              82,              82,              82,              82,              90,              150,             150,            80,              150,            82,              82,                   82,                  82,               82,                  82]

const COLUMN_ID      = 0   # Идентификатор цели
const COLUMN_AOA     = 1   # Курсовой угол на источник сигнала, градусы
const COLUMN_FREQ    = 2   # Частота несущей или центральная частота, МГц
const COLUMN_WIDTH   = 3   # Ширина занимаемого диапазона частот, МГц
const COLUMN_POW     = 4   # Уровень принимаемого сигнала, дБ
const COLUMN_TICK    = 5   # Относительное время обнаружения сигнала, мс.
const COLUMN_TMOD    = 6   # Вид модуляции
const COLUMN_FREQM   = 7   # Режим смены частоты.
const COLUMN_BAUD    = 8   # Скорость передачи данных, бит/с
const COLUMN_PROTO   = 9   # Тип протокола источника сигнала.
const COLUMN_SLON    = 10  # Координаты старта, долгота в градусах
const COLUMN_SLAT    = 11  # Координаты старта, широта в градусах
const COLUMN_SALT    = 12  # Координаты старта, высота от уровня моря, метры
const COLUMN_LAT     = 13  # Текущие координаты, долгота в градусах
const COLUMN_LON     = 14  # Текущие координаты, широта в градусах
const COLUMN_ALT     = 15  # Текущая высота, метры

# Индексы колонок, которым можно задавать выравнивание текста
const TABLE_ALLIGNED_COLUMNS  = [
    COLUMN_ID,
    COLUMN_AOA,
    COLUMN_FREQ,
    COLUMN_WIDTH,
    COLUMN_POW,
    COLUMN_TICK,
    COLUMN_BAUD,
    COLUMN_SLON,
    COLUMN_SLAT,
    COLUMN_SALT,
    COLUMN_LAT,
    COLUMN_LON,
    COLUMN_ALT  ]

# Индексы колонок, в которых можно вводит текст
const TABLE_ENTRY_COLUMNS  = [
    COLUMN_AOA,
    COLUMN_FREQ,
    COLUMN_WIDTH,
    COLUMN_POW,
    COLUMN_TICK,
    COLUMN_BAUD,
    COLUMN_SLON,
    COLUMN_SLAT,
    COLUMN_SALT,
    COLUMN_LAT,
    COLUMN_LON,
    COLUMN_ALT  ]

# Типы модуляции
const MODE_TYPES = ['<неопр.>', 'am', 'ook', 'ask', 'fm', 'qpsk', 'oqpsk', 'pi4qpsk', 'qam16',
    'qam32', 'qam64', 'qam128', 'qam256', 'qam512', 'fsk', 'cpfsk', 'psk','ofdm']

# Режим смены частоты
const FREQM = ['<неопр.>', 'fhss', 'lfm', 'const']

# Протоколы радиомодема
const M_PROTO = ['<неопр.>', '3dlink', 'skyhopperpro', 'picardiooem', 'solo7', 'j11',
    'mavlink', 'ltm', 'hc12', 'df1', ]

# Номера колонок
const COLUMN_OPT = [[COLUMN_TMOD, MODE_TYPES], [COLUMN_FREQM, FREQM], [COLUMN_PROTO, M_PROTO]]
const COLUMN_OPT_BTN = [COLUMN_TMOD, COLUMN_FREQM, COLUMN_PROTO]
const ID_ARRAY_LEN = 100    # Размер пула номеров целей


# Цель
class Threat:
    # параметры цели, второе значение, разрешение отправки.
    var row: Dictionary = {
    'id':[0,true],
    'aoa':[10.0,true],
    'freq':[2480.0,true],
    'width':[20.0,true],
    'power':[20.0,true],
    'tick':[10,true],
    'tmod':['<неопр.>',false],
    'freqm':['<неопр.>',false],
    'baud':[0.0,false],
    'proto':['<неопр.>',false],
    'slon':[0.0,false],
    'slat':[0.0,false],
    'salt':[0.0,false],
    'lat':[0.0,false],
    'lon':[0.0,false],
    'alt':[0.0,false],
    }
    var row_id: int

    func _init(th_id : int, row_i: int):
        row.id[0] = th_id
        row_id = row_i

    func get_data():
        var data_to_send : Dictionary
        for key in row.keys():
            var value = row[key]
            var data = value[0]
            var need_send = value[1]
            if need_send:
                data_to_send[key] = data
        return data_to_send

    func update_rows():
        var new_rows: Array = []
        new_rows.append(_check_value(row.id))
        new_rows.append(_check_value(row.aoa))
        new_rows.append(_check_value(row.freq))
        new_rows.append(_check_value(row.width))
        new_rows.append(_check_value(row.power))
        new_rows.append(_check_value(row.tick))
        new_rows.append(_check_value(row.tmod))
        new_rows.append(_check_value(row.freqm))
        new_rows.append(_check_value(row.baud))
        new_rows.append(_check_value(row.proto))
        new_rows.append(_check_value(row.slon))
        new_rows.append(_check_value(row.slat))
        new_rows.append(_check_value(row.salt))
        new_rows.append(_check_value(row.lat))
        new_rows.append(_check_value(row.lon))
        new_rows.append(_check_value(row.alt))
        return new_rows


    func _check_value(val):
        if val[1]:
            return '%s' % val[0]
        else:
            return ''


    func set_aoa(val):
        var value = float(val)
        value = Tools.check_low_high(value, 0, 360)
        value = Tools.check_len(val, value)
        row.aoa[0] = value
        row.aoa[1] = Tools.check_empty(value)
        return value

    func set_freq(val):
        var value = float(val)
        value = Tools.check_negative(value)
        value = Tools.check_len(val, value)
        row.freq[0] = value
        row.freq[1] = Tools.check_empty(value)
        return value

    func set_width(val):
        var value = float(val)
        value = Tools.check_negative(value)
        value = Tools.check_len(val, value)
        row.width[0] = value
        row.width[1] = Tools.check_empty(value)
        return value

    func set_power(val):
        var value = float(val)
        value = Tools.check_negative(value)
        value = Tools.check_len(val, value)
        row.power[0] = value
        row.power[1] = Tools.check_empty(value)
        return value

    func set_tick(val):
        var value = int(val)
        value = Tools.check_low_high(value, 0, 60000)
        value = Tools.check_len(val, value)
        row.tick[0] = value
        row.tick[1] = Tools.check_empty(value)
        return value

    func set_baud(val):
        var value = float(val)
        value = Tools.check_negative(value)
        value = Tools.check_len(val, value)
        row.baud[0] = value
        row.baud[1] = Tools.check_empty(value)
        return value

    func set_slon(val):
        var value = float(val)
        value = Tools.check_low_high(value, -90, 90)
        value = Tools.check_len(val, value)
        row.slon[0] = value
        row.slon[1] = Tools.check_empty(value)
        return value

    func set_slat(val):
        var value = float(val)
        value = Tools.check_low_high(value, -180, 180)
        value = Tools.check_len(val, value)
        row.slat[0] = value
        row.slat[1] = Tools.check_empty(value)
        return value

    func set_salt(val):
        var value = float(val)
        value = Tools.check_len(val, value)
        row.salt[0] = value
        row.salt[1] = Tools.check_empty(value)
        return value

    func set_lon(val):
        var value = float(val)
        value = Tools.check_low_high(value, -90, 90)
        value = Tools.check_len(val, value)
        row.lon[0] = value
        row.lon[1] = Tools.check_empty(value)
        return value

    func set_lat(val):
        var value = float(val)
        value = Tools.check_low_high(value, -180, 180)
        value = Tools.check_len(val, value)
        row.lat[0] = value
        row.lat[1] = Tools.check_empty(value)
        return value

    func set_alt_pressed(val):
        var value = float(val)
        value = Tools.check_len(val, value)
        row.alt[0] = value
        row.alt[1] = Tools.check_empty(value)
        return value

    func set_tmod(val):
        var value = str(val)
        row.tmod[0] = value
        row.tmod[1] = false  if value == '<неопр.>' else true
        return value

    func set_freqm(val):
        var value = str(val)
        row.freqm[0] = value
        row.freqm[1] = false  if value == '<неопр.>' else true
        return value

    func set_proto(val):
        var value = str(val)
        row.proto[0] = value
        row.proto[1] = false  if value == '<неопр.>' else true
        return value


func init_treats(table, btn_add, btn_del):      	# Инициализация вкладки с целями
    for i in range(ID_ARRAY_LEN):                			# Заполняет массив ID целей
        id_array.append(i+1)
    table.set_header(TABLE_HEADER_TYPES)
    table.set_header_text(TABLE_HEADERS)
    on_btn_add(table)
    init_table(table, TABLE_COLUMN_SIZES)
    g_table = table
    table.set_columns_min_size(TABLE_COLUMN_SIZES)
    table.connect('row_pressed', Callable(self, 'on_row_pressed').bind(table))
    table.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, [])
    table.connect_columns(self, 'item_selected', 'on_item_selected', COLUMN_OPT_BTN, [])
    btn_add.connect('button_up', Callable(self, 'on_btn_add').bind(table))
    btn_del.connect('button_up', Callable(self, 'on_btn_del').bind(table))


func init_table(table: Table, sizes: Array):
    for i_row in table.get_rows_count():
        #table.set_nodes_min_size(i_row, sizes)
        pass


func init_opt_btns(row : int, table):
    for item in COLUMN_OPT:
        var i_col = item[0]
        var opt_arr = item[1]
        var cell = table.get_node2(i_col, row)
        for opt in opt_arr:
            cell.add_item(opt)
        cell.select(0)


func on_item_selected(item_num, node):
    var optbtn_text = node[0].text
    var indexis = g_table.get_key_indexes(node[0].name)
    var row_i = indexis[1]
    var col_i = indexis[0]
    var cell = g_table.get_node2(0,row_i)
    var value = set_value(optbtn_text, cell.text, col_i)


func on_edit_entry(text : String, entry):
    var indexis = g_table.get_key_indexes(entry[0].name)
    var row_i = indexis[1]
    var col_i = indexis[0]
    var cell = g_table.get_node2(0,row_i)
    var value = set_value(text, cell.text, col_i)
    entry[0].text = str(value)


func set_value(val : String, treat_id : String, column : int):
    var treat = treats[treat_id]
    match column:
        COLUMN_AOA:
            return treat.set_aoa(val)
        COLUMN_FREQ:
            return treat.set_freq(val)
        COLUMN_WIDTH:
            return treat.set_width(val)
        COLUMN_POW:
            return treat.set_power(val)
        COLUMN_TICK:
            return treat.set_tick(val)
        COLUMN_TMOD:
            return treat.set_tmod(val)
        COLUMN_FREQM:
            return treat.set_freqm(val)
        COLUMN_BAUD:
            return treat.set_baud(val)
        COLUMN_PROTO:
            return treat.set_proto(val)
        COLUMN_SLON:
            return treat.set_slon(val)
        COLUMN_SLAT:
            return treat.set_slat(val)
        COLUMN_SALT:
            return treat.set_salt(val)
        COLUMN_LAT:
            return treat.set_lon(val)
        COLUMN_LON:
            return treat.set_lat(val)
        COLUMN_ALT:
            return treat.set_alt_pressed(val)


func on_row_pressed(i_row: int, table):
    table.clear_rows_selected()
    table.set_row_selected(i_row, true)


func on_btn_add(table):
    var id = pop_id()
    var threat : = Threat.new(id, table.get_rows_count())
    treats['%d' % id] = threat
    var row = threat.update_rows()
    table.add_row(TABLE_ROW_TYPES)
    table.set_row_text(table.get_rows_count()-1, row)
    init_opt_btns(table.get_rows_count()-1, table)
    table.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, [])
    table.connect_columns(self, 'item_selected', 'on_item_selected', COLUMN_OPT_BTN, [])


func on_btn_del(table):
    var row_i = []
    table.get_selected_rows(row_i)
    if len(row_i) > 0:
        var cell = table.get_node2(0, row_i[0])
        treats.erase(cell.text)
        table.remove_row(row_i[0])


func pop_id():
    var id = 0
    if len(id_array):
        id =  id_array[0]
        id_array.remove_at(0)
    return id


func push_id(id : int):
    id_array.append(id)


func get_threats_data():
    var data_to_json : Dictionary
    data_to_json['ts'] = 5
    msg_counter += 1
    data_to_json['ss'] = msg_counter
    data_to_json['msvk'] = []
    data_to_json['mis'] = []
    for key in treats:
        var treat = treats[key]
        set_ticks(treat)
        var data = treat.get_data()
        data_to_json['mis'].append(data)
    var json = JSON.new().stringify(data_to_json)
    var pac = json.to_utf8_buffer()
    return pac


func set_ticks(treat):
    var tick = Time.get_ticks_msec()
    var cell = g_table.get_node2(COLUMN_TICK,treat.row_id)
    cell.text = str(treat.set_tick(str(tick%60000)))
