#!/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


VIEWNEVER = 1
VIEWALREADY = 0

PHOTOLOIN = 0
PHOTOPRES = 1

DUREETRANSITION = 3


#*******************************************************************************
#                                                                              #
#                                                                              #
#                                       Classes                                #
#                                                                              #
#                                                                              #
#*******************************************************************************

class ImgPhoto(pygame.sprite.Sprite):
	"""This class is for the mini photos images"""
	def __init__(self, filename, id):
		pygame.sprite.Sprite.__init__(self) 		#call Sprite intializer
		dirname = os.path.join('themes-click', GLstThemesClick[const.GIdxThemes])
		filetmp = os.path.join(dirname, filename)
		if os.path.isfile(filetmp) == True:
			self.image, self.rect = datas.load_png(dirname, filename)
		else :
			self.image, self.rect = datas.load_png('/usr/local/share/pysycache/images', 'vide-off.png')
		self.imagename = filename
		self.rect.left = 712
		self.rect.top = 50 + 51 * id 
		self.id = id

class Photo:
	left = 0
	id = 0
	top = 0
	ray = 0
	view = VIEWNEVER	#0 : oui deja vue
						#1 : non pas encore vue
	mode = PHOTOLOIN	#0 : je suis loin d'une photo	
						#1 : je suis sur une photo, je peux cliquer



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


def InitialiseDessin(idxdirectory):
	"""Initialize new picture """
	directory = GLstThemesClick[idxdirectory]

	#chargement du dessin servant de cache
	filename = os.path.join(directory, GImgBackground) 
	ImgFond, background_rect = datas.load_image('/usr/local/share/pysycache/themes-click', 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))

	#on positionne la souris
	const.GTypeSouris = 0

	LstBtn.draw(screen)
	#redessin de la souris a sa position actuelle
	screen.blit(GMaSouris, GMaSouris_position)
	#rafraichissement
	pygame.display.flip()




#*******************************************************************************
# change le logo du theme 
#  (a partir des repertoires)
#*******************************************************************************
def ChangeLogoClick():
	""" Change logo of a theme """
	if const.GIdxThemes == 999999:
		#tous les themes
		filename = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/images', 'logo.png')
	else:
		#un theme particulier
		filename = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/themes-click', GLstThemesClick[const.GIdxThemes], 'logo.png')

	if os.path.isfile(filename) == True:
		imgtmp = pygame.image.load(filename)
	else:
		filename = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/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, (0, 0), (0, 0, btn.largeur, btn.hauteur))
			btn.image = imgtmp
			break




#*******************************************************************************
#
#*******************************************************************************
def LoadPhotoOfConfig(themename):
	""" Charge les photos a partir d'un fichier de configuration contenus dans le repertoire"""
	screen = pygame.display.get_surface()
	global GImgBackground

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

	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:
			GImgBackground = lig
		else:
			#recuperation des photos pour l'activite
			pho = Photo()
			lig = lig.split('-')
			(shortname, extension) = os.path.splitext(lig[0]) 
			pho.chemin = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/themes-click', themename, lig[0])
			pho.miniature = shortname			#nom (sans extension de la miniature)
			pho.id = cpt - 1
			pho.left = int(lig[1]) + const.MARGELEFT
			pho.top = int(lig[2]) + const.MARGETOP
			pho.ray = int(lig[3])
			pho.view = VIEWNEVER				#pas encore vue
			const.GTabPhotos.append(pho)

		cpt = cpt + 1
	f.close()

	#MAJ du nombre de photos vues
	const.GNbPhotos = 0



#*******************************************************************************
#
#*******************************************************************************
def RAZMiniatures():
	screen = pygame.display.get_surface()  
	
	for pho in const.GTabPhotos:
		for img in GLstImgPhotos.sprites() :
			if img.id == pho.id :
				filename = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/themes-click', GLstThemesClick[const.GIdxThemes], pho.miniature + '-off.png') 
				imgtmp = pygame.image.load(filename)
				screen.blit(Gbackground_image, (img.rect.left, img.rect.top), (0, 0, 96, 50))
				img.image.blit(imgtmp, (0, 0), (0, 0, 96, 50))
				img.image = imgtmp
				break
	GLstImgPhotos.draw(screen)



