#!/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, os
import glob
import locale
import pygame
from pygame.locals import *

import const



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

#*******************************************************************************
# Show help about pysycache
#*******************************************************************************
def Help_message():
	print '''
Pysycache is an educative software for teach to use the mouse

Usage : 
python ./pysycache.py

Options : 
    -h                : displays this help message
    -nf               : no fullscreen mode
    -ns               : no sound mode  
    -nh               : no sounds for menus
    -nc               : no credits at the end of the game 
    -debug            : show message for debug
    -lang=XX          : use the XX lang for menus 
                        (see in the directory lang for remplace
                         XX by the correct name)
    -font=XX          : use the font filename XX for menus 
                        (it must be placed in the fonts directory)
    --version         : displays Pysycache version
    ---python-version : displays Pysycache version
'''
	sys.exit(0)



#*******************************************************************************
# Show a unicode message in the console
#*******************************************************************************
def DebugMessage(message):
	if const.GDebug == 1:
		print message.encode(const.GConsoleLocale, "ignore")



#*******************************************************************************
# Charge une image (png, bmp ou jpeg)                                          #
#    isfullpath : 0      relative path                                         #
#               : 1      absolute path                                         #
#*******************************************************************************
def Load_image(dirname, filename, colorkey=None, isfullpath=False):
	""" Load png, bmp or jpeg image"""

	#recherche de l'extension
	(shortname, extension) = os.path.splitext(filename) 

	if string.upper(extension) == '.BMP':
		imagetmp, imagetmp_rect = Load_bmp(dirname, filename, colorkey, isfullpath)
	if string.upper(extension) == '.JPG':
		imagetmp, imagetmp_rect = Load_bmp(dirname, filename, colorkey, isfullpath)
	if string.upper(extension) == '.JPEG':
		imagetmp, imagetmp_rect = Load_bmp(dirname, filename, colorkey, isfullpath)
	if string.upper(extension) == '.PNG':
		imagetmp, imagetmp_rect = Load_png(dirname, filename, isfullpath)

	return imagetmp, imagetmp_rect



#*******************************************************************************
# Charge une image de type bmp ou jpeg
#*******************************************************************************
def Load_bmp(dirname, filename, colorkey=None, isfullpath=False):
	""" Load bmp or jpeg image and return image object"""
	if isfullpath:
		#le chemin est complet
		fullname = filename.encode(const.GConsoleLocale)
	else:
		fullname = os.path.join(const.GRepPysycache, dirname, filename).encode(const.GConsoleLocale)

	try:
		image = pygame.image.load(fullname)
	except pygame.error, message:
		print 'Cannot load image: ', fullname
		raise SystemExit, message

	image = image.convert()
	if colorkey is not None:
		if colorkey is -1:
			colorkey = image.get_at((0,0))
		image.set_colorkey(colorkey, RLEACCEL)

	return image, image.get_rect()


#*******************************************************************************
# Charge une image de type png
#*******************************************************************************
def Load_png(dirname, filename, isfullpath=False):
	""" Load png image and return image object"""


	if isfullpath:
		#le chemin est complet
		fullname = filename.encode(const.GConsoleLocale)
	else:
		fullname = os.path.join(const.GRepPysycache, dirname, filename).encode(const.GConsoleLocale)

	try:
		image = pygame.image.load(fullname)
		(ht, lg) = image.get_size()
		if image.get_alpha is None:
			image = image.convert()
		else:
			image = image.convert_alpha()
	except pygame.error, message:
		print 'Cannot load image:', fullname
		raise SystemExit, message

	#A GARDER !!!!!!!!!!!!!!!!!!
#	imagescaled = pygame.transform.scale(image, (ht * 0.8, lg * 0.8))		#0.8 = 640 / 800

	return image, image.get_rect()
#	return imagescaled, image.get_rect()




