#!/usr/bin/env python

# -*- coding: utf8 -*- 

#***********************************************************************
# pysycache : a program for learn to use the mouse
# Copyright (C) 2005-2007 Vincent DEROO (vincent.pysycache@free.fr) 
# 
# This program is free software; you can redistribute it and/or 
# modify it under the terms of the GNU General Public License 
# as published by the Free Software Foundation; either version 2 
# of the License, or (at your option) any later version. 
# 
# This program is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. 
# 
# You should have received a copy of the GNU General Public License 
# along with this program; if not, write to the Free Software 
# Foundation, Inc. : 
# 51 Franklin Street, Fifth Floor, Boston, MA02110-1301, USA
#***********************************************************************


#*******************************************************************************
# Importation des modules
#*******************************************************************************
import sys
import getopt, string
import random
import time

import random, os
import pygame
from pygame.locals import *
import datas
from pysyclasses import *
import const

import pysyscores





#*******************************************************************************
#                                     Classe                                   #
#*******************************************************************************


class Balloon(pygame.sprite.Sprite):
	"""This class is for the elements that move"""
	def __init__(self, left, top, filename, id, categ, fileif, fileifnot):
		pygame.sprite.Sprite.__init__(self) 				#call Sprite intializer
		self.filename = filename
		self.fileif = fileif
		self.fileifnot = fileifnot
		self.image, self.rect = datas.Load_image("themes-buttons", filename, None, True)
		self.id = id
		(self.largeur, self.hauteur) = self.image.get_size()
		self.cptspeed = 0
		self.sens = 1					# 1 : descendre
										# 0 : arret
										#-1 : monter
		self.rect.left = left
		self.rect.top = top
		self.left = left
		self.top = top
		self.oldleft = left
		self.oldtop = top
		self.categ = categ				#1 : gauche
										#2 : droite

	def clearbgrd(self, background):
		screen = pygame.display.get_surface()
		#on va redessiner le fond 
		screen.blit(background, (self.left - 5, self.top - 5), (self.left - 5, self.top - 5, self.largeur + 10, self.hauteur + 10))


	def move(self, background, LimGauche, LimDroite, LimBasG, LimHautG, LimBasD, LimHautD, LimBas, LimHaut):
		#deplacement de l'element
		self.cptspeed += 1
		if self.cptspeed == const.GSpeed:
			self.clearbgrd(background)

			#on se deplace de 1 pixel
			nvtop = self.top + 1 * self.sens

			#--------------------- verification des limites --------------------
			if self.rect.left < LimGauche :
				#zone a gauche
				liminf = LimBasG
				limsup = LimHautG
			elif self.left + self.largeur > LimDroite:
				#zone a droite
				liminf = LimBasD
				limsup = LimHautD
			else:
				#zone centrale
				liminf = LimBas
				limsup = LimHaut

			if self.top < limsup:
				nvtop = limsup
				self.sens = -1 * self.sens 
			if self.top + self.hauteur > liminf:
				nvtop = liminf - self.hauteur
				self.sens = -1 * self.sens

			self.oldleft = self.left
			self.oldtop = self.top
			self.rect.top = nvtop
			self.left = self.rect.left
			self.top = nvtop
			self.cptspeed = 0


