#!/usr/bin/env python

# -*- coding: utf8 -*- 

#***********************************************************************
# pysycache : a tool for learn to use the mouse
# Copyright (C) 2005-2006 Vincent DEROO (vincent.pysycache@free.fr)
#
# This tool is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 datasclass import BtnMenu
import const
import glob

DUREETRANSITION = 3





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


class Balloon(pygame.sprite.Sprite):
	"""This class is for the elements that move"""
	def __init__(self, left, top, filename, id, categ):
		pygame.sprite.Sprite.__init__(self) 				#call Sprite intializer
		dirname = os.path.join(const.GRepPysycache, 'themes-buttons', GLstThemesButtons[const.GIdxThemes])
		self.image, self.rect = datas.load_png(dirname, filename)
		self.id = id
		self.largeur = 96
		self.hauteur = 96
		self.cptspeed = 0
		self.visible = 1				#l'image est visible
		self.speed = const.GSpeed
		self.sens = 1					# 1 : descendre
										# 0 : arret
#										#-1 : monter
		self.rect.left = left 
		self.rect.top = top
		self.categ = categ				#1 : gauche
										#2 : droite

	def move(self):
		#deplacement de l'element
		if self.visible == 1:
			self.cptspeed = self.cptspeed + 1
			if self.cptspeed == self.speed:
				#on se deplace de 1 pixel
				self.rect.top = self.rect.top + 1 * self.sens
				self.cptspeed = 0

				#--------------------- verification des limites --------------------
				if self.rect.left < GLimGauche :
					#zone a gauche
					liminf = GLimBasG
					limsup = GLimHautG
				elif self.rect.left + self.largeur > GLimDroite:
					#zone a droite
					liminf = GLimBasD
					limsup = GLimHautD
				else:
					#zone centrale
					liminf = GLimBas
					limsup = GLimHaut

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




#*******************************************************************************
#                                                                              #
#                                                                              #
#                                    Fonctions                                 #
#                                                                              #
#                                                                              #
#*******************************************************************************





#*******************************************************************************
# le contenu de ce fichier dfg est 
#
# 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
#*******************************************************************************
def LoadBackgroundOfConfig(themename):
	""" Charge le fond a partir d'un fichier de configuration contenus dans le repertoire"""
	#                                 
	# il faut ajouter les marges  const.MARGELEFT et const.MARGETOP
	#
	#GLimHaut     ---------------------
	#             |                    |
	#             |                    |
	#             |                    |
	#GLimHautG----                     |
	#                                  |
	#GLimBasG-----                     | 
	#             |                    |
	#             |                    |
	#             |                    ---------GLimHautD
	#             |  
	#             |                    ---------GLimBasD
	#             |                    | 
	#             |                    |
	#GLimBas      |--------------------|
	#           GLimGauche          GLimDroite   
	global GLimGauche
	global GLimDroite
	global GLimHaut
	global GLimBas
	global GLimHautD
	global GLimHautG
	global GLimBasD
	global GLimBasG
	global GLstBallons			#liste des images des elements mobiles
	global GLimFinG
	global GLimFinD

	GLstBallons = pygame.sprite.RenderClear()

	screen = pygame.display.get_surface()  

	#effacer l'existant
	const.GTabButtons[:] = []

	LstFound = []

	#------------------ on va lire le fichier de configuration -----------------
	configname = GLstFicConfig[const.GIdxImage]

	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
			filename = os.path.join(themename, lig)
			imgfilename = lig
			ImgFond, background_rect = datas.load_image('themes-buttons', filename )

			#on copie ce cache sur l'image de fond
			screen = pygame.display.get_surface()  
			Gbackground_image.blit(ImgFond, (0 + const.MARGELEFT, 0 + const.MARGETOP))
			#on copie cette image sur l'ecran
			screen.blit(Gbackground_image, (0, 0))

		if cpt == 1:
			#la limite superieure gauche
			lig = lig.split('-')
			GLimGauche = int(lig[0]) + const.MARGELEFT
			GLimHaut = int(lig[1]) + const.MARGETOP

		if cpt == 2:
			#la limite inferieure droite
			lig = lig.split('-')
			GLimDroite = int(lig[0]) + const.MARGELEFT
			GLimBas = int(lig[1]) + const.MARGETOP

		if cpt == 3 :
			#le tunnel de gauche
			lig = lig.split('-')
			GLimHautG = int(lig[1]) + const.MARGETOP
			GLimBasG = int(lig[3]) + const.MARGETOP

		if cpt == 4 :
			#le tunnel de droite
			lig = lig.split('-')
			GLimHautD = int(lig[1]) + const.MARGETOP
			GLimBasD = int(lig[3]) + const.MARGETOP

		if cpt == 5:
			#l'element de gauche et le nombre maxi possible
			lig = lig.split('-')
			nb1 = random.randint(1, int(lig[1]) )
			for i in range (nb1) :
				x = random.randint(GLimGauche + 1, GLimDroite - 1 - 96) + const.MARGELEFT
				y = random.randint(GLimHaut, GLimBas - 96) + const.MARGETOP
				btn = Balloon(x, y, lig[0], i, 1)
				btn.id = i
				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]) )
			for i in range (nb2) :
				x = random.randint(GLimGauche + 1, GLimDroite - 1 - 96) + const.MARGELEFT
				y = random.randint(GLimHaut, GLimBas - 96) + const.MARGETOP
				btn = Balloon(x, y, lig[0], i, 2)
				btn.id = nb1 + i
				GLstBallons.add(btn)

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

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

		cpt = cpt + 1
	f.close()

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