#*******************************************************************************
# Play sound                                                                   #
#*******************************************************************************
def Load_sound(dirname, filename):
	""" Play sound """
	#on joue la musique
	if const.GWithSound == 1:
		if const.GSoundError == 0:
			fullname = os.path.join(const.GRepPysycache, dirname, filename).encode(const.GConsoleLocale)

			if not pygame.mixer.get_init():
				print "Cannot load sound : pygame error : ", pygame.get_error()
			else:
				if os.path.isfile(fullname):
					pygame.mixer.music.load(fullname)
					pygame.mixer.music.play(0)
				else:
					DebugMessage("sound file %s doesn't exist ! " % os.path.join(const.GRepPysycache, dirname, filename))


#*******************************************************************************
# Play the winner sound
#*******************************************************************************
def PlayWinnerSound():
	idxsnd = random.randint(0, 2)
	if idxsnd == 0 :
		Load_sound("sounds", "youpee.ogg")
	elif idxsnd == 1 :
		Load_sound("sounds", "yahoo.ogg")
	else :
		Load_sound("sounds", "rire.ogg")


#*******************************************************************************
# Make transition between two pictures 
#*******************************************************************************
def ShowTransitionOfTheme(duree, fileimage, withsound = 1):
	screen = pygame.display.get_surface()

	if withsound == 1:
		Load_sound("sounds", "transition.ogg")

	background_image2, background_rect = Load_image("images", fileimage)

	for i in range(300):
		tr2 = pygame.Rect([0, i, 800, 1] )
		screen.blit(background_image2, (0, i), tr2)
		pygame.display.update(tr2)

		tr2 = pygame.Rect([0, 600 - i, 800, 1] )
		screen.blit(background_image2, (0, 600 - i), tr2)
		pygame.display.update(tr2)

		pygame.time.wait(duree)

	#mettre tous les boutons en petits
#	if const.GIdBtnSurvol != 99:
#		if LstBtn != None :
#			for obj in LstBtn.sprites() :
#				obj.ShowSmallBtn()
	const.GIdBtnSurvol = 99

	screen.blit(background_image2, (0,0))
	pygame.display.update()


#*******************************************************************************
# Change the mouse in hand                                                     #
#*******************************************************************************
#def ChangeMouseInHand(left, top):
##	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')
#	const.GMaSouris, imgtmprect = Load_image("images", 'souris.png')
#	const.GMaSouris_position = const.GMaSouris.get_rect()
#	const.GMaSouris_position.left = left
#	const.GMaSouris_position.top = top
#	const.GMaSourisOldPositionX = left
#	const.GMaSourisOldPositionY = top
#	pygame.mouse.set_pos((const.GMaSouris_position.left, const.GMaSouris_position.top))






#*******************************************************************************
# Attends le temps necessaire                                                  #
#*******************************************************************************
def Temporisation():
#	const.Gclock.tick ( const.Gfps )	#max XXX fps / sec
						#Note that this function uses SDL_Delay function which 
						#is not accurate on every platform, but does not use much cpu
	pygame.time.wait(1)


#*******************************************************************************
# Show the FPS                                                                 #
#*******************************************************************************
def ShowFPS():
	if const.GDebug == 1:
#		const.frames += 1
		if pygame.time.get_ticks() - const.lastFPSTime >= 400:
#			print "fps pygame=", const.Gclock.get_fps()
#			#toutes les secondes, on affiche le nb de fps
#			print "FPS:", const.frames
#			const.frames = 0
			const.lastFPSTime = pygame.time.get_ticks()


#*******************************************************************************
# Verification des limites de la souris : il ne faut pas qu'elle sorte         #
# de la zone de jeux                                                           #
#*******************************************************************************
def VerifLimitesSouris(LimX = 780, LimY = 580, LimXX = 0, LimYY = 0):
	if const.GMaSourisCurrentPositionX > LimX :
		const.GMaSourisCurrentPositionX = LimX
	if const.GMaSourisCurrentPositionY > LimY :
		const.GMaSourisCurrentPositionY = LimY

	if const.GMaSourisCurrentPositionX < LimXX :
		const.GMaSourisCurrentPositionX = LimXX
	if const.GMaSourisCurrentPositionY < LimYY :
		const.GMaSourisCurrentPositionY = LimYY