#*******************************************************************************
# Recherche les fichiers de configuration pour un repertoire
# on recherche tous les fichiers de definition (*.dfg)
# il y a 1 fichier dfg par fichier .png
#*******************************************************************************
def LoadListImage(themename):
	""" Find all definition files of a theme directoy """

	#-------------------------- definition files -------------------------------
	filtre = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/themes-click', themename, '*.dfg')

	#vider
	cptliste = 0
	GLstFicConfig[:] = []

	#----------------------- remplir -----------------------------------
	#chercher les fichiers disponibles
	for nom in glob.glob(filtre):
		if os.path.isfile(nom):
			cptliste = cptliste + 1
			GLstFicConfig.append(nom)

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

	#lire ce fichier de configuration
	LoadPhotoOfConfig(themename)

	#affichage des miniatures des photos a trouver
	#chargement du dessin du nombre de photos prises
	RAZMiniatures()






#*******************************************************************************
# 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:
			#----------------- deplacement de la souris -----------------------------
			screen = pygame.display.get_surface()  

			#redessin de ce que cachait la souris
			tr3 = pygame.Rect([GMaSouris_position.left - 10, GMaSouris_position.top - 10, 120, 120] )
			screen.blit(Gbackground_image, (GMaSouris_position.left - 10, GMaSouris_position.top - 10), tr3 )

			GMaSouris_position.left = event.pos[0] 
			GMaSouris_position.top = event.pos[1] 

			#recherche de la photo
			inarea = 0
			for car in const.GTabPhotos:
				x = car.left - event.pos[0]
				y = car.top - event.pos[1]
					
				if (x * x + y * y < car.ray * car.ray):
					#on est dans la zone proche de la photo
					#on affiche l'appareil photo en rouge pour indiquer 
					inarea = 1
					break

			if inarea == 1:
				#on est bien proche d'une photo
				#on peut afficher l'appareil photo en rouge
				if const.GTypeSouris == 0:
					#on est actuellement en appareil photo normal et on passe en mode couleur
					if const.GWithSound == 1:
						datas.load_sound('/usr/local/share/pysycache/sounds', 'photo-beep0.ogg')

					filename = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/images', 'souris0.png')	   
					souristmp = pygame.image.load(filename)
					colsvg = GMaSouris.get_at((0,0))
					GMaSouris.fill(colsvg)
					GMaSouris.blit(souristmp, (0,0))
					const.GTypeSouris = 1
				else:
					#on est deja en appareil photo en couleur : on ne fait rien
					pass
			else:
				#on est loin d'une photo : 
				#il faut remettre l'appareil photo en normal
				if const.GTypeSouris == 0:
					#on est actuellement en appareil photo normal
					#on ne change pas
					pass
				else:
					#on est en appareil photo en couleur : on passe a normal
					filename = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/images', 'souris1.png')	   
					souristmp = pygame.image.load(filename)
					colsvg = GMaSouris.get_at((0,0))
					GMaSouris.fill(colsvg)
					GMaSouris.blit(souristmp, (0,0))
					const.GTypeSouris = 0