#*******************************************************************************
# Recherche les fichiers de configuration pour un repertoire
# on recherche tous les fichiers de definition (*.dfg)
#*******************************************************************************
def LoadListConfigFile(themename):
	""" Find all available pictures of a theme directory """

	filtre = os.path.join(const.GRepPysycache, 'themes-buttons', themename, '*.dfg')

	#vider
#	GLstImage[:] = []
	GLstFicConfig[:] = []

	#remplir 
	for nom in glob.glob(filtre):
		if os.path.isfile(nom):
			#--- recuperation du nom (hors chemin) du fichier de definition ----
			GLstFicConfig.append(nom)

	#choisir un fichier au hasard
	if len(GLstFicConfig) == 1:
		const.GIdxImage = 0
	else :
		const.GIdxImage = random.randint(0, len(GLstFicConfig) - 1)








#*******************************************************************************
# change le logo du theme 
#  (a partir des repertoires)
#*******************************************************************************
def ChangeLogoButtons():
	""" Change logo of a theme """
	if const.GIdxThemes == 999999:
		#tous les themes
		filename = os.path.join(const.GRepPysycache, 'images', 'logo.png')
	else:
		#un theme particulier
		filename = os.path.join(const.GRepPysycache, 'themes-buttons', GLstThemesButtons[const.GIdxThemes], 'logo.png')
	
	if os.path.isfile(filename) == True:
		imgtmp = pygame.image.load(filename)
	else:
		filename = os.path.join(const.GRepPysycache, 'images', 'logo.png')
	imgtmp = pygame.image.load(filename)

	#mise a jour de l'image du theme
	for btn in LstBtn.sprites():
		if btn.id == 5:
			#the id of the logo button
			screen = pygame.display.get_surface()
			screen.blit(Gbackground_image, (btn.rect.left, btn.rect.top), (0, 0, btn.largeur, btn.hauteur))
			btn.image.blit(imgtmp, (btn.rect.left, btn.rect.top), (0, 0, btn.largeur, btn.hauteur))
			btn.image = imgtmp