#*******************************************************************************
# Charge le dictionnaire de la langue
#*******************************************************************************
def LoadDicoLang():
	#vider
	const.GDicoLangue.clear()

	filename = os.path.join(const.GRepPysycache, "lang", const.GMyLocale, "textes.txt")

	#lecture du fichier de langue
	DebugMessage("")
	DebugMessage("Reading the lang file %s " % filename )

	if os.path.isfile(filename):
		f = open(filename, 'r')
		lignes  = f.readlines()
		for lig in lignes:
			lig = lig.strip()
			lig = lig.split('=')

			if len(lig) < 2:
				continue

			const.GDicoLangue[lig[0]] = lig[1].decode("utf-8", "ignore")

		f.close()
	else:
		DebugMessage("")
		DebugMessage("Lang file doesn't exist")


#*******************************************************************************
#
#*******************************************************************************
def GetTextInLang(IdText, Default):
	if const.GDicoLangue.has_key(IdText):
		text =  const.GDicoLangue[IdText]
	else:
		text = Default

	return text


#*******************************************************************************
# Ecrit le texte dans la langue                                                #
#*******************************************************************************
def WriteTextInLang(IdText, Default, image, left, top, size, largmax = -1):
	"""Write a text on the screen in the locale lang \n
	   if left = -1 : the text is centered
	"""

	myfont = os.path.join(const.GRepPysycache, 'fonts', const.GFontName).encode(const.GConsoleLocale)
	font = pygame.font.Font(myfont, size)
	textcolor = 46, 113, 169

	str = GetTextInLang(IdText, Default)

#OK		text = font.render(unicode(username, "utf-8"), 1, textcolor).convert_alpha()
	text = font.render(str , 1, textcolor).convert_alpha()
	(larg, haut) = text.get_size()
	if left == -1:
		if largmax > 0 :
			if larg > largmax:
				larg = largmax
			left = 10 + int( (720- larg) / 2 )
			tr2 = pygame.Rect([0, 0, larg, haut] )
			image.blit(text, (left, top), tr2 )
		else:
			left = 10 + int( (720- larg) / 2 )
			image.blit(text, (left, top)) 
	else:
		if largmax > 0 :
			if larg > largmax:
				larg = largmax
			tr2 = pygame.Rect([0, 0, larg, haut] )
			image.blit(text, (left, top), tr2 )
		else:
			image.blit(text, (left, top))


#*******************************************************************************
#    
#*******************************************************************************
def ShowHelpOfBoutonMenu(id, imgdest):
	myfont = os.path.join(const.GRepPysycache, 'fonts', const.GFontName ).encode(const.GConsoleLocale)
	font = pygame.font.Font(myfont, 20)
	textcolor = 46, 113, 169
	screen = pygame.display.get_surface()

	myrep = os.path.join(const.GRepPysycache, 'lang', const.GMyLocale )

	#joue le fichier d'aide
	if const.GWithSound == 1:
		if const.GWithHelp == 1 :
			dirname = os.path.join(const.GRepPysycache, 'lang', const.GMyLocale)
			filename = 'menu' + str(id) + '.ogg'
			Load_sound(dirname, filename)

	#affiche l'aide
	if os.path.isdir(myrep):
		filename = os.path.join(const.GRepPysycache, 'lang', const.GMyLocale , 'menu' + str(id) + '.txt')
	else :
		filename = os.path.join(const.GRepPysycache, 'lang', 'en_EN' , 'menu' + str(id) + '.txt')

	filename = os.path.join(const.GRepPysycache, 'lang', const.GMyLocale , 'menu' + str(id) + '.txt')
	if os.path.isfile(filename):
		f = open(filename, 'r')
		lignes  = f.readlines()
		cptligne = 0
		for j in lignes:
			j = j.strip()
#			text = font.render(unicode(j, "utf-8"), 1, textcolor)
			text = font.render(j.decode("utf-8", "ignore"), 1, textcolor)

			imgdest.blit(text, (200, 361 + 25 * cptligne))
			screen.blit(text, (200, 361 + 25 * cptligne))

			cptligne += 1
		f.close()
		pygame.display.update()


