class_name Diagram extends ColorRect

const ANTS_COUNT: = 28
const ANT_COLOR: = Color(0.38, 0.47, 0.51, 1.0)

@export var ant_color: Color = ANT_COLOR
@export var SecZap: PackedScene
@export var inner_radius_0: = 0.36   ## Внутренний радиус диаграммы в режиме РТО
@export var inner_radius_1: = 0.855  ## Внутренний радиус диаграммы в обзора

var fs_default_colors: PackedColorArray  ## Цвета по умолчанию для блоков ФС


func _ready() -> void:
    signaller.connect('map_mode_changed', Callable(self, 'set_view_mode'))
    ProjectSettings.connect('settings_changed', _on_settings_changed)
    _on_settings_changed()
    _init_def_colors()
    set_band_colors(fs_default_colors)


func sv(val: float) -> float: return val / ($строб.scale.x / 2.0) * 0.125

func set_band_failures(val: PackedInt32Array): material.set('shader_parameter/ant_band_m', val)
func set_canvas_rotation(val: float):          material.set('shader_parameter/rotation', val)
func set_radius_inner_frac(val: float):        material.set('shader_parameter/inner_radius', val)
func set_strob_band(val: float):               $строб.set_instance_shader_parameter('band', val / 125.0)
func set_strob_center(val: Vector2):           $строб.position = val
func set_strob_color(val: Color):              $строб.set_instance_shader_parameter('color', val)
func set_strob_dir(val: float):                $строб.set_instance_shader_parameter('dir', val)
func set_strob_radius(val: float):             $строб.set_instance_shader_parameter('radius', sv(val))
func set_strob_visible(val: bool):             $строб.visible = val
func set_strob_width(val: float):              $строб.set_instance_shader_parameter('width', val)

func get_band_colors(_val: Array):     return material.get('shader_parameter/ant_band_c')
func get_band_failures(_val: Array):   return material.get('shader_parameter/ant_band_m')
func get_canvas_rotation() -> float:   return material.get('shader_parameter/rotation')
func get_radius_outter() -> float:     return size.x / scale.x
func get_radius_inner_frac() -> float: return material.get('shader_parameter/inner_radius')
func get_strob_band() -> float:        return $строб.get_instance_shader_parameter('band') * 125.0
func get_strob_center() -> Vector2:    return $строб.position
func get_strob_color() -> float:       return $строб.get_instance_shader_parameter('color')
func get_strob_dir() -> float:         return $строб.get_instance_shader_parameter('dir')
func get_strob_radius() -> float:      return $строб.get_instance_shader_parameter('radius') * 125.0
func get_strob_visible() -> bool:      return $строб.visible
func get_strob_width() -> float:       return $строб.get_instance_shader_parameter('width')


## Выставляет цвета для секторов
func set_band_colors(val: PackedColorArray):
    var image: = Image.create(val.size(), 1, false, Image.FORMAT_RGBA8)
    for x in val.size():
        image.set_pixel(x, 0, val[x])
    var tex: = ImageTexture.create_from_image(image)
    material.set('shader_parameter/sec_colors', tex)


## Добавляет сектор запрета[br]
## [param id] - Индекс сектора запрета.[br]
## [param szv.x] - Центральная частота (198...546).[br]
## [param szv.w] - Ширина диапазона (198...546).[br]
## [param szv.y] - Угол центра (0...360).[br]
## [param szv.z] - Ширина по углу (0...360).[br]
func add_seczap(id: int, szv: Vector4):
    var seczap: = SecZap.instantiate()
    seczap.name = StringName('SECZAP%d' % id)
    seczap.position = $строб.position
    seczap.set_instance_shader_parameter('dir', szv.y - 90.0)
    seczap.set_instance_shader_parameter('width',  szv.z)
    seczap.set_instance_shader_parameter('band',   sv(szv.w))
    seczap.set_instance_shader_parameter('radius', sv(szv.x))
    add_child(seczap)


## Удаляет сектор запрета[br]
## [param id] - Индекс сектора запрета[br]
func remove_seczap(id: int):
    var seczap: = get_node_or_null('SECZAP%d' % id)
    if not seczap: return
    remove_child(seczap)
    seczap.queue_free()


## Изменяет сектор запрета[br]
## [param id] - Индекс сектора запрета[br]
## [param szv.x] - Центральная частота[br]
## [param szv.w] - Ширина диапазона[br]
## [param szv.y] - Угол центра[br]
## [param szv.z] - Ширина по углу[br]
func set_seczap(id: int, szv: Vector4):
    var seczap: = get_node('SECZAP%d' % id)
    seczap.set_instance_shader_parameter('dir', szv.y)
    seczap.set_instance_shader_parameter('width', szv.z)
    seczap.set_instance_shader_parameter('band',   sv(szv.w))
    seczap.set_instance_shader_parameter('radius', sv(szv.x))


func clear_all_seczap():
    for child in get_children():
        if child.name.begins_with('SECZAP'):
            remove_child(child)
            child.queue_free()


func set_seczap_color(id: int, c: Color):
    var seczap: = get_node('SECZAP%d' % id)
    seczap.set_instance_shader_parameter('color', c)


func set_view_mode(val: int):
    var inner_radius = inner_radius_1 if val == 1 else inner_radius_0
    material.set('shader_parameter/inner_radius', inner_radius)


func _on_settings_changed():
    ant_color = ProjectSettings.get_setting('application/interfer/ant_color', ANT_COLOR)
    ant_color *= Color(1.0, 1.0, 1.0, 0.0)


## Закрашивание по умолчанию блоков ФС цветами из настроек.
func _init_def_colors():
    fs_default_colors.clear()
    for i in ANTS_COUNT:
        fs_default_colors.append(ant_color)