#OK mais lourd		screen.blit(Gbackground_image, (0,0))
			LstBtn.draw(screen)	
			GLstImgPhotos.draw(screen)
			#redessin de la souris a sa position actuelle
			screen.blit(GMaSouris, GMaSouris_position)

			return 1
		elif event.type == MOUSEBUTTONDOWN:
			ok = 0
			screen = pygame.display.get_surface()  

			#*************************** evenement clic *************************
			#recherche si est un bouton
			for obj in LstBtn.sprites() :
				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 == 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-click.bmp')
							
						LoadPhotoOfConfig(GLstThemesClick[const.GIdxThemes])
						RAZMiniatures()
						ok = 1
					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-click.bmp')

						LoadPhotoOfConfig(GLstThemesClick[const.GIdxThemes])
						RAZMiniatures()
						ok = 1
					if ( obj.id == 5) :
						#image du theme : on change de theme
						const.GIdxThemes = const.GIdxThemes + 1
						if const.GIdxThemes == len(GLstThemesClick):
							const.GIdxThemes = 0
						LoadListImage(GLstThemesClick[const.GIdxThemes])
						ChangeLogoClick()
						ok = 1
			
					#----------- update the picture -----------------
					if ok == 1:
						const.GTypeSouris = 3
						InitialiseDessin(const.GIdxThemes)
						LstBtn.draw(screen)
						GLstImgPhotos.draw(screen)
						#redessin de la souris a sa position actuelle
						screen.blit(GMaSouris, GMaSouris_position)
						pygame.display.flip()
					
					return 1

			#recherche de la photo concernee
			inarea = 0
			for car in const.GTabPhotos:
				x = car.left - event.pos[0]
				y = car.top - event.pos[1]
							
				if (x * x + y * y < car.ray * car.ray):
					#on est dans la zone proche de la photo
					#on joue la musique
					const.GTypeSouris = 2;

					#photos pas encore vue... elle le devient
					#on affiche les infos
					if car.view == VIEWNEVER:
						const.GNbPhotos = const.GNbPhotos + 1
						car.view = VIEWALREADY

					#mise a jour du dessin representant la photo prise
					for img in GLstImgPhotos.sprites() :
						if img.id == car.id :
							filename = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/themes-click', GLstThemesClick[const.GIdxThemes], car.miniature + '-on.png') 
							imgtmp = pygame.image.load(filename)
							screen.blit(Gbackground_image, (img.rect.left, img.rect.top), (0, 0, 96, 50))
							img.image.blit(imgtmp, (img.rect.left, img.rect.top), (0, 0, 96, 50))
							img.image = imgtmp
							break

					datas.load_sound('/usr/local/share/pysycache/sounds', 'photo-click.ogg');

					#on affiche la photo
					screen.blit(Gbackground_image, (0,0))
					LstBtn.draw(screen)
					GLstImgPhotos.draw(screen)
					pygame.display.flip()
					imgtmp = pygame.image.load(car.chemin)
					screen.blit(imgtmp, [50, 50] )
					pygame.display.flip()

					#on patiente deux secondes
					pygame.time.delay(2000)

					#on efface tout
					screen.blit(Gbackground_image, (0,0))
					pygame.display.flip()
					pygame.mouse.set_pos((GMaSouris_position.left, GMaSouris_position.top))
					const.GTypeSouris = 1;

					break


				LstBtn.draw(screen)	
				GLstImgPhotos.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 GLstThemesClick 		#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.GTypeSouris = 3
	pygame.mouse.set_visible(0) 	#on cache la souris pour tout le jeu

	pygame.mouse.set_pos((const.GPosDepX, const.GPosDepY))


	#------------------- 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 = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/images', 'souris1.png')	   
	GMaSouris = pygame.image.load(filename)
	GMaSouris_position = GMaSouris.get_rect()
	GMaSouris_position.left = const.GPosDepX   
	GMaSouris_position.top =  const.GPosDepY
	const.Gtypsouris = 0

	#------------------ transition vers le jeu ------------------------
	Gbackground_image, background_rect = datas.load_image('/usr/local/share/pysycache/images', 'fond-click.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()

	#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, '/usr/local/share/pysycache/themes-click')
	GLstThemesClick = []
	for nom in os.listdir(repertoire):
		#ne prendre que les repertoires
		isrep = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/themes-click', nom)
		if os.path.isdir(isrep):
			GLstThemesClick.append(nom)

	#------- preparer les miniatures des photos avec des valeurs vides ---------
	global GLstImgPhotos
	GLstImgPhotos = pygame.sprite.RenderClear()
	for i in range(6):
		GLstImgPhotos.add(ImgPhoto('', i))
	GLstImgPhotos.draw(screen)

	#--------------------- rechercher les images d'un theme --------------------
	#------------------- le premier theme est choisi au hasard -----------------
	if len(GLstThemesClick) == 1:
		const.GIdxThemes = 0
	else:
		const.GIdxThemes = random.randint(0, len(GLstThemesClick) - 1)
	LoadListImage(GLstThemesClick[const.GIdxThemes])

	ChangeLogoClick()

	#------------------------- affichage du dessin -----------------------------
	InitialiseDessin(const.GIdxThemes)

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

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

			#on affiche l'image de gagne
			screen = pygame.display.get_surface()
			imggagne, imgfin_rect = datas.load_png('/usr/local/share/pysycache/images', 'gagne.png')
			screen.blit(imggagne, (100, 40))
			LstBtn.draw(screen)
			GLstImgPhotos.draw(screen)
			pygame.display.flip()

			#on joue le son (bloquant)
			datas.PlayWinnerSound()
			
			#attende de 3 secondes pour voir l'image de gagne
			pygame.time.wait(3000)
			
			#transition
			datas.ShowTransitionOfTheme(DUREETRANSITION, 'fond-click.bmp')

			#on recharge une nouvelle serie de photos
			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
			LoadPhotoOfConfig(GLstThemesClick[const.GIdxThemes])
			RAZMiniatures()

			#on remet la souris en normal
			filename = os.path.join(const.GRepPysycache, '/usr/local/share/pysycache/images', 'souris1.png')
			souristmp = pygame.image.load(filename)
			colsvg = GMaSouris.get_at((0,0))
			GMaSouris.fill(colsvg)
			GMaSouris.blit(souristmp, (0,0))
			const.GTypeSouris = 0

			pygame.mouse.set_pos((const.GPosDepX, const.GPosDepY))
			InitialiseDessin(const.GIdxThemes)
			const.tpsdebut = pygame.time.get_ticks()

	#----------------------------- fin du jeu ----------------------------------
	pygame.mouse.set_visible(0)