#*******************************************************************************
#
#*******************************************************************************
def InitializePreferences():
	#------ confrontation des pref utilisateur et valeurs par defaut -----------
	if const.GPrefUserFromOptions.FullScreen == 0:
		#valeur ecrasee par passage parametre
		const.GWithFullScreen = 0
	else:
		const.GWithFullScreen = const.GPrefUserInit.FullScreen

	if const.GPrefUserFromOptions.Sound == 0:
		#valeur ecrasee par passage parametre
		const.GWithSound = 0
	else:
		const.GWithSound = const.GPrefUserInit.Sound

	if const.GDureeTransition != const.GPrefUserInit.Transition:
		const.GDureeTransition = const.GPrefUserInit.Transition


#*******************************************************************************
#
#*******************************************************************************
def InitializeLang():
	DebugMessage("")
	DebugMessage ("Lang asked : %s " % const.GPrefUserFromOptions.Lang)
	DebugMessage ("Detection of the lang")

	if const.GPrefUserFromOptions.Lang != "":
		#on a force la langue 
		DebugMessage("MyLocale comes from option ")
		const.GMyLocale = const.GPrefUserFromOptions.Lang
	else:
		if const.GPrefUserInit.Lang != '':
			#on prend la valeur du fichier de configuration
			DebugMessage("MyLocale comes from file ")
			const.GMyLocale = const.GPrefUserInit.Lang
		else:
			DebugMessage("MyLocale comes from automatic detection ")
			const.GMyLocale = locale.getdefaultlocale()[0]
#			locale.setlocale(locale.LC_ALL, localeold)
#			print locale.getlocale()
#			print myencoding

	DebugMessage("MyLocale (Lang) found is %s " % const.GMyLocale)

	if const.GMyLocale == None:
		const.GMyLocale = 'en_EN'
	if const.GMyLocale.strip()  == "":
		const.GMyLocale = 'en_EN'

	myrep = os.path.join(const.GRepPysycache, 'lang', const.GMyLocale )
	if os.path.isdir(myrep):
		#le repertoire de la locale existe : rien a faire
		pass
	else :
		#chance 1 : on essaie sur les deux premiers caracteres en double (le pays)
		#par exemple fr_FR en place de fr_BE
		myrep = os.path.join(const.GRepPysycache, 'lang', const.GMyLocale[0:2] + '_' + string.upper(const.GMyLocale[0:2]) )
		if os.path.isdir(myrep):
			const.GMyLocale = const.GMyLocale[0:2] + '_' + string.upper(const.GMyLocale[0:2])
		else :
			#chance 2 : on essaie sur le seul pays (par exemple fr)
			myrep = os.path.join(const.GRepPysycache, 'lang', const.GMyLocale[0:2] )
			if os.path.isdir(myrep):
				const.GMyLocale = const.GMyLocale[0:2] 
			else :
				#valeur par defaut
				const.GMyLocale = 'en_EN'



	#test pour la police et les langes arabes
	if const.GPrefUserFromOptions.FontName != "" :
		#une langue a ete passee en parametres : on l'utilise
		const.GFontName = const.GPrefUserFromOptions.FontName
	else:
		#aucune langue passe en parametres, mais est-ce 
		#une langue qui necessite une police speciale ?
		if string.upper(const.GMyLocale[0:2]) == "AR" :
			const.GFontName = "ae_AlMothnna_bold.ttf"
		else:
			const.GFontName = "FreeSansBold.ttf"

	DebugMessage("Lang used = %s " % const.GMyLocale)


#*******************************************************************************
#
#*******************************************************************************
def ShowCreditsOfPySyCache(consoleadmin):
	myfont = os.path.join(const.GRepPysycache, 'fonts', const.GFontName ).encode(const.GConsoleLocale)
	font = pygame.font.Font(myfont, 30)
	textcolor = 46, 113, 169

	screen = pygame.display.get_surface()  

	#credits auteur
	fichier = os.path.join(const.GRepPysycache, 'lang', const.GMyLocale, 'credits.txt')
	if os.path.isfile(fichier):
		#afficher le contenu 
		f = open(fichier, 'r')
		lignes  = f.readlines()
		cptligne = 0
		for j in lignes:
			j = j.strip()
