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





#*******************************************************************************
#                                       Classes                                #
#*******************************************************************************
class Target:
	id = 0
	left = 0
	top = 0
	boxleft = 0
	boxtop = 0
	largeur = 0
	hauteur = 0
	typetgt = 0
	tofound = 0				#1 : c'est la cible qu'il faut cliquer (mode fantome)
	visible = False
	imagefile = ""
	imagetofound = ""		#-selected.png
	imagefound = ""			#-on.png
	imagenotfound = ""		#-off.png
	firstclick = pygame.time.get_ticks()
	isclicked = 0			#0 : pas clicke
							#1 : deja clicke



#*******************************************************************************
#    
#*******************************************************************************
class ApplicationDblClick(ApplicationPysy):
	def __init__(self):
		ApplicationPysy.__init__(self)
		self.GImgBackground = ""


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

		if const.GWithSound == 1:
			if const.GSoundError == 0:
				self.Channel0 = pygame.mixer.Channel(0)
				music = os.path.join(const.GRepPysycache, 'sounds', 'double-click.wav').encode(const.GConsoleLocale)
				self.Sound0 = pygame.mixer.Sound(music)



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

	#***************************************************************************
	#
	#***************************************************************************
	def DoInitLevel(self):
		""" """
		pass


	#***************************************************************************
	#
	#***************************************************************************
	def DoTheVisibleEvent(self):
		#a surcharger par chaque application
		ApplicationPysy.DoTheVisibleEvent(self)

		screen = pygame.display.get_surface() 
		self.ChangeVisibiliteTargets()
		self.DrawTarget()
		const.GLstSouris.draw(screen)
		pygame.display.update()


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

		oldGTypeSouris = const.GTypeSouris
		const.GTypeSouris == const.EVENT_NOVENT

		screen = pygame.display.get_surface()  

		#recherche de la cible concernee
		todelete = 9999
		cpt = 0
		found = 999
		for car in const.GTabTarget:

			if car.visible == False:
				cpt += 1
				continue

			if ( event0 + const.DEMISOURIS >= car.left ) & ( event0 + const.DEMISOURIS <= car.left + car.largeur ) & ( event1 + const.DEMISOURIS >= car.top  ) & ( event1 + const.DEMISOURIS <= car.top + car.hauteur ) :
				found = cpt
			cpt += 1

		idx = 0
		if found != 999:
			if const.GTabTarget[found].isclicked == 0 : 
				#cible non cliquee jusqu'a present
				const.GTabTarget[found].firstclick = pygame.time.get_ticks()
				const.GTabTarget[found].isclicked = 1
			else:
				#cible deja cliquee... mais dans les temps ?
				if pygame.time.get_ticks() - const.GTabTarget[found].firstclick < (900 / (const.GLevel + 1)):
					ok = 0
					#ok, dans les temps, mais est-ce la bonne cible ?
					if const.GModeJeu == const.MODEFANTOM :
						if const.GTabTarget[found].typetgt == const.GCategToClick:
							ok = 1
					else:
						ok = 1

					if ok == 1:
						datas.DebugMessage("           Double click on item %i  (and GItemToClick=%i) " %  (const.GTabTarget[found].id, const.GItemToClick ))

						todelete = found
						const.GTabTarget[found].visible = False
						const.GTabTarget[found].isclicked = 0
#						datas.Load_sound("sounds", "double-click.wav")
						if const.GWithSound == 1:
							if const.GSoundError == 0:
								self.Channel0.play(self.Sound0)


						#effacement du dessin de GItemToClick car c'est peut
						#etre quelqu'un d'autre mais de la meme categorie qui
						#a ete cliquee
						i = 0
						for tgt in const.GTabTarget:
							if i == const.GItemToClick:
								imgtmp, recttmp =  datas.Load_image("", tgt.imagenotfound, None, True)
								self.Background.blit(imgtmp, (tgt.boxleft, tgt.boxtop))
								self.BackgroundClear.blit(imgtmp, (tgt.boxleft, tgt.boxtop))
								screen.blit(imgtmp, (tgt.boxleft, tgt.boxtop))
								break
							i += 1

						#mise a jour des miniatures dans la boites
						imgtmp, recttmp =  datas.Load_image("", const.GTabTarget[found].imagefound, None, True)
						self.Background.blit(imgtmp, (const.GTabTarget[found].boxleft, const.GTabTarget[found].boxtop))
						self.BackgroundClear.blit(imgtmp, (const.GTabTarget[found].boxleft, const.GTabTarget[found].boxtop))
						screen.blit(imgtmp, (const.GTabTarget[found].boxleft, const.GTabTarget[found].boxtop))
				else:
					#pas dans les temps : on remet a zero
#					print "pas dans les temps"
					const.GTabTarget[found].firstclick = pygame.time.get_ticks()
					const.GTabTarget[found].isclicked = 1


		if todelete != 9999:
			#suppression de la cible 
			#on affiche l'arriere plan
			self.DrawTarget()
			#on supprime
			del const.GTabTarget[todelete]

			if len(const.GTabTarget) >= 1:
