extends Node3D

@export var button_paths = []
var buttons = []

var main_text

var camera_audience
var camera_stage
var camera_intro
var camera
var player

var paper
var paper_history
var control

var history_ui
var history_choices
var history_audience

var game_pos = -1
var keyp = false

var paper_pos = 0.0
var paper_history_pos = 0.0

var on_paper_pos = 0.0
var off_paper_pos = -1.0
@export var paper_speed = 0.1

var history = false

@export var move_speed = 1
@export var turn_speed = 1

var start_text = "Okay so a "
var mid_text = " and a "
var end_texts = [
	" decided to steal a ",
	" decided to visit a ",
	" attempted to destroy a ",
	" tried to decieve a ",
	" competed to win a ",
	" walked towards a ",
	" attempted to mail a ",
]
var punchlines = [
	"but it turns out it was broken.",
	"but they never got anywhere.",
	"but they gave up immediately.",
	"but they couldn't find one.",
	"but it was full of spiders.",
	"but they mixed up the address.",
	"but it was against the law.",
	"and they were sucessful.",
	"but they were caught.",
	"but they couldn't fit it in.",
	"but they got scared.",
]

var first_choice = 0
var second_choice = 0
var third_choice = 0

var choice_pos = 0

var target_text = ""
var true_text = ""

@export var text_rate = 1.0
var text_timer = 0.0

@export var timer_switchover_rate = 3.0
var timer_switchover = 0.0

@export var punchline_rate = 2.0
var punchline_time = 0.0
var punchline_trigger = false

@export var crowd_period = 5.0
@export var cheer_point = 4.0
var crowd_time = 0.0
var cheering = false

var aud1
var aud2 
var aud3 
var aud4

var expected_1
var expected_2
var expected_3

var rng = RandomNumberGenerator.new()

var won = false
var win
var win_pos = 0.0
var on_win_pos = 0.0
var off_win_pos = -1.0

var turns = 0
var score_obj

var as_targ = -1.0
var audience_score
var as_pos = -1.0

var as_cont
var as_text

var end_text = ""

var prev_choices = []

var start
var start_pos = 0.0
var start_targ = 0.0

var write
var write_vol = -10.0

@export var audience_reaction_paths = []
var audience_reactions = []

@export var mumble_paths = []
var mumbles = []

var mute = false
var mpre = false

func _start_game():
	reset_turn()
	start_targ = 1.0
	player["parameters/StateMachine/conditions/start"] = true

func _on_button(id):
	player["parameters/StateMachine/conditions/card_stow"] = false
	
	#print(id)
	
	if game_pos == 0:
		if choice_pos == 0:
			first_choice = id
			choice_pos = 1
			target_text = start_text + buttons[first_choice]["text"] + \
							mid_text + "..."
		elif choice_pos == 1:
			second_choice = id
			choice_pos = 2
			end_text = end_texts[rng.randi_range(0, end_texts.size()-1)]
			target_text = start_text + buttons[first_choice]["text"] + \
							mid_text + buttons[second_choice]["text"] + \
							end_text + "..."
		elif choice_pos == 2:
			third_choice = id
			choice_pos = 3
			target_text = start_text + buttons[first_choice]["text"] + \
							mid_text + buttons[second_choice]["text"] + \
							end_text + buttons[third_choice]["text"] + "\n\n"
			timer_switchover = timer_switchover_rate
			punchline_trigger = false
			
			game_pos = 1
			history = false
			
			player["parameters/StateMachine/conditions/card_stow"] = true
		else:
			print("choice_pos wrong! ", choice_pos)
			
		for button in buttons:
			button.rotation = rng.randf_range(-0.06, 0.06)
	
	pass

