extends Area2D

# signals
signal update_display # tells parent to update points display
signal refund # will tell parent a refund is occuring, for display
signal shooting_speed_upgrade # signals that a shooting speed upgrade has occured
signal ship_speed_upgrade 
signal other_shooting_upgrade
signal other_ship_speed_upgrade
signal shooting_speed_fully_upgraded
signal ship_speed_fully_upgraded
signal restart_game
signal multiplayer_movement

export (PackedScene) var Laser

################################
# THINGS THAT MAY NEED ADJUSTING
#################################

# first 5 tiers of shooting speed
const BULLET_DELAY_TIER1 = 0.8
const BULLET_DELAY_TIER2 = 0.5
const BULLET_DELAY_TIER3 = 0.2
const BULLET_DELAY_TIER4 = 0.1
const BULLET_DELAY_TIER5 = 0.05

# starting cost of shooting speed upgrades after tier 5
const SHOOTING_SPEED_UPGRADE_DEFAULT = 1500

# can't shoot faster than this
const BULLET_DELAY_MINIMUM = 0.01

# costs of shooting speed upgrades
const BULLET_DELAY_TIER2_COST = 100
const BULLET_DELAY_TIER3_COST = 200
const BULLET_DELAY_TIER4_COST = 400
const BULLET_DELAY_TIER5_COST = 1000

# the 5 tiers of ship speed
const SHIP_SPEED_TIER1 = 150
const SHIP_SPEED_TIER2 = 200
const SHIP_SPEED_TIER3 = 300
const SHIP_SPEED_TIER4 = 500
const SHIP_SPEED_TIER5 = 800

# costs of ship speed upgrades
const SHIP_SPEED_TIER2_COST = 200
const SHIP_SPEED_TIER3_COST = 400
const SHIP_SPEED_TIER4_COST = 600
const SHIP_SPEED_TIER5_COST = 800

# the ship's starting position
const STARTING_POSITION = Vector2(100, 250)

# the amount of money the player starts with
const STARTING_MONEY = 100

#################################

# set sliding shooting speed upgrade costs
var shooting_speed_upgrade = SHOOTING_SPEED_UPGRADE_DEFAULT

# used to limit player movement
var screensize

# can the player shoot at this instant
var can_shoot = false

# timer for shooting speed
var timer = null

# sets ship movement speed to the default
var ship_speed = SHIP_SPEED_TIER1
var ship_speed_tier = 0

# sets the delay between shots to the default
var bullet_delay = BULLET_DELAY_TIER1
var bullet_delay_tier = 0

# sets other shooting settings to their defaults
var laser_penetration = 0
var double_laser = false

# gives the player their starting points
var money = STARTING_MONEY

# sets initial value of ship, to be added to with upgrades for refunds
var ship_value = 0

# what percentage of points should be returned on refunding
var refund_percentage = 1

# is a menu open? try to ignore input in-game
# only really relevant to touchscreens
var menu_open = false

# opens the upgrade menu
func upgradeMenu():
	menu_open = true
	var upgmenu = preload("res://UpgradeMenu.tscn").instance()
	add_child(upgmenu)
	upgmenu.connect("refund", self, "_refund_button")
	upgmenu.connect("bullet_delay_upgrade", self, "upgradeBulletDelay_button")
	upgmenu.connect("ship_speed_upgrade", self, "upgradeShipSpeed_button")
	upgmenu.connect("double_laser_upgrade", self, "doubleLaserUpgrade_button")
	upgmenu.connect("laser_penetration_upgrade", self, "laserPenetrationUpgrade_button")
	upgmenu.connect("menu_closed", self, "menuClosed")
	upgmenu.bullet_delay_tier = bullet_delay_tier
	upgmenu.ship_speed_tier = ship_speed_tier
	if !get_tree().has_network_peer():
		get_tree().paused = true

# signalled on close of UpgradeMenu
func menuClosed():
	menu_open = false

#######################
# REQUESTING UPGRADES #
#######################
# all will request their upgrade
# all will pause the game if not in multiplayer

func doubleLaserUpgrade_button():
	doubleLaserUpgrade()
	emit_signal("update_display")
	if !get_tree().has_network_peer():
		get_tree().paused = true