#			text = font.render(unicode(j, "utf-8"), 1, textcolor)
			text = font.render(j.decode("utf-8", "ignore"), 1, textcolor)
			screen.blit(text, (30, 30 + 40 * cptligne))	  
			cptligne += 1
		pygame.display.update()
		f.close()
		pygame.time.wait(3500) 

	#pub pour autres themes
	fichier = os.path.join(const.GRepPysycache, 'lang', const.GMyLocale, 'themes.txt')
	if os.path.isfile(fichier):
		const.Gbackground_image, background_rect = Load_image("images", "fond-themes.png")
		ShowTransitionOfTheme(const.GDureeTransition, "fond-themes.png")
		#afficher le contenu 
		f = open(fichier, 'r')
		lignes  = f.readlines()
		cptligne = 0
		for j in lignes:
			j = j.rstrip()
#			text = font.render(unicode(j, "utf-8"), 1, textcolor)
			text = font.render(j.decode("utf-8", "ignore"), 1, textcolor)
			screen.blit(text, (30, 30 + 40 * cptligne))	  
			cptligne += 1
		pygame.display.update()
		f.close()
		pygame.time.wait(3500) 

	#licence
	fichier = os.path.join(const.GRepPysycache, 'lang', const.GMyLocale, 'licences.txt')
	if os.path.isfile(fichier):
		const.Gbackground_image, background_rect = Load_image("images", "fond-licences.png")
		ShowTransitionOfTheme(const.GDureeTransition, "fond-licences.png")
		#afficher le contenu 
		f = open(fichier, 'r')
		lignes  = f.readlines()
		cptligne = 0
		for j in lignes:
			j = j.rstrip()
#			text = font.render(unicode(j, "utf-8"), 1, textcolor)
			text = font.render(j.decode("utf-8", "ignore"), 1, textcolor)
			screen.blit(text, (30, 30 + 40 * cptligne))	  
			cptligne += 1
		pygame.display.update()
		f.close()

	#credit des themes 
	if const.GWithCredits :
		pygame.time.wait(5000) 

		const.Gbackground_image, background_rect = Load_image("images", "fond5.png")
		ShowTransitionOfTheme(const.GDureeTransition, "fond5.png")

		#credit images for themes
		if const.GAdmin == 0:
			if consoleadmin == 0:
				#credits de pysycache
				const.AppMove.ReadCreditOfDirectory(const.GRepPysycache)
				const.AppClick.ReadCreditOfDirectory(const.GRepPysycache)
				const.AppButtons.ReadCreditOfDirectory(const.GRepPysycache)
				const.AppDblClick.ReadCreditOfDirectory(const.GRepPysycache)
				const.AppPuzzle.ReadCreditOfDirectory(const.GRepPysycache)
	
				#credits des themes dans le rep des utilisateurs
				if const.GPysyUserMode == 0:
					#mode utilisateur simple
					const.AppMove.ReadCreditOfDirectory(const.GRepPersoUser)
					const.AppClick.ReadCreditOfDirectory(const.GRepPersoUser)
					const.AppButtons.ReadCreditOfDirectory(const.GRepPersoUser)
					const.AppDblClick.ReadCreditOfDirectory(const.GRepPersoUser)
					const.AppPuzzle.ReadCreditOfDirectory(const.GRepPersoUser)
				else:
					#mode multiutilisateurs
					for f in os.listdir( const.GRepUsersPysycache ):
						dirname = os.path.join(const.GRepUsersPysycache, f)
						if (os.path.isdir(dirname)):
							const.AppMove.ReadCreditOfDirectory(dirname)
							const.AppClick.ReadCreditOfDirectory(dirname)
							const.AppButtons.ReadCreditOfDirectory(dirname)
							const.AppDblClick.ReadCreditOfDirectory(dirname)
							const.AppPuzzle.ReadCreditOfDirectory(dirname)