# Called when the node enters the scene tree for the first time.
func _ready():
	camera_audience = get_node("camera_audience")
	camera_stage = get_node("camera_stage")
	camera_intro = get_node("camera_intro")
	camera = get_node("Camera3D")
	player = get_node("conman/AnimationTree")
	
	paper = get_node("Camera3D/paper")
	paper_history = get_node("Camera3D/paper_history")
	win = get_node("Control/win")
	control = get_node("Control/paper")
	
	main_text = get_node("Control/paper/Label")
	score_obj = get_node("Control/win/score")
	
	
	history_ui = get_node("Control/history")
	history_choices = get_node("Control/history/choices")
	history_audience = get_node("Control/history/audience")
	
	as_cont = get_node("Control/state")
	as_text = get_node("Control/state/state")
	
	aud1 = get_node("audience_fr")
	aud2 = get_node("audience_fr2")
	aud3 = get_node("audience_fr3")
	aud4 = get_node("audience_fr4")
	
	start = get_node("Control/intro")
	
	write = get_node("write")
	
	player["parameters/StateMachine/conditions/card_look"] = true
	
	for button_path in button_paths:
		buttons.push_back(get_node(button_path))
		
	target_text = start_text + "..."
	
	expected_1 = rng.randi_range(0,9)
	expected_2 = rng.randi_range(0,9)
	expected_3 = rng.randi_range(0,9)
	
	for button in buttons:
		button.rotation = rng.randf_range(-0.06, 0.06)
		
	for react_path in audience_reaction_paths:
		audience_reactions.push_back(get_node(react_path))
		
	for mumble_path in mumble_paths:
		mumbles.push_back(get_node(mumble_path))
	
func get_score():
	var sc = 0
	var m1 = false
	var m2 = false
	var m3 = false
	
	if expected_1 == first_choice:
		sc += 2
		m1 = true
	if expected_2 == second_choice:
		sc += 2
		m2 = true
	if expected_3 == third_choice:
		sc += 2
		m3 = true
		
	if expected_1 != first_choice:
		if (not m2 and expected_1 == second_choice) or \
		   (not m3 and expected_1 == third_choice):
			sc += 1
	if expected_2 != second_choice:
		if (not m1 and expected_2 == first_choice) or \
		   (not m3 and expected_2 == third_choice):
			sc += 1
	if expected_3 != third_choice:
		if (not m1 and expected_3 == first_choice) or \
		   (not m2 and expected_3 == second_choice):
			sc += 1
			
	return sc

func reset_turn():
	game_pos = 0
	choice_pos = 0
	as_targ = -1.0
	as_pos = -1.0
	target_text = start_text + "..."
	true_text = ""
	won = false
	win_pos = off_win_pos
	player["parameters/StateMachine/conditions/card_stow"] = false
	player["parameters/StateMachine/conditions/card_look"] = true
	
