extends MarginContainer
class_name ProfTest
var msec_t = 1
var subclass
var subnative
var engine
var vec
var typed_vec := Vector3(1,1,1)
var world2d
var selected_func = "NONE"
var rayquery = PhysicsRayQueryParameters2D.create(Vector2(0, 0), Vector2(50, 100))
var rayquery_typed := PhysicsRayQueryParameters2D.create(Vector2(0, 0), Vector2(50, 100))

const SLIDER_MAX = 200

const CALL_TYPES = {
	"NONE": "Do nothing",
	"IDENT_COMMON": "Normal self function call in the same class.",
	"IDENT_STATIC": "Normal static function call in the same class.",
	"IDENT_STATIC_NESTED": "2 nested static function calls in the same class.",
	"IDENT_EXTENDED_FUNC": "Native function of the class ancestor. find_child",
	"IDENT_NEW": "Bare new(), calls on current class.",
	"IDENT_COMMON_AWAITED": "Awaited self function call in the same class.",
	"IDENT_STATIC_AWAITED": "Awaited static function call in the same class.",
	"IDENT_TYPED": "Normal self function call, typed",
	"SUB_NEW_NATIVE": "New called on engine class engine class",
	"SUB_CLASS_STATIC": "Static call on a generic RefCounted class from the same script",
	"SUB_CLASS_NESTEDSTATIC": "2 nested static calls on a generic RefCounted class",
	"SUB_CLASS_METHOD": "Normal Method",
	"SUB_CLASS_METHOD_call": "Normal method called with call()",
	"SUB_CLASS_NATIVE_call": "Native method called with call()",
	"SUB_CLASS_METHOD_call_deferred": "Normal method called with deferred_call()",
	"SUB_CLASS_NATIVE_call_deferred": "Native method called with deferred_call()",
	"SUB_PHYSICSPROC_NATIVE": "Native call within _physics_process, from a normal untyped variable.\nPhysicsDirectSpaceState2D.intersect_ray()",
	"SUB_PHYSICSPROC_NONNATIVE": "Non-native call within _physics_process",
	"SUB_COMMON_NATIVE": "Normal native call from untyped var.",
	"SUB_COMMON_AUDIOSERVER": "Audioserver native call",
	"SUB_COMMON_RAYCAST": "Raycast call",
	"SUB_AWAITED_NATIVE": "Awaited native call from untyped var.",
	"SUB_TYPED_NATIVE": "Native call from typed var",
	"SUB_STATIC_NATIVE": "Static native call",
}



class SomeClass:
	extends Node
	
	func new():
		for i in 10000:
			i * i

	static func static_method():
		for i in 10000:
			i * i

	func normal_method():
		for i in 10000:
			i * i
		
		
	static func nesting_static_method():
		for i in 10000:
			i * i
		
		nested_static_method()

	static func nested_static_method():
		for i in 10000:
			i * i
		

func _ready():
	subclass = SomeClass.new()
	subnative = RandomNumberGenerator.new()
	engine = Engine.get_singleton("Engine")
	vec = Vector3(1,2,3)
	world2d = get_world_2d()

	var button = find_child("OptionButton")
	var i = 0
	for calltype in CALL_TYPES:
		button.add_item(calltype, i)
		button.set_item_tooltip(i, CALL_TYPES[calltype])
		i += 1
	button.item_selected.connect(func_changed)
	button.select(CALL_TYPES.keys().find(selected_func))
	_on_h_slider_value_changed(msec_t)
	$HBoxContainer/VBoxContainer/issue_warning.hide()
	$HBoxContainer/VBoxContainer/VBoxContainer/HSlider.set_max(SLIDER_MAX)

func func_changed(index):
	var button = find_child("OptionButton")
	selected_func = button.get_item_text(index)
	if selected_func in ["SUB_CLASS_METHOD_call_deferred",
						"SUB_CLASS_NATIVE_call_deferred",
						"SUB_PHYSICSPROC_NATIVE",
						"SUB_PHYSICSPROC_NONNATIVE"]:
		$HBoxContainer/VBoxContainer/VBoxContainer/HSlider.value=1
		$HBoxContainer/VBoxContainer/issue_warning.show()
		$HBoxContainer/VBoxContainer/VBoxContainer/HSlider.set_max(1000)
	else:
		$HBoxContainer/VBoxContainer/issue_warning.hide()
		$HBoxContainer/VBoxContainer/VBoxContainer/HSlider.set_max(SLIDER_MAX)

static func static_func():
	for i in 10000:
		i * i
		
func normal_func_single():
	for i in 10000:
		i * i
	
func normal_func():
	for i in 10000:
		i * i
	

func typed_func(a: int) -> void:
	for i in 10000:
		i * i
	

static func nesting_static_func():
	for i in 10000:
		i * i
	
	nested_static_func()

static func nested_static_func():
	for i in 10000:
		i * i
	

func _physics_process(delta):
	var i = 0
	if selected_func == "SUB_PHYSICSPROC_NATIVE":
		while i < msec_t:
			var result = world2d.direct_space_state.intersect_ray(rayquery)
			i += 1
	if selected_func == "SUB_PHYSICSPROC_NONNATIVE":
		while i < msec_t:
			i += 1
			var result = normal_func()

func _process(delta):
	var start = Time.get_ticks_msec()
	var i = 0
	while Time.get_ticks_msec() - start < msec_t:
		i += 1
		match selected_func:
			"IDENT_COMMON":
				normal_func()
			"IDENT_STATIC":
				static_func()
			"IDENT_STATIC_NESTED":
				nesting_static_func()
			"IDENT_EXTENDED_FUNC":
				find_child("asdf")
			"IDENT_NEW":
				var a = new()
				a.queue_free()
			"IDENT_COMMON_AWAITED":
				await normal_func()
			"IDENT_STATIC_AWAITED":
				await nested_static_func()
			"IDENT_TYPED":
				var a := 5
				typed_func(a)
			"SUB_NEW_NATIVE":
				TileMap.new()
			"SUB_CLASS_STATIC":
				SomeClass.static_method()
			"SUB_CLASS_NESTEDSTATIC":
				SomeClass.nesting_static_method()
			"SUB_CLASS_METHOD":
				subclass.normal_method()
			"SUB_CLASS_METHOD_call":
				subclass.call("normal_method", )
			"SUB_CLASS_NATIVE_call":
				engine.call("get_copyright_info")
			"SUB_CLASS_METHOD_call_deferred":
				subclass.call_deferred("normal_method")
				if i > msec_t:
					break
			"SUB_CLASS_NATIVE_call_deferred":
				engine.call_deferred("get_copyright_info")
				if i > msec_t:
					break
			"SUB_PHYSICSPROC_NATIVE":
				break
			"SUB_PHYSICSPROC_NONNATIVE":
				break
			"SUB_COMMON_NATIVE":
				engine.get_copyright_info()
			"SUB_COMMON_AUDIOSERVER":
				AudioServer.get_input_device_list()
			"SUB_COMMON_RAYCAST":
				world2d.direct_space_state.intersect_ray(rayquery)
			"SUB_AWAITED_NATIVE":
				await engine.get_copyright_info()
			"SUB_TYPED_NATIVE":
				var a: int = 1
				OS.delay_msec(a)
			"SUB_STATIC_NATIVE":
				Image.create(500, 500, true, Image.FORMAT_BPTC_RGBA)


func _on_h_slider_value_changed(value):
	msec_t = int(value)
	find_child("Label").set_text("msecs: " + str(msec_t))
