# Path: tinygame/character_display.py
# ESCAPE = chr(27)
# 
# CSI = ESCAPE + "[" # control sequences are started by writing a special sequence of characters to the terminal known as a Control Sequebce Introducer (CSI)


import termios	# module get and set terminal attributes
import fcntl	# module to manipulate a file descriptor (ie the standard input file descriptor)
import sys, os	# opersting system wrapper module
import select	# a module exposing the lowleve select() call which allows a program to monitor multiple file  descriptors,  waiting  until  one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible).
from tinygame.character_display import ESCAPE, CSI # we read ANSI escape sequences for special keys similar to printing them for display. See character_display.py

	__old_attributes = termios.tcgetattr(__keyboard_file_descriptor) # read the old attributes
	__new_attributes = __old_attributes[:] # make a copy of the attributes using the slice operator for list copy
	__new_attributes[3] = __new_attributes[3] & ~termios.ICANON & ~termios.ECHO # turn off canonical mode and character echo for the keyboard
	termios.tcsetattr(__keyboard_file_descriptor, termios.TCSANOW, __new_attributes) # commit the changed attributes

	__old_flags = fcntl.fcntl(__keyboard_file_descriptor, fcntl.F_GETFL) # get the old flags
	fcntl.fcntl(__keyboard_file_descriptor, fcntl.F_SETFL, __old_flags | os.O_NONBLOCK) # turn off non-blocking mode. IMPORTANT! This will allow us to check for keyboard input but continue handling the game without waiting for user input

def getch(timeout = 0):
	"""
	Reads one most resent key hit by the user.

	Styled after the getch() function in <conio.h> in C
	It is a nonblocking call to read the keyboard. You call it and wait for a maximum amount of time for a key press. If a key has already been pressed it returns immediately.
	The name can be misleading since key hits are sometimes escape sequences containing several characters. eg ESC[A is the Up key. Nevertheless the most recent full key character string is returned

	timeout: a floating point value representing the maximum amount of time (in second units) to wait for a key press. If it is 0, the function returns immediately and reports the most recent key
	return: a string representing the key pressed may be None if no key was pressed. eg 'x' for the x key or 'ESC[A' for the up arrow key
	"""
	# since there is only one keyboard we store keyboard in these global variables
	global __keyboard_file_descriptor # the filedesciptor of standard input (keyboard)

	r, w, e = select.select([__keyboard_file_descriptor], [], [], timeout) # wait at most timeout for reads to be available on standard input
	if r: # check if it returned because input is available
		q = sys.stdin.read() # if so read a key from standard in
		tokens = q.split(CSI) # get escape sequences
		if len(tokens) == 1: # check if there is no escape sequence
			return tokens[0] # if so simply return the key
		else:

# Path: tinygame/character_display.py
# ESCAPE = chr(27)
# 
# CSI = ESCAPE + "[" # control sequences are started by writing a special sequence of characters to the terminal known as a Control Sequebce Introducer (CSI)


# Path: tinygame/keyboard.py
import termios	# module get and set terminal attributes
import fcntl	# module to manipulate a file descriptor (ie the standard input file descriptor)
import sys, os	# opersting system wrapper module
import select	# a module exposing the lowleve select() call which allows a program to monitor multiple file  descriptors,  waiting  until  one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible).
from tinygame.character_display import ESCAPE, CSI # we read ANSI escape sequences for special keys similar to printing them for display. See character_display.py


	__old_attributes = termios.tcgetattr(__keyboard_file_descriptor) # read the old attributes
	__new_attributes = __old_attributes[:] # make a copy of the attributes using the slice operator for list copy
	__new_attributes[3] = __new_attributes[3] & ~termios.ICANON & ~termios.ECHO # turn off canonical mode and character echo for the keyboard
	termios.tcsetattr(__keyboard_file_descriptor, termios.TCSANOW, __new_attributes) # commit the changed attributes

	__old_flags = fcntl.fcntl(__keyboard_file_descriptor, fcntl.F_GETFL) # get the old flags
	fcntl.fcntl(__keyboard_file_descriptor, fcntl.F_SETFL, __old_flags | os.O_NONBLOCK) # turn off non-blocking mode. IMPORTANT! This will allow us to check for keyboard input but continue handling the game without waiting for user input

def getch(timeout = 0):
	"""
	Reads one most resent key hit by the user.

	Styled after the getch() function in <conio.h> in C
	It is a nonblocking call to read the keyboard. You call it and wait for a maximum amount of time for a key press. If a key has already been pressed it returns immediately.
	The name can be misleading since key hits are sometimes escape sequences containing several characters. eg ESC[A is the Up key. Nevertheless the most recent full key character string is returned

	timeout: a floating point value representing the maximum amount of time (in second units) to wait for a key press. If it is 0, the function returns immediately and reports the most recent key
	return: a string representing the key pressed may be None if no key was pressed. eg 'x' for the x key or 'ESC[A' for the up arrow key
	"""
	# since there is only one keyboard we store keyboard in these global variables
	global __keyboard_file_descriptor # the filedesciptor of standard input (keyboard)

	r, w, e = select.select([__keyboard_file_descriptor], [], [], timeout) # wait at most timeout for reads to be available on standard input
	if r: # check if it returned because input is available
		q = sys.stdin.read() # if so read a key from standard in
		tokens = q.split(CSI) # get escape sequences
		if len(tokens) == 1: # check if there is no escape sequence
			return tokens[0] # if so simply return the key
		else:

			return CSI + tokens[-1] # otherwise return only the most recent escape sequence