import pygame, sys,os ,pickle
from pygame.locals import *
from random import *
from pickle import *

pygame.init()
if not pygame.font: 	print 'Warning, fonts disabled'
if not pygame.mixer: 	print 'Warning, sound disabled'

window = pygame.display.set_mode((160,160))
screen = pygame.Surface((160,160)).convert()
font = pygame.font.Font(None,20)
clock = pygame.time.Clock()
pygame.mouse.set_visible(1)
pygame.display.set_caption("ku")

########################################################################
#######################base function####################################
########################################################################


########################################################################
#######################image building###################################
########################################################################

image_score = []
for combo in  range(21) :
	image = font.render(str(combo),0,(255,128,128),(255,255,255)).convert()
	image.set_colorkey(image.get_at((0,0)), RLEACCEL)
	image_score.append(image)

try:   	background = pygame.image.load((os.path.join('data', 'clickeux.png'))).convert()
except pygame.error, message:
	background = pygame.Surface((160,160)).convert()
	background.fill((255,255,255))

try:	single_scale = pygame.image.load((os.path.join('data', 'single_scale.png'))).convert()
except pygame.error, message:
	single_scale = font.render("1x",0,(0,0,0),(255,255,255)).convert()
single_scale.set_colorkey(single_scale.get_at((0,0)), RLEACCEL)

try:	double_scale = pygame.image.load((os.path.join('data', 'double_scale.png'))).convert()
except pygame.error, message:
	double_scale = font.render("2x",0,(0,0,0),(255,255,255)).convert()
double_scale.set_colorkey(double_scale.get_at((0,0)), RLEACCEL)

try:	quad_scale = pygame.image.load((os.path.join('data', 'quad_scale.png'))).convert()
except pygame.error, message:
	quad_scale = font.render("4x",0,(0,0,0),(255,255,255)).convert()
quad_scale.set_colorkey(quad_scale.get_at((0,0)), RLEACCEL)

try:   	dead = pygame.image.load((os.path.join('data', 'dead.png'))).convert()
except pygame.error, message:
	dead = font.render("X",0,(255,0,0),(255,255,255)).convert()
dead.set_colorkey((255,255,255), RLEACCEL)

try:   	image_new_game = pygame.image.load((os.path.join('data', 'new_game.png'))).convert()
except pygame.error, message:
	image_new_game = font.render("new_game",0,(255,0,0),(255,255,255)).convert()
image_new_game.set_colorkey((255,255,255), RLEACCEL)
	
def blok_build(color):
	image = pygame.Surface((10,10)).convert()
	pygame.draw.rect(image,color,pygame.Rect(1,1,8,8),0)
	image.set_colorkey((255,255,255), RLEACCEL)
	return image

################################################################################################
##################################mouse sprite##################################################
################################################################################################

class spr_mice(pygame.sprite.Sprite):
	def __init__(self):
		pygame.sprite.Sprite.__init__(self)
		self.rect = pygame.Rect(0,0,0,0)
		self.screen_do = None
		self.mouse_do = None

	def update(self):
		(self.rect.x, self.rect.y) = pygame.mouse.get_pos()

spr_mice = spr_mice()

##################################################################################################
###################################THOSE BLOK#####################################################
##################################################################################################

grp_blok = pygame.sprite.RenderUpdates()

matrix_blok = []
for x in range(10):
	matrix_blok.append([])
	for y in range(17):
		matrix_blok[x].append(None)