#				print "on recherche un nouvel item"
				self.RAZTarget()
				self.DrawTarget()

				self.GetCategToClick()
				#on affiche les miniatures dans les boites
				i = 0
				for tgt in const.GTabTarget :
					if const.GModeJeu == const.MODEFANTOM :
						if i == const.GItemToClick:
							imgtmp, recttmp =  datas.Load_image("", tgt.imagetofound, None, True)
							self.Background.blit(imgtmp, (tgt.boxleft, tgt.boxtop))
							self.BackgroundClear.blit(imgtmp, (tgt.boxleft, tgt.boxtop))
							screen.blit(imgtmp, (tgt.boxleft, tgt.boxtop))
							break
					i += 1

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

		const.GTypeSouris = oldGTypeSouris


	#***************************************************************************
	#
	#***************************************************************************
	def GetCategToClick(self):
		if const.GModeJeu == const.MODEFANTOM :
			#on va tirer au sort un element puis prendre sa categorie
			const.GItemToClick = random.randint(0, len(const.GTabTarget) - 1)

			ok = 0
			while ok == 0:
				if const.GTabTarget[const.GItemToClick].visible == True:
					#item visible... 
					const.GCategToClick = const.GTabTarget[const.GItemToClick].typetgt
					ok = 1
				else:
					#item invisible... on recommence
					const.GItemToClick = random.randint(0, len(const.GTabTarget) - 1)
		else:
			const.GCategToClick = 999

#		print "il faudra trouver la categ ", const.GCategToClick, " et l'item ", const.GItemToClick


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

		screen = pygame.display.get_surface()
		const.GCategToClick = 999

		#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 de position des items
			configname = self.LstFicConfig[self.IdxFileDfg]

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

				if cpt == 0:
					pass
				else:
					#recuperation des cibles pour l'activite
					#image - image a trouver - nb mini - nb maxi - gauche coin gauche - haut coin gauche - bas coin droit - droit coin droit
					lig = lig.split('|')
					#les limites de la zone de destination des cibles
					LimGauche = int(lig[2]) + const.MARGELEFT
					LimHaut = int(lig[3]) + const.MARGETOP
					LimDroite = int(lig[4]) + const.MARGELEFT
					LimBas = int(lig[5]) + const.MARGETOP
					rect = pygame.Rect([LimGauche - const.MARGELEFT, LimHaut - const.MARGETOP, LimDroite - LimGauche, LimBas - LimHaut])
					pygame.draw.rect(ImgFond, (255, 0, 0, 50), rect, 0)

				cpt += 1
			f.close()

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

		self.GetCategToClick()

		#affichage des miniatures dans la boites
		i = 0
		for tgt in const.GTabTarget :
			if const.GModeJeu == const.MODEFANTOM :
				if i == const.GItemToClick:
					imgtmp, recttmp =  datas.Load_image("", tgt.imagetofound, None, True)
				else:
					imgtmp, recttmp =  datas.Load_image("", tgt.imagenotfound, None, True)
			else:
				imgtmp, recttmp =  datas.Load_image("", tgt.imagenotfound, None, True)
			self.Background.blit(imgtmp, (tgt.boxleft, tgt.boxtop))
			self.BackgroundClear.blit(imgtmp, (tgt.boxleft, tgt.boxtop))
			screen.blit(imgtmp, (tgt.boxleft, tgt.boxtop))
			i += 1

		#on va copier sur l'ecran les elements a double cliquer
		self.DrawTarget()


	#***************************************************************************
	#
	#***************************************************************************
	def DrawTarget(self):
		screen = pygame.display.get_surface()

		#on efface tous les caches
		for img in const.GTabTarget :
