import pygame, math, random
from pygame.locals import *

class mice(pygame.sprite.Sprite):
	def __init__(self):
		pygame.sprite.Sprite.__init__(self)
		self.button = None
		self.position = None
		self.pressed = None
		self.raize = None
		#-----------	
		self.image = pygame.Surface((20,20))
		self.image.set_colorkey((0,0,0))
		self.rect = self.image.get_rect()
		pygame.draw.circle(self.image,(1,1,1),self.rect.center,8,2)
		
	def update(self):
		self.button = pygame.mouse.get_pressed()	
		self.position = pygame.mouse.get_pos()
		if True in self.button :
			if self.pressed != True:
				self.raize = True
			else:
				self.raize = False
			self.pressed = True
		else:
			self.pressed = False
			self.raize = False
		#------------------
		self.rect.center = self.position
		
	def draw(self):
		pass
		
def perpixelspritecollid(pos,other):
	(px,py) = pos
	if (px or py) < 0 or px > other.rect.w or py > other.rect.h:
		return False
	if other.image.get_at(pos) == other.image.get_colorkey():
		return False
	return True
	
def poxel2pixel(poxel,mod_rad=0.0):
	(radian,radius) = poxel
	return (int(math.sin(radian+mod_rad)*radius), int(math.cos(radian+mod_rad)*radius))
	
def pixel2poxel(pos):
	(x,y) = pos
	return (int(math.atan2(x,y)) , int(math.hypot(x,y)))

class boulle(pygame.sprite.Sprite):
	def __init__(self,x,y,radius,radians,color,limit,grp):
		pygame.sprite.Sprite.__init__(self)
		self.radius, self.radians = radius, radians
		self.color, self.limit, self.grp = color, limit, grp
		self.rect = pygame.Rect(0,0,3,3)
		self.rect.center = (x,y)
		self.redraw()
		self.move = (random.choice((1,-1)),random.choice((1,-1)))
		
	def redraw(self):
		(x,y) = self.rect.center
		self.image = pygame.Surface((int(self.radius*2)+2,int(self.radius*2)+2))
		self.rect = self.image.get_rect()
		pygame.draw.circle(self.image, self.color, self.rect.center, int(self.radius),0)
		self.image.set_colorkey((0,0,0))
		self.rect.center = (x,y)		

	def collide(self,other):
		if other != self:
			if other.color != coal:
				nradians, nradius = pixel2poxel((other.rect.centerx-self.rect.centerx,other.rect.centery-self.rect.centery))
				if nradius <= other.radius+self.radius:
					if self.color != other.color:
						self.radians = nradians + math.radians(180)
						self.move = poxel2pixel((self.radians,3))
					else:
						if self.radius == other.radius:
							self.radius += 0.01
						if self.radius > other.radius:
							self.radius = math.sqrt(((math.pi*self.radius**2) + (math.pi*other.radius**2))/math.pi)
							#other.radius = 0
							other.remove(other.grp)
							self.redraw()
			elif other.color == coal:
				#la bulle pete en deux
				nradians = self.radians+math.pi/2
				nradius = math.sqrt((self.radius**2)/2)
				(nx,ny) = poxel2pixel((nradians,self.radius))
				nx,ny = nx+self.rect.centerx,ny+self.rect.centery
				self.grp.add(boulle(nx,ny,nradius,nradians,self.color,self.limit,self.grp))
				nradians = self.radians-math.pi/2
				(nx,ny) = poxel2pixel((nradians,self.radius))
				nx,ny = nx+self.rect.centerx,ny+self.rect.centery
				self.grp.add(boulle(nx,ny,nradius,nradians,self.color,self.limit,self.grp))
				other.remove(other.grp)
				self.remove(self.grp)

	def update(self):
		if self.radius <= 2:
			self.remove(self.grp)
		if self.rect.right < self.limit.left:
			self.rect.left = self.limit.right 
		elif self.rect.left > self.limit.right:
			self.rect.right = self.limit.left
		elif self.rect.top > self.limit.bottom:
			self.rect.bottom = self.limit.top
		elif self.rect.bottom < self.limit.top:
			self.rect.top = self.limit.bottom
		else:
			(x,y) = self.move
			self.rect.move_ip(x,y)
		for other in pygame.sprite.spritecollide(self, self.grp, 0):
			self.collide(other)