class spr_blok(pygame.sprite.Sprite):
	def __init__(self, xpos, ypos, image, group, target):
		pygame.sprite.Sprite.__init__(self)
		self.image = image
		self.rect = self.image.get_rect().move(xpos,ypos)
		self.xdest, self.ydest = xpos,ypos
		self.group = group
		self.do = self.collapse
		self.target = target
		self.combo = 0
		self.matrix = matrix_blok
		self.xpos, self.ypos = xpos/10, ypos/10
		self.matrix[self.xpos][self.ypos] = self

	def update(self):
		self.do()

	def gameover(self):
		for sprite in self.group:
			sprite.do = sprite.die

	def die(self):
		self.image = dead
		
	def jump(self):
		if self.ypos > 0 :
			if self.matrix[self.xpos][self.ypos - 1] != None:
				self.matrix[self.xpos][self.ypos - 1].do = self.matrix[self.xpos][self.ypos - 1].jump
			elif self.matrix[self.xpos][self.ypos - 1] == None:
				self.matrix[self.xpos][self.ypos] = None
				self.ypos -= 1
				self.matrix[self.xpos][self.ypos] = self
				self.do = self.collapse
		elif self.ypos <= 0:
			self.do = self.die

	def collapse(self):
		if self.rect.x < self.xdest:	xmove = 5
		elif self.rect.x > self.xdest:	xmove = -5
		else:				xmove = 0
		if self.rect.y < self.ydest:	ymove = 5
		elif self.rect.y > self.ydest:	ymove = -5
		else:				ymove = 0
		self.rect.move_ip(xmove,ymove)
		if self.ypos < 15:
			if self.matrix[self.xpos][self.ypos + 1] == None:
				self.matrix[self.xpos][self.ypos] = None
				self.ypos += 1
				self.matrix[self.xpos][self.ypos] = self
		elif self.ypos == 15:
			pass	#go left
		self.xdest, self.ydest =  self.xpos*10, self.ypos*10

	def clicked(self):
		if self.ypos > 0 :
			self.top = self.matrix[self.xpos][self.ypos-1]
		else:	self.top = None
		if self.xpos > 0 :
			self.left = self.matrix[self.xpos-1][self.ypos]
		else:	self.left = None
		if self.ypos < 15 :
			self.bottom = self.matrix[self.xpos][self.ypos+1]
		else:	self.bottom = None
		if self.xpos < 9 :
			self.right = self.matrix[self.xpos+1][self.ypos]
		else:	self.right = None

		around = [(self.left),(self.right),(self.top),(self.bottom)]
		for side in around:
			if side != None:
				if side.image == self.image:
					side.do = side.clicked
					side.combo += 1
					self.combo += 1
					self.combo = side.combo = side.combo + self.combo

		if self.combo > 20 :
			self.combo = 20
		self.image = image_score[self.combo]

		self.matrix[self.xpos][self.ypos] = None
		self.remove(self.group)
		self.add(self.target)

		self.do = self.score

	def score(self):
		if (self.rect.x, self.rect.y) != (120,20) :
			self.rect.y += 5 * (20 - self.rect.y) / (120 - self.rect.x)
			self.rect.x += 5

###############################################################################################
#############################scaler sprite#####################################################
###############################################################################################

class spr_single(pygame.sprite.Sprite):
	def __init__(self,xpos,ypos, mouse):
		pygame.sprite.Sprite.__init__(self)
		self.image = single_scale
		self.rect = self.image.get_rect().move(xpos,ypos)
		self.mouse = mouse

	def scale_screen(self,screen,window):
		window.blit(screen,(0,0))

	def scale_mouse(self,mouse):
		pass

	def click(self):
		window = pygame.display.set_mode((160,160))
		self.mouse.mouse_do = self.scale_mouse
		self.mouse.screen_do = self.scale_screen

class spr_double(pygame.sprite.Sprite):
	def __init__(self,xpos,ypos, mouse):
		pygame.sprite.Sprite.__init__(self)
		self.image = double_scale
		self.rect = self.image.get_rect().move(xpos,ypos)
		self.mouse = mouse

	def scale_screen(self,screen,window):
		scaled = pygame.transform.scale2x(screen)
		window.blit(scaled,(0,0))

	def scale_mouse(self,mouse):
		mouse.rect.x, mouse.rect.y = mouse.rect.x/2, mouse.rect.y/2

	def click(self):
		window = pygame.display.set_mode((320,320))
		self.mouse.mouse_do = self.scale_mouse
		self.mouse.screen_do = self.scale_screen

class spr_quad(pygame.sprite.Sprite):
	def __init__(self,xpos,ypos, mouse):
		pygame.sprite.Sprite.__init__(self)
		self.image = quad_scale
		self.rect = self.image.get_rect().move(xpos,ypos)
		self.mouse = mouse

	def scale_screen(self,screen,window):
		scaled = pygame.transform.scale2x(screen)
		scaled = pygame.transform.scale2x(scaled)
		window.blit(scaled,(0,0))

	def scale_mouse(self,mouse):
		mouse.rect.x, mouse.rect.y = mouse.rect.x/4, mouse.rect.y/4

	def click(self):
		window = pygame.display.set_mode((640,640))
		self.mouse.mouse_do = self.scale_mouse
		self.mouse.screen_do = self.scale_screen


