#!/usr/bin/python

from sys import stdout
from PySFML import *
from random import random
import time as timec
import copy

'''
 _         _         _   _            _      _ _   _ 
| |    ___| |_ ___  | | | | __ _  ___| | __ (_) |_| |
| |   / _ \ __/ __| | |_| |/ _` |/ __| |/ / | | __| |
| |__|  __/ |_\__ \ |  _  | (_| | (__|   <  | | |_|_|
|_____\___|\__|___/ |_| |_|\__,_|\___|_|\_\ |_|\__(_)
                                                     
http://letshackit.energylabs.com.br

Lucas Teske
'''

emptypiece = [	" ", " ", " ",
				" ", " ", " ",
				" ", " ", " "	]

pieces = [ 
	[	"#", " ", " ", 
		"#", " ", " ", 
		"#", "#", "#" 	],
	
	[	"#", "#", " ",
		" ", "#", " ",
		" ", "#", "#"	],

	[	" ", "#", "#",
		" ", "#", " ",
		"#", "#", " "	],

	[	" ", "#", " ",
		" ", "#", " ",
		" ", "#", " "	],

	[	"#", "#", "#", 
		"#", "#", "#", 
		"#", "#", "#" 	]
]	

colors	=	[
	"\033[31m",
	"\033[32m",
	"\033[33m",
	"\033[34m",
	"\033[35m",
	"\033[36m",
	"\033[37m"
]

screen_text = '''
 _____ _____ _____ ____  ___ ____  
|_   _| ____|_   _|  _ \|_ _/ ___| 
  | | |  _|   | | | |_) || |\___ \ 
  | | | |___  | | |  _ < | | ___) |
  |_| |_____| |_| |_| \_\___|____/          
                     
TTTTTTTTTTTXTTTTTTTTTTTTTTTTTTTTTTTTX
T          T                        T
T   PPP    T                        T
T   PPP    T                        T
T   PPP    T                        T
T          T                        T
T          T                        T
T          T                        T
T          T                        T
T          T                        T
T          T                        T
T  SCORE   T                        T
T 00000000 T                        T
T          T                        T
T          T                        T
TTTTTTTTTTTXTTTTTTTTTTTTTTTTTTTTTTTTX
'''
ctr = screen_text.split("\n")
scr	=	[ [ (ctr[y][x] if (len(ctr) > (y) ) and (len(ctr[y]) > x) and not "P" in ctr[y][x] else " ") for x in range(38) ] for y in range(23) ] 
scr[0][0] = "\033[0m\033[31m"
scr[6][0] = "\033[0m"

window = sf.RenderWindow(sf.VideoMode(100, 100), "TETRIS")
input = window.GetInput()
acpxy = [ 0 , -2 ]
actualpiece = (pieces[int(round(random()*(len(pieces)-1)))], colors[int(round(random()*(len(colors)-1)))])
lasttime = round(timec.time()*1000)
deltatime = 0

gamecoord = [ (0,0),(0,0),(0,0),(0,0) ]
x = 0
y = 0
xmax = 37
p = 0

screen_base = copy.deepcopy(scr)

time = round(timec.time()*1000)

nextpiece = (pieces[int(round(random()*(len(pieces)-1)))], colors[int(round(random()*(len(colors)-1)))])

starttime = round(timec.time()*1000)
stdout.write("\033[2J\033[;H")

def prnscr(screen):
	for line in screen:
		for column in line:
			stdout.write(column)
		stdout.write("\n")


for line in scr:
	for char in line:
		if char == "X":
			gamecoord[p] = (x,y)
			p = p + 1
		x = x + 1
		if x > xmax:
			x = 0
			y = y + 1

for y in range(len(screen_base)):
	for x in range(len(screen_base[y])):
		if "X" in screen_base[y][x] or screen_base[y][x] == "T":
			screen_base[y][x] = "\033[107mO\033[0m"

def SetXY( screen , x , y , char, color = None ):
	y = y + gamecoord[0][1]
	x = x + gamecoord[0][0] + 1
	
	if y < len(screen) and x < len(screen[0]) and x > 1 and y > 7:
		if not screen[y][x] == ['O']: 
			if not color == None:
				screen[y][x] = "%s%s%s" % (color, char, "\033[0m")			
			else:
				screen[y][x] = char
	return screen 

def SetRawXY( screen, x, y, char, color=None):
	if y < len(screen) and x < len(screen[0]): 
		if not color == None:
			screen[y][x] = "%s%s%s" % (color, char, "\033[0m")			
		else:
			screen[y][x] = char
	return screen 

def WritePiece(screen, x, y, piece, f=SetXY, color=None, Force=False):
	x = x
	y = y
	ax = 0
	ay = 0	
	for c in piece:
		if ((y+ay >= 0) or (x+ax > 0)) and not (c ==' ' and not Force):
			f(screen, x+ax, y+ay, c, color)
		if ax == 2:
			ay = ay + 1
			ax = 0	
		else:
			ax = ax + 1
	return screen

