extends RigidBody

export (float, 0, 100) var audible_range_max = 10.0
export (int, 1, 12) var preset = 1

export (bool) var use_embeded_patch = false
export (String, MULTILINE) var patch = ""

var _my_patch = "user://buoyancy/SoundBoxLying.pd"
var _my_id = 0

func set_size(size):
	$CollisionShape.shape.radius = size
	$MeshInstance.mesh.radius = size
	$MeshInstance.mesh.height = size * 2

func set_freq(freq):
	Global._gdpd.start_message(2)
	Global._gdpd.add_symbol('freq')
	Global._gdpd.add_float(freq)
	Global._gdpd.finish_list("fromGodot" + String(_my_id))

func set_gain(gain):
	Global._gdpd.start_message(2)
	Global._gdpd.add_symbol('gain')
	Global._gdpd.add_float(gain)
	Global._gdpd.finish_list("fromGodot" + String(_my_id))

func set_param(param):
	Global._gdpd.start_message(param.size()+1)
	Global._gdpd.add_symbol("param")
	for i in range(param.size()):
		Global._gdpd.add_float(param[i])
	Global._gdpd.finish_list("fromGodot" + String(_my_id))

func set_preset(prs):
	preset = prs
	Global._gdpd.start_message(2)
	Global._gdpd.add_symbol("preset")
	Global._gdpd.add_float(prs)
	Global._gdpd.finish_list("fromGodot" + String(_my_id))

func set_color(color):
	$MeshInstance.material_override = SpatialMaterial.new()
	$MeshInstance.material_override.albedo_color = color

func _ready():
	# save patch (for export)
	if use_embeded_patch:
		assert(_my_patch.substr(0, 7) == "user://", "use userpath with embeded_patch enabled !")
		assert(patch != "", "patch is empty?")
		_save_patch()

	# load patch
	_my_id = Global.load_patch(ProjectSettings.globalize_path(_my_patch))

	# listen 'player_transform_updated' event
	Events.connect("player_transform_updated", self, "_on_Events_player_transform_updated")

	# send 'preset'
	set_preset(preset)

func _on_Events_player_transform_updated(playerpos, playerheading):
	var mypos = get_global_translation()
	var mypos2d = Vector2(mypos.x, mypos.z)
	var playerpos2d = Vector2(playerpos.x, playerpos.z)
	# calculate distance
	var distance = mypos.distance_to(playerpos)
	# calculate angle
	var angle = fmod(fmod(playerpos2d.angle_to_point(mypos2d) + playerheading - PI/2, PI*2) + PI*2, PI*2)
	if angle > PI:
		angle = angle - PI*2
	# (check)
#	print(str(_my_id) +" : ("+ str(distance) +","+ str(angle) +")")
	# calculate gain
	var gain = 1 - distance/audible_range_max
	# send to the patch
	Global._gdpd.start_message(3)
	Global._gdpd.add_symbol("panvol")
	Global._gdpd.add_float(gain)
	Global._gdpd.add_float(angle)
	Global._gdpd.finish_list("fromGodot" + String(_my_id))


func _exit_tree():
	Global.close_patch(_my_id)

func _save_patch():
	# save patch
	# prepare directory
	var patch_name = _my_patch.split("/")[-1]
	var patch_dir = _my_patch.trim_suffix(patch_name)
	var dir = Directory.new()
	dir.make_dir_recursive(patch_dir)
	# save to file
	var file = File.new()
	file.open(_my_patch, File.WRITE)
	file.store_string(patch)
	file.close()