class aiguille(pygame.sprite.Sprite):
	def __init__(self,pos,radian,limit,grp):
		pygame.sprite.Sprite.__init__(self)
		self.radius, self.color, self.radian = 6, coal, radian
		self.grp, self.limit = grp, limit
		self.image = pygame.Surface((15,15)).convert()
		self.rect = self.image.get_rect()
		self.image.set_colorkey((0,0,0))
		src = poxel2pixel((radian + math.pi,self.radius))
		dest = poxel2pixel((radian,self.radius))
		src = (src[0] + self.rect.centerx, src[1] + self.rect.centery)
		dest = (dest[0] + self.rect.centerx, dest[1] + self.rect.centery)
		pygame.draw.line(self.image, coal, src, dest, 4)
		self.rect.center = pos
		self.move = poxel2pixel((self.radian,7))
		
	def update(self):
		(x,y) = self.move
		self.rect.centerx, self.rect.centery = self.rect.centerx+x, self.rect.centery+y
		if self.rect.right < self.limit.left:
			self.rect.left = self.limit.right 
		elif self.rect.left > self.limit.right:
			self.rect.right = self.limit.left
		elif self.rect.top > self.limit.bottom:
			self.rect.bottom = self.limit.top
		elif self.rect.bottom < self.limit.top:
			self.rect.top = self.limit.bottom

class peteux_d_bulle(pygame.sprite.Sprite):
	def __init__(self,limit,grp,mouse):
		pygame.sprite.Sprite.__init__(self)
		self.angle = 0.0
		self.grp, self.mice, self.limit = grp,mice,limit
		self.image = pygame.Surface((40,40))
		self.rect = self.image.get_rect()
		self.image.set_colorkey((0,0,0))
		self.rect.center = (150,150)
		self.redraw()
		
	def redraw(self):
		self.image.fill((0,0,0))
		point_list = []
		for poxel in [(0.0,18), (2.356,18), (3.1416,5), (3.927,18)]:
			(x,y) = poxel2pixel(poxel,self.angle)
			point_list.append((x+20,y+20))
		pygame.draw.polygon(self.image, coal, point_list, 0)	
		
	def update(self):
		mx,my = self.mice.position
		self.angle = math.atan2(mx - self.rect.centerx,my - self.rect.centery)
		if self.mice.pressed and not self.mice.raize:
			self.rect.centerx += math.sin(self.angle) * 5
			self.rect.centery += math.cos(self.angle) * 5
		elif self.mice.raize:
			pos = self.rect.centerx + math.sin(self.angle)*24, self.rect.centery + math.cos(self.angle)*24
			self.grp.add(aiguille(pos,self.angle,self.limit,self.grp))
		self.redraw()
		for other in pygame.sprite.spritecollide(self,self.grp,0):
			pass
				

#--------------------------------------------------------------
#--------------------------------------------------------------
#--------------------------------------------------------------
#--------------------------------------------------------------
#--------------------------------------------------------------
#--------------------------------------------------------------
pygame.init()
pygame.display.set_caption("Peteux_d'Bulles")
pygame.mouse.set_visible(1)
clock = pygame.time.Clock()
screen = pygame.display.set_mode((300, 300))
offscr = screen.get_rect()
end = False
mice = mice()
#-------------------------------------------------
spiele = pygame.sprite.Group()

coal = (51,51,51)
green = (0,200,0)
red = (200,0,0)
blue = (0,0,200)
colors = (green,red,blue)

ship = peteux_d_bulle(offscr,spiele,mice)

for i in range(10):
	spiele.add(boulle(random.randint(20,280),random.randint(20,280),random.randint(5,20),random.randint(0,int(2*math.pi)),random.choice(colors),offscr,spiele))


#-------------------------------------------------
while end == False :	
	clock.tick(30)
	pygame.display.flip()
	mice.update()
	for event in pygame.event.get():
    		if event.type == QUIT:
        			end = True
	#=======================================================
	screen.fill((240,240,240))
	screen.blit(mice.image,mice.rect)
	screen.blit(ship.image,ship.rect)
	ship.update()
	spiele.update()
	spiele.draw(screen)

	#======================================================