#*******************************************************************************
# Detection des evenements
#                                                                              #
#	self.listenKeys = { K_UP: self.MoveUp,
#						K_DOWN: self.MoveDown,
#						K_LEFT: self.SetVelocityLeft,
#						K_RIGHT: self.SetVelocityRight,
#						K_SPACE: self.MoveUp
#					  }
#                                                                              #
#*******************************************************************************
def DetectEvent():
	""" Traitement des evenements """
	for event in pygame.event.get():
		if event.type == QUIT:
			return 0
		elif event.type == KEYUP:
			if event.key == K_ESCAPE:
				return 0
		elif event.type == pygame.MOUSEMOTION:
			#*************** evenement deplacement de la souris ***************
			event0 = event.pos[0] 
			event1 = event.pos[1] 

			screen = pygame.display.get_surface() 
			screen.blit(Gbackground_image, (0,0))

			#redessin de la souris a sa position actuelle
			screen.blit(GMaSouris, GMaSouris_position)

			GMaSouris_position.left = event0 
			GMaSouris_position.top = event1 
			return 1
		elif event.type == MOUSEBUTTONDOWN:
			#*************************** evenement clic *************************
			str = pygame.mouse.get_pressed() 
			ok = 0

			#----------------- recherche si un objet a deplacer ----------------
			#on ne fait pas deplacer si en dehors de la zone 
			for obj in GLstBallons.sprites():
				if obj.visible == 0:
					continue
				if ( event.pos[0] >= obj.rect.left ) & ( event.pos[0] <= obj.rect.left + obj.largeur ) & ( event.pos[1] >= obj.rect.top  ) & ( event.pos[1] <= obj.rect.top + obj.hauteur ) :
					objtrouve = obj
					ok = 1

			if ok == 1:
				ok = 0
				if str[0] == 1:
					#------------------ a gauche -------------------------------
					datas.load_sound('sounds', 'left.ogg')
					ok = 1

					#ne pas aller dans la zone interdite...
					if GLimGauche >= objtrouve.rect.left - 50:
						if objtrouve.categ == 1:
							#l'element peut aller a gauche... mais 
							#est-il dans la zone pour aller se ranger ?
							if (objtrouve.rect.top > GLimHautG) & (objtrouve.rect.top + objtrouve.hauteur < GLimBasG) :
								objtrouve.rect.left = objtrouve.rect.left - 50
								
								#verification que l'element a atteint sa limite
								if objtrouve.rect.left <= GLimFinG:
									objtrouve.visible = 0
						
									filename = os.path.join(const.GRepPysycache, 'images', 'button-vide.png')
									imgtmp = pygame.image.load(filename)
									screen = pygame.display.get_surface() 
									objtrouve.image.blit(imgtmp, (0, 0), (0, 0, objtrouve.largeur, objtrouve.hauteur))
									objtrouve.image = imgtmp
									const.GNbButtons = const.GNbButtons - 1
							else:
								objtrouve.rect.left = GLimGauche
						else:
							objtrouve.rect.left = GLimGauche
					else:
						#pas de pb de limites
						objtrouve.rect.left = objtrouve.rect.left - 50
	
				elif str[1] == 1:
					#-------- on change le mvt : haut <--> bas -----------------
					datas.load_sound('sounds', 'center.ogg')
					objtrouve.sens = -1 * objtrouve.sens
				elif str[2] == 1:
					#-------------------- a droite -----------------------------
					datas.load_sound('sounds', 'right.wav')
					ok = 1

					if GLimDroite <= objtrouve.rect.left + 50 + objtrouve.largeur :
						if objtrouve.categ == 2:
							#l'element peut aller a droite... mais 
							#est-il dans la zone pour aller se ranger ?
							if (objtrouve.rect.top > GLimHautD) & (objtrouve.rect.top + objtrouve.hauteur < GLimBasD) :
								objtrouve.rect.left = objtrouve.rect.left + 50
								
								#verification que l'element a atteint sa limite
								if objtrouve.rect.left + objtrouve.largeur >= GLimFinD:
									objtrouve.visible = 0

									filename = os.path.join(const.GRepPysycache, 'images', 'button-vide.png')
									imgtmp = pygame.image.load(filename)

									screen = pygame.display.get_surface() 
									objtrouve.image.blit(imgtmp, (0, 0), (0, 0, objtrouve.largeur, objtrouve.hauteur))
									objtrouve.image = imgtmp
									const.GNbButtons = const.GNbButtons - 1
							else:
								objtrouve.rect.left = GLimDroite - objtrouve.largeur

						else:
							objtrouve.rect.left = GLimDroite - objtrouve.largeur
					else:
						#pas de pb de limites
						objtrouve.rect.left = objtrouve.rect.left + 50

				if ok == 1:
					screen = pygame.display.get_surface()  
#					LstBtn.draw(screen)
					GLstBallons.draw(screen)
					#redessin de la souris a sa position actuelle