func laserPenetrationUpgrade_button():
	laserPenetrationUpgrade()
	emit_signal("update_display")
	if !get_tree().has_network_peer():
		get_tree().paused = true

func upgradeShipSpeed_button():
	upgradeShipSpeed()
	emit_signal("update_display")
	if !get_tree().has_network_peer():
		get_tree().paused = true

func upgradeBulletDelay_button():
	upgradeBulletDelay()
	emit_signal("update_display")
	if !get_tree().has_network_peer():
		get_tree().paused = true

#######################


######################
# PROVIDING UPGRADES #
######################
# checks which tier the player is already on, and if they have enough points
# upgrades and charges the player, if possible
# increases the ship value by the amount spent, for refunds
# sends an rpc message about current state for a given upgrade

# upgrades shooting speed
func upgradeBulletDelay():
	if (bullet_delay == BULLET_DELAY_TIER1 && money >= BULLET_DELAY_TIER2_COST):
		bullet_delay = BULLET_DELAY_TIER2
		money -= BULLET_DELAY_TIER2_COST
		ship_value += BULLET_DELAY_TIER2_COST
		bullet_delay_tier = 1
	elif (bullet_delay == BULLET_DELAY_TIER2 && money >= BULLET_DELAY_TIER3_COST):
		bullet_delay = BULLET_DELAY_TIER3
		money -= BULLET_DELAY_TIER3_COST
		ship_value += BULLET_DELAY_TIER3_COST
		bullet_delay_tier = 2
	elif (bullet_delay == BULLET_DELAY_TIER3 && money >= BULLET_DELAY_TIER4_COST):
		bullet_delay = BULLET_DELAY_TIER4
		money -= BULLET_DELAY_TIER4_COST
		ship_value += BULLET_DELAY_TIER4_COST
		bullet_delay_tier = 3
	elif (bullet_delay == BULLET_DELAY_TIER4 && money >= BULLET_DELAY_TIER5_COST):
		bullet_delay = BULLET_DELAY_TIER5
		money -= BULLET_DELAY_TIER5_COST
		ship_value += BULLET_DELAY_TIER5_COST
		bullet_delay_tier = 4
	elif (bullet_delay <= BULLET_DELAY_MINIMUM):
		emit_signal("bullet_delay_fully_upgraded")
	elif (bullet_delay <= BULLET_DELAY_TIER5 && money >= shooting_speed_upgrade):
		bullet_delay = bullet_delay*0.95
		money -= shooting_speed_upgrade
		ship_value += shooting_speed_upgrade
		shooting_speed_upgrade *= 1.1
		bullet_delay_tier += 1
	
	timer.set_wait_time(bullet_delay)
	rpc("other_shooting_speed_upgrade", get_tree().get_network_unique_id(), bullet_delay)

# upgrades the speed at which the ship moves
# not relevant for touchscreen users
func upgradeShipSpeed():
	prints("func upgradeShipSpeed():")
	if (ship_speed == SHIP_SPEED_TIER1 && money >= SHIP_SPEED_TIER2_COST):
		ship_speed = SHIP_SPEED_TIER2
		money -= SHIP_SPEED_TIER2_COST
		ship_value += SHIP_SPEED_TIER2_COST
		ship_speed_tier = 1
	elif (ship_speed == SHIP_SPEED_TIER2 && money >= SHIP_SPEED_TIER3_COST):
		ship_speed = SHIP_SPEED_TIER3
		money -= SHIP_SPEED_TIER3_COST
		ship_value += SHIP_SPEED_TIER3_COST
		ship_speed_tier = 2
	elif (ship_speed == SHIP_SPEED_TIER3 && money >= SHIP_SPEED_TIER4_COST):
		ship_speed = SHIP_SPEED_TIER4
		money -= SHIP_SPEED_TIER4_COST
		ship_value += SHIP_SPEED_TIER4_COST
		ship_speed_tier = 3
	elif (ship_speed == SHIP_SPEED_TIER4 && money >= SHIP_SPEED_TIER5_COST):
		ship_speed = SHIP_SPEED_TIER5
		money -= SHIP_SPEED_TIER5_COST
		ship_value += SHIP_SPEED_TIER5_COST
		ship_speed_tier = 4
	
	prints(ship_speed)

######################

