extends Node2D

signal buy(amount)
signal sell(amount)

const MAX_PRICES = 15

const Y_START = 60
const Y_END = 356
const X_START = 50
const X_END = 1000

var price_label
var shares_label
var top_label
var mid_label
var bottom_label
var darksouls_background: Sprite2D
var darksouls_text: Label

var price_history = []
var base_pos_mult = 0.5 # no size limit
var base_neg_mult = 0.5 # probably keep this below 1

var hype_mult = 1.0
var hype_decr = 0.1
var hype_inc = 0.05
var panic_mult = 1.0
var panic_decr = 0.1
var panic_inc = 0.01

var bailout_counter = 0
var bailout_time = 1

var bailout_price = Big.new(5)
var start_val = Big.new(5)
var prev_price = start_val

var shares = 0

func handle_bailout(new_price: Big) -> Big:
	if bailout_counter < bailout_time:
		new_price = Big.new(0)
		bailout_counter += 1
	else:
		darksouls_background.visible = true
		darksouls_text.visible = true
		darksouls_text.text = "Bailed Out"
		new_price = bailout_price
		bailout_counter = 0
		bailout_time *= 2
		panic_mult = 1.0
		hype_mult = 1.0
		
	return new_price
	
func draw_stonks(minval: Big, maxval: Big) -> void:
	var stonks: Line2D = $Stonks
	stonks.clear_points()
	
	var index = 0
	var x_delta = (X_END - X_START)/float(len(price_history)-1)
	var y_range = Big.new(Y_END - Y_START)
	var price_range = maxval.minus(minval)
	for price: Big in price_history:
		var x_pos = x_delta * index + X_START
		var y_pos = Y_END
		if price_range.isGreaterThan(0.001):
			var price_ratio = (price.minus(minval)).dividedBy(price_range)
			y_pos = float(Big.new(Y_END).minus(y_range.times(price_ratio)).toString())
		var pos = Vector2(x_pos, y_pos)
		stonks.add_point(pos, index)
		index += 1
		
	
func get_min_price() -> Big:
	var minval = Big.new(-1)
	for price in price_history:
		if price.isLessThan(minval) or minval.isLessThan(0):
			minval = price
	return minval
	
func get_max_price() -> Big:
	var maxval = Big.new(-1)
	for price in price_history:
		if price.isGreaterThan(maxval):
			maxval = price
	return maxval

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	price_label = $"Price Label"
	shares_label = $"Shares Held Label"
	top_label = $Top
	mid_label = $Middle
	bottom_label = $Bottom
	darksouls_background = $DarkSoulsTextBox
	darksouls_text = $DarkSoulsLabel
	
	price_label.text = "Price:\n$%s" % start_val.toString()
	price_history.push_front(start_val)
	
	shares_label.text = "Shares\nHeld:%d" % shares

 
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta: float) -> void:
	pass


func _on_timer_timeout() -> void:
	darksouls_background.visible = false
	darksouls_text.visible = false
	var new_price = prev_price
	
	hype_mult -= hype_decr
	if hype_mult < 1: hype_mult = 1.0
	
	panic_mult -= panic_decr
	if panic_mult < 1: panic_mult = 1.0
		
	if prev_price.isLessThanOrEqualTo(0):
		new_price = handle_bailout(new_price)
	elif randf() < 0.5:
		var mult = Big.new(1).plus(Big.new(base_pos_mult * hype_mult * randf()))
		new_price = new_price.times(mult)
	else:
		var mult = Big.new(1).minus(Big.new(base_neg_mult * panic_mult * randf()))
		new_price = new_price.times(mult)
		
	if new_price.isLessThan(1) or new_price.toString()[0] == '-':
		if bailout_counter == 0:
			darksouls_background.visible = true
			darksouls_text.visible = true
			darksouls_text.text = "Stock Bankrupt"
			new_price = Big.new(0)
			shares = 0
			shares_label.text = "Shares\nHeld:%d" % shares
			$AudioStreamPlayer.play()
			$ShakePivot.shake()
		
	if len(price_history) >= MAX_PRICES:
		price_history.pop_front()
	price_history.push_back(new_price)
	prev_price = new_price
	
	price_label.text = "Price:\n$%s" % new_price.toString()
	
	var min_price = get_min_price()
	var max_price = get_max_price()
	var mean_price = min_price.plus(max_price).dividedBy(2)
	
	top_label.text = "%s" % max_price.toScientific()
	mid_label.text = "%s" % mean_price.toScientific()
	bottom_label.text = "%s" % min_price.toScientific()
	
	draw_stonks(min_price, max_price)


func _on_buy_button_button_up() -> void:
	if shares < 100 and prev_price.isGreaterThan(0):
		shares += 1
		shares_label.text = "Shares\nHeld:%d" % shares
		hype_mult += hype_inc
		buy.emit(prev_price)


func _on_sell_button_button_up() -> void:
	if shares > 0:
		shares -= 1
		shares_label.text = "Shares\nHeld:%d" % shares
		panic_mult += panic_inc
		sell.emit(prev_price)