#					screen.blit(GMaSouris, GMaSouris_position)
					pygame.display.flip()
				
				return 1


			#------------------ recherche si un bouton de menu -----------------
			for obj in LstBtn.sprites() :
				screen = pygame.display.get_surface()  

				if ( event.pos[0] >= obj.rect.left ) & ( event.pos[0] <= obj.rect.left + obj.largeur ) & ( event.pos[1] >= obj.rect.top  ) & ( event.pos[1] <= obj.rect.top + obj.hauteur ) :
					#----------- show the correct window -----------------
					if ( obj.id == 1 ) :
						#change la vitesse du jeu (normal/moyenne/rapide)
						if const.GSpeed == 3:
							const.GSpeed = 2
							filename = os.path.join(const.GRepPysycache, 'images', 'btn-vitesse2.png')
						elif const.GSpeed == 2:
							const.GSpeed = 1
							filename = os.path.join(const.GRepPysycache, 'images', 'btn-vitesse1.png')
						elif const.GSpeed == 1:
							const.GSpeed = 3
							filename = os.path.join(const.GRepPysycache, 'images', 'btn-vitesse3.png')
						imgtmp = pygame.image.load(filename)

						#mise a jour image 
						screen.blit(Gbackground_image, (obj.rect.left, obj.rect.top), (0, 0, obj.largeur, obj.hauteur))
						obj.image.blit(imgtmp, (obj.rect.left, obj.rect.top), (0, 0, obj.largeur, obj.hauteur))
						obj.image = imgtmp

						#rechargement du jeu
						LoadListConfigFile(GLstThemesButtons[const.GIdxThemes])
						LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes])
						ChangeLogoButtons()
						ok = 1
					if ( obj.id == 2) :
						#Quitter
						return 0
					if ( obj.id == 3) :
						#image avant (dans le theme)
						if const.GIdxImage > 0:
							const.GIdxImage = const.GIdxImage - 1
						else:
							const.GIdxImage = len(GLstFicConfig) - 1

						#transition
						datas.ShowTransitionOfTheme(DUREETRANSITION, 'fond-buttons.bmp')

						LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes])
						ChangeLogoButtons()

						ok = 0
					if ( obj.id == 4) :
						#image apres (dans le theme)
						if const.GIdxImage < len(GLstFicConfig) - 1:
							const.GIdxImage = const.GIdxImage + 1
						else:
							const.GIdxImage = 0
						
						#transition
						datas.ShowTransitionOfTheme(DUREETRANSITION, 'fond-buttons.bmp')

						LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes])
						ChangeLogoButtons()

						ok = 0
					if ( obj.id == 5) :
						#autre theme
						const.GIdxThemes = const.GIdxThemes + 1
						if const.GIdxThemes == len(GLstThemesButtons):
							const.GIdxThemes = 0
						LoadListConfigFile(GLstThemesButtons[const.GIdxThemes])
						LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes])
						ChangeLogoButtons()
						ok = 1
					break
					

			if ok == 1:
				LstBtn.draw(screen)
				GLstBallons.draw(screen)
				#redessin de la souris a sa position actuelle
				screen.blit(GMaSouris, GMaSouris_position)
				pygame.display.flip()
#					return 1
	return 1





#*******************************************************************************
# boucle principale
# si typfull 	= 0 : mode fenetre
#				= 1 : mode plein ecran
#*******************************************************************************
def ShowWindow(typfull):
	global GMaSouris
	global Gbackground_image	#image de fond
	global GMaSouris_position
	global GLstThemesButtons   	#themes des images
								#est obtenue a partir du repertoire datas
	global GLstFicConfig		#liste des fichiers de config dans le theme


	screen = pygame.display.get_surface()

	const.GIdxThemes = 0
	const.GIdxImage = 0
	const.GSpeed = 2



	#------------------- changer la souris en main -------------------