def RotateRight(piece):
	return [	piece[6], piece[3], piece[0],
				piece[7], piece[4], piece[1],
				piece[8], piece[5], piece[2]	]

def RotateLeft(piece):
	return [	piece[2], piece[5], piece[8],
				piece[1], piece[4], piece[7],
				piece[0], piece[3], piece[6]	]

def CheckPieceCollision(scr, acpxy):
	'''
				0					1				2
				3					4				5
				6					7				8
		(px		,	py	)	(px+1	,	py	)	(px+2	,	py	)
		(px		,	py+1)	(px+1	,	py+1)	(px+2	,	py+1)
		(px		,	py+2)	(px+1	,	py+2)	(px+2	,	py+2)
	
	'''
	px 	= 	int(acpxy[0]) + gamecoord[0][0]+1
	py 	=	int(acpxy[1]) + gamecoord[0][1]+1
	print (px,py,acpxy)
	return 		(( 	not scr[py][px]		==	" "	and not ( scr[py][px]		== "O" and	(acpxy[1] <= 4)	)	) 	and	("#" in actualpiece[0][0]	))  or 	\
				(( 	not scr[py][px+1]	==	" "	and not ( scr[py][px+1]		== "O" and	(acpxy[1] <= 4)	)	)	and	("#" in actualpiece[0][1]	))	or	\
				((	not scr[py][px+2]	==	" "	and not ( scr[py][px+2]		== "O" and	(acpxy[1] <= 4)	)	)	and	("#" in actualpiece[0][2]	))	or	\
				(( 	not scr[py+1][px]	==	" "	and not ( scr[py+1][px]		== "O" and	(acpxy[1] <= 4)	)	) 	and	("#" in actualpiece[0][3]	))  or	\
				(( 	not scr[py+1][px+1]	==	" "	and not ( scr[py+1][px+1]	== "O" and	(acpxy[1] <= 4)	)	)	and	("#" in actualpiece[0][4]	))	or	\
				((	not scr[py+1][px+2]	==	" "	and not ( scr[py+1][px+2]	== "O" and	(acpxy[1] <= 4)	)	)	and	("#" in actualpiece[0][5]	))	or	\
				(( 	not scr[py+2][px]	==	" "	and not ( scr[py+2][px]		== "O" and	(acpxy[1] <= 4)	)	) 	and	("#" in actualpiece[0][6]	))  or 	\
				(( 	not scr[py+2][px+1]	==	" "	and not ( scr[py+2][px+1]	== "O" and	(acpxy[1] <= 4)	)	)	and	("#" in actualpiece[0][7]	))	or	\
				((	not scr[py+2][px+2]	==	" "	and not ( scr[py+2][px+2]	== "O" and	(acpxy[1] <= 4)	)	)	and	("#" in actualpiece[0][8]	))

def CheckLineBreak(scr):
	'''
		x	:	0	->	24
		y	:	0	->	13
	'''
	lbreak = [ False for i in range(13) ]
	for y in range(24):
		lbreak[y] = True
		for x in range(13):
			lbreak[y] = lbreak[y] and ("#" in scr[y][x])
		


while True:
	deltatime = round(timec.time()*1000) - lasttime
	lasttime = round(timec.time()*1000)
	keypressed = False
	event = sf.Event()
	while window.GetEvent(event):
		if event.Type == sf.Event.KeyPressed:
			#	Process Keyboard P1 Inputs
			keypressed = True
			if event.Key.Code == sf.Key.Left:
				acpxy[0] = acpxy[0] - 1 if (acpxy[0] > 0) and not (CheckPieceCollision(screen_base, [acpxy[0]-1, acpxy[1]] )) else acpxy[0]
			if event.Key.Code == sf.Key.Right:
				acpxy[0] = acpxy[0] + 1 if (acpxy[0] < 21) and not (CheckPieceCollision(screen_base, [acpxy[0]+1, acpxy[1]] )) else acpxy[0]
			if event.Key.Code == sf.Key.Z:
				actualpiece = (RotateRight(actualpiece[0]),actualpiece[1])

	screen = copy.deepcopy(screen_base)
	screen = WritePiece(screen, 4, 9, emptypiece, SetRawXY, None, True)
	screen = WritePiece(screen, 4, 9, nextpiece[0], SetRawXY, nextpiece[1])
	screen = WritePiece(screen, int(acpxy[0]) , int(acpxy[1]), actualpiece[0], SetXY, actualpiece[1])
	stdout.write("\033[2J\033[;H\033[0m")		

	prnscr(screen)

	stdout.flush()
	window.Display()
	if	CheckPieceCollision(screen_base, acpxy):
		screen_base = WritePiece(screen, int(acpxy[0]) , int(acpxy[1]), actualpiece[0], SetXY, actualpiece[1])
		acpxy = [ 0 , 0 ]
		actualpiece = nextpiece
		nextpiece = (pieces[int(round(random()*(len(pieces)-1)))], colors[int(round(random()*(len(colors)-1)))])
	else:
		acpxy[1] = acpxy[1] + deltatime / 300.0

	timec.sleep(0.1)