func reset_game():
	reset_turn()
	
	expected_1 = rng.randi_range(0,9)
	expected_2 = rng.randi_range(0,9)
	expected_3 = rng.randi_range(0,9)
	
	prev_choices = []

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	player["parameters/StateMachine/conditions/card_look"] = false
	player["parameters/StateMachine/conditions/end_line"] = false
	player["parameters/StateMachine 2/conditions/talk"] = false
	
	if Input.is_key_pressed(KEY_H):
		if !keyp:
			history = !history
			
			var choice_list = ""
			var score_list = ""
		
			for choice in prev_choices:
				choice_list += buttons[choice[0]]["text"] + "," + \
							   buttons[choice[1]]["text"] + "," + \
							   buttons[choice[2]]["text"] + "\n"
				score_list += str(choice[3]) + "\n"
				
			history_choices["text"] = choice_list
			history_audience["text"] = score_list
		keyp = true
	else:
		keyp = false	
		
	if Input.is_key_pressed(KEY_M):
		if !mpre:
			mute = !mute
			
			if mute:
				AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), -100)
			else:
				AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), 0)	
		mpre = true
	else:
		mpre = false	
	
	if Input.is_key_pressed(KEY_R):
		reset_game()
	
	if game_pos == -1:
		camera.transform.origin = lerp(
			camera.transform.origin, 
			camera_intro.transform.origin,
			delta * move_speed)
		camera.basis = lerp(
			camera.basis, 
			camera_intro.basis,
			delta * turn_speed)
	elif game_pos == 0 or game_pos == 1:
		camera.transform.origin = lerp(
			camera.transform.origin, 
			camera_stage.transform.origin,
			delta * move_speed)
		camera.basis = lerp(
			camera.basis, 
			camera_stage.basis,
			delta * turn_speed)
	else:
		camera.transform.origin = lerp(
			camera.transform.origin, 
			camera_audience.transform.origin,
			delta * move_speed)
		camera.basis = lerp(
			camera.basis, 
			camera_audience.basis,
			delta * turn_speed)
			
	if game_pos == 0:
		aud1.reset_react()
		aud2.reset_react()
		aud3.reset_react()
		aud4.reset_react()
		
	if game_pos == 0 or game_pos == 1:
		paper_pos = lerp(paper_pos, on_paper_pos, delta * paper_speed)
	else:
		paper_pos = lerp(paper_pos, off_paper_pos, delta * paper_speed)
		
	if history:
		paper_history_pos = lerp(paper_history_pos, on_paper_pos, delta * paper_speed)
	else:
		paper_history_pos = lerp(paper_history_pos, off_paper_pos, delta * paper_speed)
		
	if won:
		win_pos = lerp(win_pos, on_win_pos, delta * paper_speed / 2)
	else:
		win_pos = lerp(win_pos, off_win_pos, delta * paper_speed / 2)

	var as_speed = 0.5

	if as_pos > as_targ:
		as_pos -= delta * as_speed
	else:
		as_pos += delta * as_speed
		
	if game_pos == 0:
		for button in buttons:
			button.visible = true
	else:
		for button in buttons:
			button.visible = false
			
	start_pos = lerp(start_pos, start_targ, delta * paper_speed / 2)
		
	paper.position.y = paper_pos/10
	control.position.y = -paper_pos*850
	paper_history.position.y = paper_history_pos/10
	history_ui.position.y = -paper_history_pos*950
	win.position.y = win_pos*850
	as_cont.position.x = pow(as_pos, 3)*1200 + 1200.0
	start.position.x = start_pos*1200
	
	if true_text.length() > target_text.length():
		true_text = true_text.substr(0, target_text.length())
	
	for x in range(0, true_text.length()):
		if true_text[x] != target_text[x]:
			true_text = true_text.substr(0, x)
			break
			
	text_timer -= delta
	
	write_vol -= delta * 50.0
	
	if text_timer < 0 and \
		true_text.length() < target_text.length():
		true_text += target_text[true_text.length()]
		text_timer = text_rate
		if write_vol < -10:
			write_vol = -10
		write_vol += delta * 200.0
		if write_vol > 10:
			write_vol = 10
		
	write["volume_db"] = write_vol
		
	main_text["text"] = true_text
	
	timer_switchover -= delta
	
	if timer_switchover < 0 and choice_pos == 3 and \
		game_pos == 1 and not punchline_trigger:
		target_text += punchlines[rng.randi_range(0, punchlines.size()-1)]
		punchline_time = punchline_rate
		punchline_trigger = true
		mumbles[rng.randi_range(0, mumbles.size()-1)]["playing"] = true
		player["parameters/StateMachine 2/conditions/talk"] = true
		#parameters/StateMachine 2/conditions/talk
		#print(target_text)
		
	punchline_time -= delta
	
	if punchline_time < 0 and punchline_trigger and game_pos == 1:
		game_pos = 2
		player["parameters/StateMachine/conditions/end_line"] = true
		crowd_time = crowd_period
		cheering = false
		as_targ = -1.0
		as_pos = -1.0
		
	if game_pos == 2:
		crowd_time -= delta
		#print(crowd_time)
		
		aud1.clear_all_params()
		aud2.clear_all_params()
		aud3.clear_all_params()
		aud4.clear_all_params()
		
		if not cheering and crowd_time < cheer_point:
			var score = get_score()
			
			if score == 6:
				won = true
				crowd_time = 100000
				score_obj["text"] = "You won in " + str(turns+1) + " turns!"
			else:
				player["parameters/StateMachine/conditions/card_look"] = true

			aud1.set_reaction(score, 1.0)
			aud2.set_reaction(score, 1.0)
			aud3.set_reaction(score, 1.0)
			aud4.set_reaction(score, 1.0)
			cheering = true
			
			audience_reactions[score]["playing"] = true
			
			turns+=1
			
			as_targ = 1.0
			as_text["text"] = "Audience Score: " + str(score)
			
			print("cheer")
			
			prev_choices.push_back([first_choice, second_choice, third_choice, score])
			
		if crowd_time < 0:
			reset_turn()
