import display
from utime import sleep
from color import Color
import buttons
from array import array
import leds

UNUSED = 255 # Can be changed, just dont use 1 or 0 since those are the Player numbers

#Used for win counting
wins = array("i", [0,0])

# Configuration
FIELD_SIZE = 80
X_OFFSET = 40
Y_OFFSET = 0

#Split the field into nine rectangles
line = int(FIELD_SIZE / 3)
active_player = 0
position = 0

disp = display.open()
def reset_everything():
	global active_player
	global position
	global game_board
	disp.clear().update()
	# vertical lines
	disp.line(    line + X_OFFSET, Y_OFFSET,     line + X_OFFSET, FIELD_SIZE + Y_OFFSET)
	disp.line(2 * line + X_OFFSET, Y_OFFSET, 2 * line + X_OFFSET, FIELD_SIZE + Y_OFFSET)

	# horizontal lines
	disp.line(X_OFFSET,     line + Y_OFFSET, FIELD_SIZE + X_OFFSET,     line + Y_OFFSET)
	disp.line(X_OFFSET, 2 * line + Y_OFFSET, FIELD_SIZE + X_OFFSET, 2 * line + Y_OFFSET)

	disp.print("{:2}".format(wins[0]), posy=30 )
	disp.print("{:2}".format(wins[1]), posy=30, posx=(X_OFFSET + FIELD_SIZE +10) )

	game_board = array('i', [UNUSED, UNUSED, UNUSED , UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED])

	active_player = 0
	position = 0

reset_everything()
# Selecting a position
def select_position(position):
	global active_player
	game_board[position % 9] = active_player
	if (active_player):
		position_cross(position)
		active_player = 0
	else:
		position_circle(position)
		active_player = 1

def calc_x_and_y_from(position):
	x_pos = position %3
	y_pos = int((position / 3)) % 3
	return x_pos, y_pos

def handle_draw():
	disp.clear()
	disp.print("DRAW", posx=70, posy=30)
	disp.update()
	sleep(3)
	reset_everything()
	
def handle_victory():
	wins[active_player^1] += 1
	disp.clear()
	disp.print("Winner:", posy=20)
	disp.print("player {:1}!".format(active_player^1), posy=40 )
	disp.update()
	sleep(3)
	reset_everything()


def check_board_stats():
	i = 0
	for i in range(0, 3):
		#vertical checks
		if ((game_board[i] == game_board[i + 3]) and (game_board[i + 3] == game_board[i + 6]) and (game_board[i] != UNUSED)):
			handle_victory()

		c_pos = i * 3
		# horizontal checks
		if ((game_board[c_pos] == game_board[c_pos + 1]) and (game_board[c_pos +1 ] == game_board[c_pos +2]) and (game_board[c_pos] != UNUSED)):
			handle_victory()
	#diagonal stuff
	if ((game_board[0] == game_board[4]) and (game_board[4] == game_board[8]) and (game_board[0] != UNUSED)):
		handle_victory()

	if ((game_board[2] == game_board[4]) and (game_board[4] == game_board[6]) and (game_board[2] != UNUSED)):
		handle_victory()
	#draw detection
	for i in range(0,9):
		if (game_board[i] == UNUSED):
			i = 0
			break
	if (i == 8):
		handle_draw()

# Choosing
def process_button(position, pressed):
	x_pos, y_pos = calc_x_and_y_from(position)
	position_rectangle(x_pos, y_pos, Color.BLACK)
	if pressed & buttons.BOTTOM_LEFT != 0:
		position += 8
		while (game_board[position % 9] != UNUSED):
			position += 8
	if pressed & buttons.BOTTOM_RIGHT != 0:
		position += 1
	if pressed & buttons.TOP_RIGHT != 0:
		select_position(position)
		check_board_stats()
	while (game_board[position % 9] != UNUSED):
		position += 1
	x_pos, y_pos = calc_x_and_y_from(position)
	position_rectangle(x_pos, y_pos, Color.RED)
	return position

def position_rectangle(x_pos, y_pos, rec_color):
	x_start = X_OFFSET + 1 + (x_pos)     * line
	y_start = Y_OFFSET + 1 + (y_pos)     * line
	x_end   = X_OFFSET - 1 + (x_pos + 1) * line
	y_end   = Y_OFFSET - 1 + (y_pos + 1) * line
	disp.rect(x_start, y_start, x_end, y_end, col = rec_color)
	disp.update()

def position_circle(position):
	x_pos, y_pos = calc_x_and_y_from(position)
	radius = int(line/2) - 2		# Magic correction value
	x_center = X_OFFSET + radius + x_pos * line + 2
	y_center = Y_OFFSET + radius + y_pos * line + 2
	disp.circ(x_center, y_center, radius, col=Color.WHITE, filled=False)
	disp.update()

def position_cross(position):
	x_pos, y_pos = calc_x_and_y_from(position)
	x_start = X_OFFSET + 1 + (x_pos)     * line
	y_start = Y_OFFSET + 1 + (y_pos)     * line
	x_end   = X_OFFSET - 1 + (x_pos + 1) * line
	y_end   = Y_OFFSET - 1 + (y_pos + 1) * line
	disp.line(x_start, y_start, x_end, y_end, col=Color.WHITE)
	disp.line(x_start, y_end, x_end, y_start, col=Color.WHITE)
	disp.update()

#disp.rect(x_start, y_start, x_end, y_end, col=color.Color.BLACK)
position_rectangle(0, 0, Color.RED)

# show the stuff
while True:
	sleep(0.2)
	pressed = buttons.read(
		buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT
	)
	if pressed != 0:
		position = process_button(position, pressed)