#			if img.visible == False:
			img.isclicked = 0
			imgtmp, recttmp = datas.Load_image("", img.imagefile, True)
			(img.largeur, img.hauteur) = imgtmp.get_size()
			self.Background.blit(self.BackgroundClear, (img.left, img.top), ([img.left, img.top, img.largeur, img.hauteur]) )
			screen.blit(self.BackgroundClear, (img.left, img.top), ([img.left, img.top, img.largeur, img.hauteur]) )

		#on affiche que les visibles
		for img in const.GTabTarget :
			if img.visible == True:
				imgtmp, recttmp = datas.Load_image("", img.imagefile, True)
				(img.largeur, img.hauteur) = imgtmp.get_size()
				self.Background.blit(imgtmp, (img.left, img.top))
				screen.blit(imgtmp, (img.left, img.top))


	#***************************************************************************
	# Selon le niveau, on ne vas pas afficher toutes les cibles en meme temps
	# il faut avoir vide la liste avant
	#***************************************************************************
	def RAZTarget(self):
		pygame.time.set_timer(const.EVTVISIBLE, 0)

		if len(const.GTabTarget) == 0:
			pass
		else:
			#--------- selon le niveau, on rend visible certains elements ----------
			if const.GLevel == 0:												#facile 
				#on rend visible une seule cible a la fois
				idx = random.randint(0, len(const.GTabTarget) - 1)
				self.MakeTargetVisible(idx, True)
			elif const.GLevel == 1:												#moyen
				#on rend visible plusieurs cibles en meme temps
				if len(const.GTabTarget) <= 3:
					for i in range (0, len(const.GTabTarget)) :
						self.MakeTargetVisible(i, True)
				else:
					for i in range (0, len(const.GTabTarget)) :
						x = random.randint(0, 1)			#0 : invisible - 1 : visible
						if x == 0:
							self.MakeTargetVisible(i, False)
						else:
							self.MakeTargetVisible(i, True)
			else:																#difficile
				#on rend visible toutes les cibles et de temps en temps elles disparaissent
				if len(const.GTabTarget) <= 4:
					for i in range (0, len(const.GTabTarget)) :
						self.MakeTargetVisible(i, True)
				else:
					for i in range (0, len(const.GTabTarget)) :
						x = random.randint(0, 1)			#0 : invisible - 1 : visible
						if x == 0:
							self.MakeTargetVisible(i, False)
						else:
							self.MakeTargetVisible(i, True)

				#evenement pour changer la visibilite de la cible
				pygame.time.set_timer(const.EVTVISIBLE, 2000)


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


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


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

		""" Charge les cibles a partir d'un fichier de configuration contenus dans le repertoire"""
		screen = pygame.display.get_surface()

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

		LstFound = []

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

		datas.DebugMessage("")
		datas.DebugMessage("dfg file (number %i ) named %s " %( self.IdxFileDfg, configname ))

		(dirpath, dirname) = os.path.split(configname)

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

			if cpt == 0:
				self.GImgBackground = os.path.join(dirpath, lig)
				cpdid = 0
			else:
				#recuperation des cibles pour l'activite
				#image - image a trouver - nb mini - nb maxi - gauche coin gauche - haut coin gauche - bas coin droit - droit coin droit
				lig = lig.split('|')

				#le nombre de cible a generer
				nb1 = int(lig[1])
				datas.DebugMessage("...number of targets : %i " % nb1)
				#les limites de la zone de destination des cibles
				LimGauche = int(lig[2]) + const.MARGELEFT
				LimHaut = int(lig[3]) + const.MARGETOP
				LimDroite = int(lig[4]) + const.MARGELEFT
				LimBas = int(lig[5]) + const.MARGETOP

				for i in range (nb1) :
					tgt = Target()
					tgt.imagefile = os.path.join(dirpath, lig[0] + ".png")
					tgt.imagetofound = os.path.join(dirpath, lig[0] + "-selected.png")		#image a decouvrir
					tgt.imagefound = os.path.join(dirpath, lig[0] + "-on.png")				#image normale
					tgt.imagenotfound = os.path.join(dirpath, lig[0] + "-off.png")			#image de la silhouette (non dbl cliquee)
					x = random.randint(LimGauche, LimDroite - 92)		#92 = largeur max d'une image
					y = random.randint(LimHaut, LimBas - 92)
					tgt.id = cpdid
					tgt.left = x + 27
					tgt.top = y 
					if cpdid <= 6:
						tgt.boxleft = 39 + 91 * cpdid
						tgt.boxtop = 490
					else:
						tgt.boxleft = 39 + 91 * (cpdid - 7)
						tgt.boxtop = 545
					tgt.typetgt = cpt
					datas.DebugMessage("item id = " + str(cpdid) + " categ = " + str(cpt))
					const.GTabTarget.append(tgt)

					cpdid += 1

					datas.DebugMessage("...position on background left=" + str(tgt.left) + " top=" + str(tgt.top))

			cpt += 1
		f.close()

		self.RAZTarget()

#		const.GNbTarget = len(const.GTabTarget)


	#***************************************************************************
	#
	#***************************************************************************
	def ChangeVisibiliteTargets(self):
		if const.GLevel != 2:
			pass
		else:
			#valable que pour le niveau difficile et s'il y a au moins 4 elements
			#on choisit une cible au hasard et on change sa visibilite
			if len(const.GTabTarget) > 3:
				#une ou plusieurs cibles ?
				idx = random.randint(0, len(const.GTabTarget) - 1)
				x = random.randint(0, 1) 			#0 : invisible - 1 : visible
				if x == 0 :
					self.MakeTargetVisible(idx, False)
				else:
					self.MakeTargetVisible(idx, True)
#			else:
#				self.MakeTargetVisible(idx, True)


	#***************************************************************************
	#
	#***************************************************************************
	def MakeTargetVisible(self, idx, visible):
		datas.DebugMessage("Change visibility of item num %i " % idx)

		if const.GTabTarget[idx].visible != visible :
			const.GTabTarget[idx].isclicked = 0
			const.GTabTarget[idx].visible = visible

#		cpt = 0
#		for img in const.GTabTarget :
#			if cpt == idx :
#				img.isclicked = 0
#				if img.visible != visible:
#					#on ne change que si sont differents
#					if visible == True:
#						#on rend la cible visible
#						if const.GDebug == 1:
#							print "...visible"
#					else:
#						#on rend invisible la cible
#						if const.GDebug == 1:
#							print "...invisible"
#					img.visible = visible
#
#				break
#			cpt += 1
