#
# Copyright (C) 2018  Sage Vaillancourt, sagev9000@gmail.com
#
# This file is part of Fronter.
# 
# Fronter is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# Fronter is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Fronter.  If not, see <http://www.gnu.org/licenses/>.
#

extends Node

export (PackedScene) var FirstBad
export (PackedScene) var BlobBad
export (PackedScene) var LaserBad
export (PackedScene) var Prison
export (PackedScene) var RectangleBoss
export (PackedScene) var BlackHole

var players = {}

var position = Vector2(200, 200)
var bads_this_round = 0
var upgrade_cost = 50
var booting = true
var screen_flashing = false
var rectangle_opacity = 1
var bad_spawning_enabled = true
var player_info
var touchy_shooty = false
var my_info = { name = "sagethesagesage", color = "FFFFFF" }
var mainmenu

var not_loading = false

const BADDIE_WAIT_TIME_DEFAULT = 4

func _ready():
	# Prepare black rectangle for fading in
	$ColorRect.visible = true
	
	if OS.has_touchscreen_ui_hint():
		$HowTo.visible = true
	else:
		$HowToDesktop.visible = true
	
	# Launch the main menu on boot and pause the game
	mainmenu = preload("res://MainMenu.tscn").instance()
	add_child(mainmenu)
	mainmenu.connect("multiplayer_menu", self, "_open_multiplayer_menu")
	get_tree().paused = true
	
	# Prepare timer for spawning enemies
	$BaddieTimer.wait_time = BADDIE_WAIT_TIME_DEFAULT
	$BaddieTimer.start()
	
	# Seed randi for randomizing enemy spawn locations
	randomize()

# Open the multiplayer section of the menu and pause the game
func _open_multiplayer_menu():
	var multiplayer = preload("res://Networking.tscn").instance()
	multiplayer.connect("player_info", self, "_load_players")
	multiplayer.connect("start_multiplayer_game", self, "_start_multiplayer_game")
	add_child(multiplayer)
	multiplayer.setName(my_info.name)
	get_tree().paused = true

func _process(delta):
	# If L+R+A+Start is pressed on a controller, quit
	if (Input.is_action_pressed("ctlr_l")):
		if (Input.is_action_pressed("ctlr_r")):
			if (Input.is_action_pressed("ctlr_a")):
				if (Input.is_action_pressed("ctlr_start")):
					get_tree().quit()
	# If the quit button is pressed, do it
	if (Input.is_action_pressed("ui_quit")):
		get_tree().quit()
	
	if Input.is_action_pressed("ui_right") || Input.is_action_pressed("ui_left"):
		_on_HideHowTo_pressed()
	if Input.is_action_pressed("ui_down") || Input.is_action_pressed("ui_up"):
		_on_HideHowTo_pressed()
	if Input.is_action_pressed("ui_accept"):
		_on_HideHowTo_pressed()
	
	# Constantly update point display
	updatePoints()
	
	# If you're in multiplayer,
	if get_tree().has_network_peer():
		# and not the host
		if !get_tree().is_network_server():
			# Stop spawning bads
			$BaddieTimer.stop()
	
	if (touchy_feely && (abs(touchy_feely.position.x - $Player.position.x) > 1)):
		if (touchy_feely.position.x < 800):
			$Player.moveto(touchy_feely.position)
	
	if (touchy_shooty && $Player.can_shoot):
		$Player.shoot()
	
	# If we're in the booting process, fade out the rectangle
	if booting == true:
		$ColorRect.color = Color(0, 0, 0, rectangle_opacity)
		rectangle_opacity -= delta/1.25
		if rectangle_opacity <= 0:
			booting = false
			$ColorRect.visible = false
	
	# Flash the screen white
	if screen_flashing == true:
		$ColorRect.color = Color(1, 1, 1, rectangle_opacity)
		rectangle_opacity -= delta/4
		if rectangle_opacity <= 0:
			screen_flashing = false
			$ColorRect.visible = false

# When an enemy dies
func _on_bad_death(kill_money):
	# Give players appropriate money
	$Player.money += kill_money

#########################
# ENEMY SPAWNING SCRIPT #
#########################
var a_round_of_bads = 50
var sendblob = 1
var bad_health_multi = 1.5
var total_bads_spawned = 0
func BaddieTimer():
	if total_bads_spawned == 5: # 75 default
		if get_tree().is_network_server():
			total_bads_spawned += 1
			rpc("bossMode")
		else:
			total_bads_spawned += 1
			bossMode()
	
	if bads_this_round <= a_round_of_bads && bad_spawning_enabled:
		var bad_type
		var badposition = Vector2()
		
		if sendblob%50 == 0:
			bad_type = 3
			sendblob += 1
		elif sendblob%20 == 0:
			bad_type = 2
			sendblob += 1
		elif sendblob%5 == 0:
			bad_type = 1
			sendblob += 1
		else:
			bad_type = 0
			sendblob += 1
		
		bads_this_round += 1
		if $BaddieTimer.wait_time > 1:
			$BaddieTimer.wait_time = $BaddieTimer.wait_time * 0.99
		if bads_this_round == a_round_of_bads:
			bad_health_multi *= 1.5
		
		badposition.x = 1200
		badposition.y = (randi()%410) + 50
		if get_tree().is_network_server():
			rpc("spawnBad", bad_type, badposition, bad_health_multi)
		else:
			spawnBad(bad_type, badposition, bad_health_multi)
	else:
		bads_this_round = 0