spr_single = spr_single(111,0, spr_mice)
spr_double = spr_double(128,0, spr_mice)
spr_quad = spr_quad(145,0, spr_mice)
grp_button = pygame.sprite.RenderUpdates((spr_single, spr_double, spr_quad))

#############################################################################################
################################SCORE SPRITE#################################################
#############################################################################################

grp_combo = pygame.sprite.RenderUpdates()

class spr_combo(pygame.sprite.Sprite):
	def __init__(self,xpos,ypos,group):
		pygame.sprite.Sprite.__init__(self)
		self.score = self.old = 0
		self.group = group
		self.image = font.render(str(0),0,(255,128,128),(255,255,255)).convert()
		self.image.set_colorkey(self.image.get_at((0,0)), RLEACCEL)
		self.rect = self.image.get_rect().move(xpos,ypos)
		self.xpos, self.ypos = xpos, ypos

	def update(self):
		if self.score != self.old :
			self.image = font.render(str(self.score),0,(255,128,128),(255,255,255)).convert()
			self.rect = self.image.get_rect().move(self.xpos,self.ypos)
			self.image.set_colorkey(self.image.get_at((0,0)), RLEACCEL)
		self.old = self.score
		for sprite in pygame.sprite.spritecollide(self, self.group, False) :
			self.score += sprite.combo
			sprite.kill()

	def click(self):
		pass

spr_combo = spr_combo(111,20,grp_combo)
grp_button.add(spr_combo)

class high_score(pygame.sprite.Sprite):
	def __init__(self):
		pygame.sprite.Sprite.__init__(self)
		hall_of_fame = {}

	def update(self):
		pass

	def draw(self):
		pass

high_score = high_score()

##################################################################################################
###################################New Game#######################################################
##################################################################################################

grp_blok.empty()
image_all = [blok_build((0,0,255)), blok_build((255,0,0)), blok_build((0,255,0))]

class spr_new_game(pygame.sprite.Sprite):
	def __init__(self,xpos,ypos,image,group,image_list):
		pygame.sprite.Sprite.__init__(self)
		self.image = image
		self.rect = self.image.get_rect().move(xpos,ypos)
		self.group = group
		self.lst = image_list
		self.alive = True

	def click(self):
		self.group.empty()
		self.lst = [blok_build((0,0,255)), blok_build((255,0,0)), blok_build((0,255,0))]


spr_new_game = spr_new_game(110,140,image_new_game,grp_blok,image_all)
grp_button.add(spr_new_game)




###############################################################################################
##################################the main loop################################################
###############################################################################################

alive = True
old = pygame.time.get_ticks()
spr_double.click()


while True :
	clock.tick(24)
	for event in pygame.event.get():
		if event.type == QUIT:
			sys.exit(0)
    		elif event.type == MOUSEBUTTONDOWN:
			#those blok
			if alive == True:
				for sprite_click in pygame.sprite.spritecollide (spr_mice, grp_blok, False) :
					sprite_click.do = sprite_click.clicked	
			#compare button with mouse
			for sprite_click in pygame.sprite.spritecollide (spr_mice, grp_button, False) :
				sprite_click.click()


#those blok
	grp_blok.update()
	grp_blok.draw(screen)
	if alive == True:
		new = pygame.time.get_ticks()
		if new >= old + 4000 :
			old = new
			for x in range(0,100,10) :
				if matrix_blok[x/10][16] == None:
					new_blok = spr_blok(x,160,choice(image_all),grp_blok, grp_combo)
					new_blok.do = new_blok.jump
					grp_blok.add(new_blok)
		for x in range(0,100,10) :			
			if matrix_blok[x/10][0] != None:
				alive = False
				matrix_blok[x/10][0].do = matrix_blok[x/10][0].gameover

#all button like scaler , score , level chooser
	grp_button.update()
	grp_button.draw(screen)
#blok that becom combo and will be drawn on top of the rest
	grp_combo.update()
	grp_combo.draw(screen)
#screen update
	spr_mice.update()
	spr_mice.mouse_do(spr_mice)
	spr_mice.screen_do(screen,window)
	pygame.display.flip()
	screen.blit(background,(0,0))