#*******************************************************************************
#
#*******************************************************************************
class ApplicationButtons(ApplicationPysy):
	def __init__(self):
		ApplicationPysy.__init__(self)
		self.GLimGauche = 0
		self.GLimDroite = 0
		self.GLimHaut = 0
		self.GLimBas = 0
		self.GLimHautD = 0
		self.GLimHautG = 0
		self.GLimBasD = 0
		self.GLimBasG = 0
		self.GLstBallons = pygame.sprite.RenderClear()			#liste des images des elements mobiles
		self.GLimFinG = 0
		self.GLimFinD = 0
		self.GImgBackground = ""


	#***************************************************************************
	# Retour 0 : on a pas gagne
	#        1 : on a gagne  
	#***************************************************************************
	def OnAGagne(self, gagne):
		if (const.GNbButtons == 0):
			gagne = 1
		else:
			gagne = 0
		
		return gagne


	#***************************************************************************
	#
	#***************************************************************************
	def InitializeApp(self, DirThemes, ActName):
		ApplicationPysy.InitializeApp(self, DirThemes, ActName)

		if const.GWithSound == 1:
			if const.GSoundError == 0:
				self.Channel0 = pygame.mixer.Channel(0)
				self.Channel1 = pygame.mixer.Channel(1)
				self.Channel2 = pygame.mixer.Channel(2)
				music = os.path.join(const.GRepPysycache, 'sounds', 'left.wav').encode(const.GConsoleLocale)
				self.Sound0 = pygame.mixer.Sound(music)
				music = os.path.join(const.GRepPysycache, 'sounds', 'center.wav').encode(const.GConsoleLocale)
				self.Sound1 = pygame.mixer.Sound(music)
				music = os.path.join(const.GRepPysycache, 'sounds', 'right.wav').encode(const.GConsoleLocale)
				self.Sound2 = pygame.mixer.Sound(music)



	#***************************************************************************
	#
	#***************************************************************************
	def DoInitLevel(self):
		""" """
		if const.GLevel == 2:		#difficile
			const.GSpeed = 1
		elif const.GLevel == 1:
			const.GSpeed = 2
		elif const.GLevel == 0:
			const.GSpeed = 3


	#***************************************************************************
	#
	#***************************************************************************
	def DoTheMoveEvent(self):
		ApplicationPysy.DoTheMoveEvent(self)

		#les elements doivent-ils bouger ?
		screen = pygame.display.get_surface()

		for o in self.GLstBallons.sprites():
			o.move(self.Background, self.GLimGauche, self.GLimDroite, self.GLimBasG, self.GLimHautG, self.GLimBasD, self.GLimHautD, self.GLimBas, self.GLimHaut)

		self.GLstBallons.draw(screen)
		const.GLstSouris.draw(screen)
		pygame.display.update()


	#***************************************************************************
	#
	#***************************************************************************
	def DoOnMouseDown(self, event0, event1, str):
		ApplicationPysy.DoOnMouseDown(self, event0, event1, str)

		ok = 0

		#----------------- recherche si un objet a deplacer ----------------
		#on ne fait pas deplacer si en dehors de la zone 
		for obj in self.GLstBallons.sprites():
			if ( event0 + const.DEMISOURIS >= obj.left ) & ( event0 + const.DEMISOURIS <= obj.left + obj.largeur ) & ( event1 + const.DEMISOURIS >= obj.top ) & ( event1 + const.DEMISOURIS <= obj.top + obj.hauteur ) :
				objtrouve = obj
				datas.DebugMessage("             id of found item2 : %i " % objtrouve.id)
				ok = 1

		if ok == 1:
			ok = 0
			const.GTypeSouris = const.EVENT_NOVENT

			if str == 1:
				#------------------ a gauche -------------------------------
				datas.DebugMessage("Click on left button")
				if const.GWithSound == 1:
					if const.GSoundError == 0:
						self.Channel0.play(self.Sound0)
				ok = 1

				#ne pas aller dans la zone interdite...
				if self.GLimGauche >= objtrouve.left - 50:
					objtrouve.clearbgrd(self.Background)
					if objtrouve.categ == 1:
						#l'element peut aller a gauche... mais 
						#est-il dans la zone pour aller se ranger ?
						if (objtrouve.top >= self.GLimHautG) & (objtrouve.top + objtrouve.hauteur <= self.GLimBasG) :
							#on entre dans le tunnel... que si on est le bon element
							oktunnel = 0
							if const.GItemToMove == 99:
								oktunnel = 1
							else:
								if const.GItemToMove == objtrouve.id:
									oktunnel = 1

							if oktunnel == 1:
								objtrouve.rect.move_ip(- 50, 0)
								objtrouve.left = objtrouve.rect.left
								#verification que l'element a atteint sa limite
								if objtrouve.left <= self.GLimFinG:
									self.GLstBallons.remove(objtrouve)
									const.GNbButtons = const.GNbButtons - 1
									self.GetIdOfItemToMove()
						else:
							#l'objet n'est pas devant le tunnel : il est bloque
							objtrouve.rect.left = self.GLimGauche
							objtrouve.left = objtrouve.rect.left
							datas.DebugMessage("Bloque")
					else:
						#l'objet ne peut qu'aller a droite : il est donc bloque
						objtrouve.rect.left = self.GLimGauche
						objtrouve.left = objtrouve.rect.left
						datas.DebugMessage("Is a left item : cannot go at left !")
				else:
					#pas de pb de limites
					objtrouve.clearbgrd(self.Background)
					objtrouve.rect.move_ip(- 50, 0)
					objtrouve.rect.left = objtrouve.rect.left

			elif str == 2:
				#-------- on change le mvt : haut <--> bas -----------------
				datas.DebugMessage("click on center button")
				if const.GWithSound == 1:
					if const.GSoundError == 0:
						self.Channel1.play(self.Sound1)
				objtrouve.sens = -1 * objtrouve.sens
			elif str == 3:
				#-------------------- a droite -----------------------------
				datas.DebugMessage("click on right button")
				if const.GWithSound == 1:
					if const.GSoundError == 0:
						self.Channel2.play(self.Sound2)
				ok = 1

				if self.GLimDroite <= objtrouve.left + 50 + objtrouve.largeur :
					objtrouve.clearbgrd(self.Background)
					if objtrouve.categ == 2:
						#l'element peut aller a droite... mais 
						#est-il dans la zone pour aller se ranger ?
						if (objtrouve.top >= self.GLimHautD) & (objtrouve.top + objtrouve.hauteur <= self.GLimBasD) :
							#on entre dans le tunnel... que si on est le bon element
							oktunnel = 0
							if const.GItemToMove == 99:
								oktunnel = 1
							else:
								if const.GItemToMove == objtrouve.id:
									oktunnel = 1

							if oktunnel == 1:
								objtrouve.rect.move_ip(50, 0)
								objtrouve.left = objtrouve.rect.left
								#verification que l'element a atteint sa limite
								if objtrouve.left + objtrouve.largeur >= self.GLimFinD:
									self.GLstBallons.remove(objtrouve)
									const.GNbButtons = const.GNbButtons - 1
									self.GetIdOfItemToMove()
						else:
							objtrouve.rect.left = self.GLimDroite - objtrouve.largeur
							objtrouve.left = objtrouve.rect.left
					else:
						objtrouve.rect.left = self.GLimDroite - objtrouve.largeur
						objtrouve.left = objtrouve.rect.left
				else:
					#pas de pb de limites
					objtrouve.clearbgrd(self.Background)
					objtrouve.rect.move_ip(50, 0)
					objtrouve.rect.left = objtrouve.rect.left


			if ok == 1:
				screen = pygame.display.get_surface()  

				self.GLstBallons.draw(screen)
				const.GLstSouris.draw(screen)
				pygame.display.update()

			const.GTypeSouris = const.EVENT_JEU0

			return 1



	#***************************************************************************
	#
	#***************************************************************************
	def InitActivity(self, WithHasard):
		ApplicationPysy.InitActivity(self, WithHasard)

		pygame.time.set_timer ( const.EVTMOVE, 0 )

		screen = pygame.display.get_surface()

		self.GetIdOfItemToMove()

		#on copie cette image sur l'ecran
		ImgFond, background_rect = datas.Load_image("", self.GImgBackground, None, True)
		if const.GDebug == 1:
			#on dessine les zones gauches
			rect = pygame.Rect([self.GLimFinG - const.MARGELEFT, self.GLimHautG - const.MARGETOP, self.GLimGauche - self.GLimFinG, self.GLimBasG - self.GLimHautG])
			pygame.draw.rect(ImgFond, (255, 0, 0), rect, 0)
			#on dessine les zones droites
			rect = pygame.Rect([self.GLimDroite - const.MARGELEFT, self.GLimHautD - const.MARGETOP, self.GLimFinD - self.GLimDroite, self.GLimBasD - self.GLimHautD])
			pygame.draw.rect(ImgFond, (0, 255, 0), rect, 0)

		#on copie ce cache sur l'image de fond
		self.Background.blit(ImgFond, (0 + const.MARGELEFT, 0 + const.MARGETOP))

		self.GLstBallons.draw(screen)

		#rafraichissement
		pygame.display.update()

		pygame.time.set_timer ( const.EVTMOVE, 40 )  #toutes les 40 milli secondes


	#***************************************************************************
	#
	#***************************************************************************
	def MotionAfterMouse(self, event0, event1, str):
		ApplicationPysy.MotionAfterMouse(self, event0, event1, str)

		screen = pygame.display.get_surface()
		self.GLstBallons.draw(screen)



	#***************************************************************************
	# il faut ajouter les marges  const.MARGELEFT et const.MARGETOP
	#
	#self.GLimHaut     ---------------------
	#                  |                    |
	#                  |                    |
	#                  |                    |
	#self.GLimHautG----                     |
	#                                       |
	#self.GLimBasG-----                     | 
	#                  |                    |
	#                  |                    |
	#                  |                    ---------self.GLimHautD
	#                  |  
	#                  |                    ---------self.GLimBasD
	#                  |                    | 
	#                  |                    |
	#self.GLimBas      |--------------------|
	#           self.GLimGauche          self.GLimDroite   
	#
	# fond01.bmp 				image de fond
	# 200-20					coin ht gauche
	# 500-505					coin bas droite
	# 180-150-180-300			
	# 500-365-500-515
	# 01.png-4					img de gauche - nbre
	# 02.png-2					img de droite - nbre
	# 01b.png-01a.png			img de gauche si non actif - si actif
	# 02b.png-02a.png			img de droite si non actif - si actif
	#***************************************************************************
	def ReadDfgFile(self):
		ApplicationPysy.ReadDfgFile(self)

		screen = pygame.display.get_surface()  

		LstFound = []
		self.GLstBallons.empty()

		#------------------ on va lire le fichier de configuration -----------------
		configname = self.LstFicConfig[self.IdxFileDfg]

		(filepath, filetmp) = os.path.split(configname)

		datas.DebugMessage("")
		datas.DebugMessage("Reading the config file %s " % configname)

		cpt = 0
		f = open(configname,'rb') 
		lignes = f.readlines()
		for lig in lignes:
			lig = lig.strip()
			if len(lig) == 0:
				continue

			if cpt == 0:
				#fond de l'image
				#chargement du dessin servant de cache
				self.GImgBackground = os.path.join(filepath, lig)
				datas.DebugMessage("Used background : %s " % self.GImgBackground)

			if cpt == 1:
				#la limite superieure gauche
				lig = lig.split('|')
				self.GLimGauche = int(lig[0]) + const.MARGELEFT
				self.GLimHaut = int(lig[1]) + const.MARGETOP
				datas.DebugMessage("...Top Left corner : %i  (left), %i (top)" % ( self.GLimGauche, self.GLimHaut) )

			if cpt == 2:
				#la limite inferieure droite
				lig = lig.split('|')
				self.GLimDroite = int(lig[0]) + const.MARGELEFT
				self.GLimBas = int(lig[1]) + const.MARGETOP
				datas.DebugMessage("")
				datas.DebugMessage("...Bottom Right corner : %i (right), %i (bottom)" % (self.GLimDroite, self.GLimBas) )

			if cpt == 3 :
				#le tunnel de gauche
				lig = lig.split('|')
				self.GLimHautG = int(lig[1]) + const.MARGETOP
				self.GLimBasG = int(lig[3]) + const.MARGETOP
				datas.DebugMessage("")
				datas.DebugMessage("...Left target area : %i  (top), %i (bottom)" % (self.GLimHautG, self.GLimBasG) )

			if cpt == 4 :
				#le tunnel de droite
				lig = lig.split('|')
				self.GLimHautD = int(lig[1]) + const.MARGETOP
				self.GLimBasD = int(lig[3]) + const.MARGETOP
				datas.DebugMessage("")
				datas.DebugMessage("...Right target area : %i  (top), %i (bottom)" %(self.GLimHautD, self.GLimBasD) )

			if cpt == 5:
				#l'element de gauche et le nombre maxi possible
				lig = lig.split('|')
				nb1 = random.randint(1, int(lig[1]) + 1 )
				datas.DebugMessage("")
				datas.DebugMessage("...number of left items : %i " % nb1)
				filename = os.path.join(filepath, lig[0])
				filenamenoif = os.path.join(filepath, lig[2])
				filenameif = os.path.join(filepath, lig[3])

				for i in range (0, nb1) :
					x = random.randint(self.GLimGauche + 1, self.GLimDroite - 1 - 96) + const.MARGELEFT
					y = random.randint(self.GLimHaut, self.GLimBas - 96) + const.MARGETOP
					btn = Balloon(x, y, filename, i, 1, filenameif, filenamenoif)
					self.GLstBallons.add(btn)
	
			if cpt == 6:
				#l'element de droite et le nombre maxi possible
				lig = lig.split('|')
				nb2 = random.randint(1, int(lig[1]) + 1 )
				datas.DebugMessage("")
				datas.DebugMessage("...number of right items : %i " % nb2)
				filename = os.path.join(filepath, lig[0])
				filenamenoif = os.path.join(filepath, lig[2])
				filenameif = os.path.join(filepath, lig[3])

				for i in range (0, nb2) :
					x = random.randint(self.GLimGauche + 1, self.GLimDroite - 1 - 96) + const.MARGELEFT
					y = random.randint(self.GLimHaut, self.GLimBas - 96) + const.MARGETOP
					btn = Balloon(x, y, filename, nb1 + i, 2, filenameif, filenamenoif)
					self.GLstBallons.add(btn)

			if cpt == 7:
				#la limite a gauche pour cacher l'element
				lig = lig.split('|')
				self.GLimFinG = int(lig[0]) + const.MARGELEFT

			if cpt == 8:
				#la limite a gauche pour cacher l'element
				lig = lig.split('|')
				self.GLimFinD = int(lig[0]) + const.MARGELEFT

			cpt += 1
		f.close()

		#MAJ du nombre de buttons a voir
		const.GNbButtons = nb1 + nb2

		self.SortBallons()



	#***************************************************************************
	#
	#***************************************************************************
	def GetIdOfItemToMove(self):
		""" """
	
		if const.GModeJeu == const.MODENORMAL:
			const.GItemToMove = 99
		else:
			if len(self.GLstBallons) == 0:
				const.GItemToMove = 99
			else:
				idx = random.randint(0, len(self.GLstBallons) - 1)
				datas.DebugMessage("")
				datas.DebugMessage("GItemToMove : %i" % const.GItemToMove)
				cpt = 0
				for obj in self.GLstBallons.sprites():
					if cpt == idx:
						const.GItemToMove = obj.id
						obj.image, recttmp = datas.Load_image("", obj.fileif, None, True)
					else:
						obj.image, recttmp = datas.Load_image("", obj.fileifnot, None, True)
					cpt += 1


	#***************************************************************************
	#
	#***************************************************************************
	def EndOfActivity(self):
		pygame.time.set_timer (const.EVTMOVE, 0 ) 


	#***************************************************************************
	#
	#***************************************************************************
	def SortBallons(self):
		i = 0
		datas.DebugMessage("")
		datas.DebugMessage("BEFORE")
		if const.GDebug == 1:
			for obj in self.GLstBallons.sprites():
				print obj.id, " - ", obj.filename, " - ", obj.categ, obj.fileif, obj.fileifnot

		for i in range(0, const.GNbButtons):
			cpt = 0
			for obj in self.GLstBallons.sprites():
				if cpt == i:
					if ( i != obj.id) :
						#cet obj ne devrait pas etre la
						objadepl = Balloon(obj.left, obj.top, obj.filename, obj.id, obj.categ, obj.fileif, obj.fileifnot)
						objadepl.rect = obj.rect
						objadepl.image = obj.image
						objadepl.filename = obj.filename
						objadepl.fileif = obj.fileif
						objadepl.fileifnot = obj.fileifnot

						#recherche de celui qui devrait etre a cette place
						j = 0
						for obj2 in self.GLstBallons.sprites():
							if obj2.id == i :
								#on a trouve l'obj qui devrait etre la
								objfound =  Balloon(obj2.left, obj2.top, obj2.filename, obj2.id, obj2.categ, obj2.fileif, obj2.fileifnot)

								obj2.id = objadepl.id
								obj2.rect = objadepl.rect
								obj2.image = objadepl.image
								obj2.largeur = objadepl.largeur
								obj2.hauteur = objadepl.hauteur
								obj2.left = objadepl.left
								obj2.top = objadepl.top
								obj2.oldleft = objadepl.oldleft
								obj2.oldtop = objadepl.oldtop
								obj2.categ = objadepl.categ
								obj2.filename = objadepl.filename
								obj2.fileif = objadepl.fileif
								obj2.fileifnot = objadepl.fileifnot

								break
							j += 1
						obj.id = objfound.id
						obj.filename = objfound.filename
						obj.fileif = objfound.fileif
						obj.fileifnot = objfound.fileifnot
						obj.rect = objfound.rect
						obj.image = objfound.image
						obj.largeur = objfound.largeur
						obj.hauteur = objfound.hauteur
						obj.left = objfound.left
						obj.top = objfound.top
						obj.oldleft = objfound.oldleft
						obj.oldtop = objfound.oldtop
						obj.categ = objfound.categ
					break
				cpt += 1

		datas.DebugMessage("")
		datas.DebugMessage("AFTER")
		if const.GDebug == 1:
			for obj in self.GLstBallons.sprites():
				print obj.id, " - ", obj.filename, " - ", obj.categ, obj.fileif, obj.fileifnot

#		self.GetIdOfItemToMove()
#		screen = pygame.display.get_surface()
#		self.GLstBallons.draw(screen)
#		#redessin de la souris a sa position actuelle
#	#				screen.blit(const.GMaSouris, const.GMaSouris_position)
#		const.GLstSouris.draw(screen)
#		pygame.display.update()