#	filename = os.path.join('images', 'souris.xbm')
#	maskname = os.path.join('images', 'souris-mask.xbm')
#	cursor = pygame.cursors.load_xbm(filename, maskname)
#	cursor = cursor[0], (cursor[0][0] / 2, cursor[0][1] / 2), cursor[2], cursor[3]
#	pygame.mouse.set_cursor(cursor[0], (0, 0), cursor[2], cursor[3])

	filename = dirname = os.path.join(const.GRepPysycache, 'images', 'souris.png')
	GMaSouris = pygame.image.load(filename)
	GMaSouris_position = GMaSouris.get_rect()
	GMaSouris_position.left = const.GPosDepX   
	GMaSouris_position.top = const.GPosDepY
	pygame.mouse.set_pos((GMaSouris_position.left, GMaSouris_position.top))

	#------------------ transition vers le jeu ------------------------
	Gbackground_image, background_rect = datas.load_image('images', 'fond-buttons.bmp')
	for i in range(300):
		screen.blit(Gbackground_image, (0, i), (0, i, 800, 1))
		screen.blit(Gbackground_image, (0, 600 - i), (0, 600 - i, 800, 1))
		pygame.display.flip()
		pygame.time.wait(8) 
	screen.blit(Gbackground_image, (0,0))
	pygame.display.flip()

	#-------------------- liste des boutons ----------------------
	global LstBtn
	LstBtn = pygame.sprite.RenderClear()
	#vitesse du jeu - 0/1/2
	LstBtn.add(BtnMenu(712, 10, 'btn-vitesse2.png', 1, 85, 85))

	#image du theme
	LstBtn.add(BtnMenu(711, 504, 'logo.png', 5, 85, 85))

	#avant et apres
	LstBtn.add(BtnMenu(489, 537, 'btn-avant.png', 3, 60, 60))
	LstBtn.add(BtnMenu(603, 537, 'btn-apres.png', 4, 60, 60))

	#quitter
	LstBtn.add(BtnMenu(25, 535, 'btn-quitter.png', 2, 186, 60))

	GLstFicConfig = []

	#----------------- rechercher les themes disponibles -----------------------
	repertoire = os.path.join(const.GRepPysycache, 'themes-buttons')
	GLstThemesButtons = []
	for nom in os.listdir(repertoire):
		#ne prendre que les repertoires
		isrep = os.path.join(const.GRepPysycache, 'themes-buttons', nom)
		if os.path.isdir(isrep):
			GLstThemesButtons.append(nom)
	if len(GLstThemesButtons) == 1:
		const.GIdxThemes = 0
	else:
		const.GIdxThemes = random.randint(0, len(GLstThemesButtons) - 1)

	#---------- rechercher les fichiers de config d'un theme -------------------
	LoadListConfigFile(GLstThemesButtons[const.GIdxThemes])

	#lire ce fichier de configuration
	LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes])

	ChangeLogoButtons()

	GLstBallons.draw(screen)


	#-------------- entree dans la boucle principale --------------
	clock = pygame.time.Clock ()
	running = 1
	while running:
		clock.tick ( 60 )	#max 60 fps / sec

		#recherche des evt
		running = DetectEvent()

		screen.blit(Gbackground_image, (0,0))
		for o in GLstBallons.sprites():
			o.move()

		LstBtn.draw(screen)


		#verification si on a tout decouvert
		if const.GNbButtons == 0:
			tpsfin = pygame.time.get_ticks()
			pygame.mouse.set_pos((const.GPosDepX, const.GPosDepY))
			const.GTypeSouris = 1		   #on passe en mode gagne
			GMaSouris_position.left = const.GPosDepX 
			GMaSouris_position.top = const.GPosDepY

			GLstBallons.draw(screen)
			pygame.display.flip()

			#on joue la musique de gagne
			datas.PlayWinnerSound()

			#on affiche l'image de gagne
			imggagne, imgfin_rect = datas.load_png('images', 'gagne.png')
			screen.blit(imggagne, (100, 40))
			pygame.display.flip()

			#attende de 3 secondes
			pygame.time.wait(3000)
			
			#transition
			datas.ShowTransitionOfTheme(DUREETRANSITION, 'fond-buttons.bmp')
			
			#on recharge une nouvelle image
			if len(GLstFicConfig) > 1:
				nvidx = random.randint(0, len(GLstFicConfig) - 1)
				if nvidx == const.GIdxImage:
					#si la meme image qu'actuellement, on fait un second essai
					nvidx = random.randint(0, len(GLstFicConfig) - 1)
				const.GIdxImage = nvidx
			pygame.mouse.set_pos((const.GPosDepX, const.GPosDepY))
			LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes])
			const.tpsdebut = pygame.time.get_ticks()

		GLstBallons.draw(screen)
		screen.blit(GMaSouris, GMaSouris_position)
		pygame.display.flip()