func _ready():
	# for measuring time between lasers
	timer = Timer.new()
	timer.set_one_shot(true)
	timer.set_wait_time(bullet_delay)
	timer.connect("timeout", self, "on_timeout_complete")
	add_child(timer)
	timer.start()
	
	# set player's position to the default
	position = STARTING_POSITION
	
	# sets screensize to prevent player leaving screen
	screensize = get_viewport_rect().size
	
	# starts the ship's rocketing animation
	$AnimatedSprite.play()

# resets all upgrades to the default
# refunds them with adjustable percentage returned
func _refund_button():
	bullet_delay = BULLET_DELAY_TIER1
	bullet_delay_tier = 0
	timer.set_wait_time(bullet_delay)
	ship_speed = SHIP_SPEED_TIER1
	laser_penetration = 0
	double_laser = false
	shooting_speed_upgrade = SHOOTING_SPEED_UPGRADE_DEFAULT
	money += ship_value*refund_percentage
	prints("Refunded ", ship_value*refund_percentage)
	ship_value = 0
	emit_signal("update_display")
	get_tree().paused = true

func on_timeout_complete():
	can_shoot = true

var is_shooting

func moveto(finger_position):
	if !menu_open:
		if (finger_position.x > position.x && finger_position.x < 800):
			velocity.x += 1
		if position.x > finger_position.x:
			velocity.x -= 1
		if (finger_position.y - 100 > position.y && finger_position.x < 800):
			velocity.y += 1
		if (position.y > finger_position.y - 100 && finger_position.x < 800):
			velocity.y -= 1

remote func move_player(id, position, is_shooting):
	emit_signal("multiplayer_movement", id, position, is_shooting)

remote func other_shooting_speed_upgrade(id, bullet_delay):
	emit_signal("other_shooting_upgrade", id, bullet_delay)

# the player's movement vector
var velocity = Vector2()

func _process(delta):
	# move player with keyboard
	velocity = Vector2()
	if Input.is_action_pressed("ui_right"):
		velocity.x += 1
	if Input.is_action_pressed("ui_left"):
		velocity.x -= 1
	if Input.is_action_pressed("ui_down"):
		velocity.y += 1
	if Input.is_action_pressed("ui_up"):
		velocity.y -= 1
	if (velocity.length() > 0):
		velocity = velocity.normalized() * ship_speed
	position += velocity * delta
	
	# prevents player leaving the screen
	position.x = clamp(position.x, 0, screensize.x)
	position.y = clamp(position.y, 0, screensize.y)
	
	# basically exists just for rpc messages about whether or not the player is currently firing
	if can_shoot:
		is_shooting = false
	else:
		is_shooting = true
	
	# if in multiplayer mode, push position and shooting status as often as possible
	if get_tree().has_network_peer():
		rpc_unreliable("move_player", get_tree().get_network_unique_id(), position, is_shooting)
	
	# if shoot button is pressed, try shooting
	if Input.is_action_pressed("ui_accept"):
		shoot()
	
	# ui_reset button opens the upgrade menu
	if Input.is_action_pressed("ui_reset"):
		upgradeMenu()

# spawn lasers to shoot
# lasers can be set to penetrate or not
# can fire two lasers at once if double_laser is on
func shoot():
	if can_shoot:
		var laser = Laser.instance()
		get_node("../").add_child(laser)
		laser.current_pen = laser_penetration
		laser.position.y = position.y - 27
		laser.position.x = position.x + 46
		
		#MAYBE THE LASERS SHOULD BE THEIR OWN NODES
		#Would allow for more simple additions in the future
		if double_laser == true:
			var laser2 = Laser.instance()
			get_node("../").add_child(laser2)
			laser2.position.y = position.y + 28
			laser2.position.x = position.x + 46
			laser2.current_pen = laser_penetration
			
		# don't shoot again until the timer resets 
		can_shoot = false
		timer.start()

# displays endgame screen and pauses
func gameOver():
	var gameover = preload("res://GameOver.tscn").instance()
	add_child(gameover)
	gameover.connect("restart", self, "restart_game")
#	gameover.connect("bullet_delay_upgrade", self, "upgradeBulletDelay_button")
	get_tree().paused = true

# uses refund function to remove upgrades
# sets points back to default
func restart_game():
	_refund_button()
	get_tree().paused = false
	money = STARTING_MONEY
	emit_signal("restart_game")