sync func spawnBad(bad_type, position, health_multi):
	var bad 
	if bad_type == 0:
		bad = FirstBad.instance()
	if bad_type == 1:
		bad = BlobBad.instance()
	if bad_type == 2:
		bad = LaserBad.instance()
	if bad_type == 3:
		bad = Prison.instance()
	
	# Increase BG speed with each enemy spawned
	$BG.fly_speed *= 1.01
	
	# Add one to total of enemies spawned
	total_bads_spawned += 1
	
	add_child(bad)
	bad.connect("dead", self, "_on_bad_death")
	if bad_type == 3:
		bad.connect("health_up", self, "_on_health_up")
	bad.health_multi = health_multi
	bad.position = position

func _on_health_up(hp_increase):
	$Mothership.health += hp_increase
	$Mothership._update_health_bar()

func _on_PauseButton_pressed():
	$Player.upgradeMenu()

func updatePoints():
	$MoneyDisplay.text = str($Player.money, " points")

func _on_Player_update_display():
	updatePoints()

func _on_Mothership_game_over():
	$ShootButton.visible = false
	$Player.gameOver()

func _on_Player_restart_game():
	for child in self.get_children():
		if (child.has_method("_on_Visibility_screen_exited")):
			child.queue_free()
		if (child.has_method("bossHealth")):
			child.queue_free()
	bads_this_round = 0
	total_bads_spawned = 0
	$BaddieTimer.wait_time = BADDIE_WAIT_TIME_DEFAULT
	$ShootButton.visible = true

var touchy_feely

var touchscreen_on = false
func _input(event):
	if (event is InputEventScreenTouch || event is InputEventScreenDrag):
		touchscreen_on = true
		if event.position.x < 800: #&& (abs (event.position.y - $Player.position.y) < 100) :
			$Player.position.x = event.position.x + 100*(event.position.x/800)
			$Player.position.y = event.position.y - 100
			prints(event.index)
		else:
			touchy_shooty = true

func other_shooting_upgrade(id, other_bullet_delay):
	prints("Other player shooting speed upgrade")
	get_node(str(id)).timer.set_wait_time(other_bullet_delay)

func other_ship_color_change(id, other_color):
	prints("Other player color change")
	get_node(str(id)).modulate(other_color)

func double_laser_upgrade(id):
	prints("Double laser upgrade for", id)
	get_node(str(id)).double_laser = true

# Show other player's movement
func _on_Player_multiplayer_movement(id, pos, other_is_shooting):
	get_node(str(id)).position = pos
	
	if other_is_shooting:
		get_node(str(id)).shoot()

# BOSS MODE #
# Disable enemy spawning
# Wait a few seconds for enemies to clear
# Call for boss launch
var bosstimer = null
sync func bossMode():
	prints("bossMode()")
	bad_spawning_enabled = false
	bosstimer = Timer.new()
	bosstimer.connect("timeout",self,"_launch_boss") 
	add_child(bosstimer) #to process
	bosstimer.wait_time = 15
	bosstimer.one_shot = true
	bosstimer.start() #to start

# Spawn the first boss
func _launch_boss():
	prints("_launch_boss()")
	var bad 
	#bad = RectangleBoss.instance()
	bad = BlackHole.instance()
	add_child(bad)
	
	# Flash screen when signalled
	bad.connect("flash", self, "_flash_screen")
	bad.show_behind_parent = true
	
	# Boss death functions the same as regular death
	bad.connect("dead", self, "_on_boss_death")
	
	# Get boss health
	bad.connect("boss_health", self, "getBossHealth")

func getBossHealth(currentHealth, totalHealth):
	totalHealth = float(totalHealth)
	var health_bar = Vector2(((currentHealth/totalHealth)*800)+100, 50)
	$BossHealth.set_point_position(1, health_bar)
	$BossHealth.default_color.a = 1
	if currentHealth <= 0:
		$BossHealth.default_color.a = 0
	pass

# Currently same as regular enemy death
func _on_boss_death(kill_money):
	# Give players appropriate money, and restart spawns
	$Player.money += kill_money
	bad_spawning_enabled = true
	bosstimer.stop()

# Begins screen-flashing process
func _flash_screen():
	prints("_flash_screen")
	screen_flashing = true
	rectangle_opacity = 1
	$ColorRect.visible = true

func _load_players(id, info):
	player_info = info
	prints("_load_players", player_info)
	#prints(player_info[id].name, "YEET", player_info[id].color)

func _start_multiplayer_game():
	print(player_info)
	mainmenu.now_quitting = true
	for peer_id in player_info:
		if peer_id != get_tree().get_network_unique_id():
			var player = preload("res://OtherPlayer.tscn").instance()
			player.set_name(str(peer_id))
			prints(str(peer_id), "yeetert")
			add_child(player)
			#get_node("/").add_child(player)
			player.setUsername(player_info[peer_id].name)
			#$MultiplayerTimer.start()

func _on_HideHowTo_pressed():
	$HowTo.visible = false
	$HowToDesktop.visible = false
	$HideHowTo.visible = false

func _on_Player_other_ship_enable_rainbow(id):
	prints("Other player entered rainbow mode")
	get_node(str(id)).enable_the_rainbow()