extends StaticBody2D

class_name GameObjectPowerStorage

const MAX_CHARGE = 5e5

var open = false
var attached = true
onready var activationRange = $ActivationRange as ActivationRange
onready var manager = $PowerManager as PowerManager

export var current_charge = MAX_CHARGE setget set_charge
export var max_charge_rate = 0 setget set_max_charge
export var max_discharge_rate = 2000 setget set_max_discharge

var next_network_update = Multiplayer.SYSTEMS_UPDATE_INTERVAL

func _ready() -> void:
	if not Engine.editor_hint:
		activationRange.visible = true
	$Control/PowerUI.set_current_charge(current_charge)
	$Control/PowerUI.set_max_charge(MAX_CHARGE)
	$Control/PowerUI.init_values(max_charge_rate, max_discharge_rate)
	set_max_charge(max_charge_rate)

func _physics_process(delta: float) -> void:
	if not is_network_master():
		return
	next_network_update -= 1
	if next_network_update < 0:
		next_network_update = Multiplayer.SYSTEMS_UPDATE_INTERVAL
	if manager.wired:
		if current_charge > 0:
			manager.power_source = min(current_charge, max_discharge_rate)
		if manager.power_load > 0:
			var new_charge = current_charge - manager.power_load * delta
			if next_network_update == 0:
				rpc("set_charge", new_charge)
			else:
				set_charge(new_charge)
		if PowerNetwork.DEBUG:
			update()
	if manager.powered:
		var new_charge = current_charge + max_charge_rate * delta
		if next_network_update == 0:
			rpc("set_charge", new_charge)
		else:
			set_charge(new_charge)

func _input(event):
	if event is InputEventMouseButton and event.pressed and not is_inside and open:
		open = false
		$UIAnimation.play("fadeout")

func _input_event(_viewport, event, _shape_idx):
	if Engine.editor_hint:
		return
	if event is InputEventMouseButton and event.pressed and not open:
		# Must be in range
		if activationRange.in_range():
			open = true
			$Control/PowerUI.visible = true
			$UIAnimation.play("fadein")

var is_inside = false
func _ui_focus_changed(entered):
	is_inside = entered

func _ui_fade_completed(anim_name):
	if anim_name == "fadeout":
		$Control/PowerUI.visible = false

func _force_close_ui():
	if open:
		open = false
		$UIAnimation.play("fadeout")

func _draw():
	if PowerNetwork.DEBUG and manager.wired:
		var charge_px = int(current_charge / MAX_CHARGE * 32)
		var charge_color = Color.greenyellow
		if charge_px < 20:
			charge_color = Color.yellow
		if charge_px < 10:
			charge_color = Color.red
		draw_rect(Rect2(32, 32-charge_px, 4, charge_px), charge_color)

remotesync func set_max_discharge(val: float) -> void:
	max_discharge_rate = val

remotesync func set_max_charge(val: float) -> void:
	max_charge_rate = val
	if manager != null:
		manager.power_usage = val

remotesync func set_charge(val: float) -> void:
	current_charge = val
	$Control/PowerUI.set_current_charge(current_charge)

func serialize():
	return {
		"current_charge": current_charge,
		"max_charge_rate": max_charge_rate,
		"max_discharge_rate": max_discharge_rate
	}

func deserialize(data):
	set_charge(data["current_charge"])
	set_max_charge(data["max_charge_rate"])
	set_max_discharge(data["max_discharge_rate"])
