#!/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 locale
import shutil

import random
import os.path
import pygame
from pygame.locals import *

import datas
from pysyclasses import *
import const
import pysymenu
import pysyihm
import pysypreferences


LG = 140
HT = 46

class PysyUser:
	"""A user """
	name = u''
	withsound = 0
	level = 2
	id = 0
	photo = u''
	colonne = 0
	rangee = 0
	left = 0
	top = 0
	hauteur = 0
	largeur = 0
	selected = 0


#*******************************************************************************
#
#*******************************************************************************
def WriteUserNames(id, username, colonne, rangee):
	#copie du nom de l'utilisateur
	myfont = os.path.join(const.GRepPysycache, 'fonts', const.GFontName).encode(const.GConsoleLocale)
	font = pygame.font.Font(myfont, 20)	
	textcolor = 46, 113, 169
#	text = font.render(unicode(username, const.GConsoleLocale), 1, textcolor).convert_alpha()
#	text = font.render(username.decode(const.GConsoleLocale, "ignore"), 1, textcolor).convert_alpha()
	text = font.render(username, 1, textcolor).convert_alpha()
	(larg, haut) = text.get_size()

	screen = pygame.display.get_surface()

	if larg < LG :
		const.Gbackground_image.blit(text, (LG * (colonne) + const.MARGELEFT + 7 + int((LG - larg) / 2) , 175 * rangee + const.MARGETOP - HT))
		screen.blit(text, (LG * (colonne) + const.MARGELEFT + 7 + int((LG - larg) / 2) , 175 * rangee + const.MARGETOP - HT))
	else:
		#texte trop long : on va le couper
		username = username.split(" ")
		str = ""
		oldstr = ""
		cpt = 0
		for i in range(len(username)):
			str = str + " " + username[i]
#			text = font.render(unicode(str, const.GConsoleLocale), 1, textcolor).convert_alpha()
#			text = font.render(str.decode(const.GConsoleLocale, "ignore"), 1, textcolor).convert_alpha()
			text = font.render(str, 1, textcolor).convert_alpha()
			(larg, haut) = text.get_size()
			if larg < LG :
				oldstr = str
				pass
			else:
#				texttmp = font.render(unicode(oldstr, const.GConsoleLocale), 1, textcolor).convert_alpha()
#				texttmp = font.render(oldstr.decode(const.GConsoleLocale, "ignore"), 1, textcolor).convert_alpha()
				texttmp = font.render(oldstr, 1, textcolor).convert_alpha()
				(larg, haut) = texttmp.get_size()
				const.Gbackground_image.blit(texttmp, (LG * (colonne) + const.MARGELEFT + int((LG - larg) / 2) , 175 * rangee + const.MARGETOP + 22 * cpt - HT))
				screen.blit(texttmp, (LG * (colonne) + const.MARGELEFT + int((LG - larg) / 2) , 175 * rangee + const.MARGETOP + 22 * cpt - HT))
				str = username[i]
				oldstr = str
				cpt += 1
#		texttmp = font.render(unicode(oldstr, const.GConsoleLocale), 1, textcolor).convert_alpha()
#		texttmp = font.render(oldstr.decode(const.GConsoleLocale, "ignore"), 1, textcolor).convert_alpha()

		texttmp = font.render(oldstr, 1, textcolor).convert_alpha()
		(larg, haut) = texttmp.get_size()
		const.Gbackground_image.blit(texttmp, (LG * ( colonne) + const.MARGELEFT + int((LG - larg) / 2) , 175 * rangee + const.MARGETOP + 22 * cpt - HT))
		screen.blit(texttmp, (LG * (colonne) + const.MARGELEFT + int((LG - larg) / 2) , 175 * rangee + const.MARGETOP + 22 * cpt - HT))


#*******************************************************************************
#
#*******************************************************************************
def ShowAllSelection():
	screen = pygame.display.get_surface()
	screen.blit(Background_Restore, (0,0))
	SearchAllUsers()

	const.GLstSouris.empty()
	const.GLstSouris.add(MouseOfActivity(400, 300, "souris.png") )
	for o in const.GLstSouris.sprites():
		o.move(const.Gbackground_image)
	const.GLstSouris.draw(screen)
	pygame.display.update()


#*******************************************************************************
#
#*******************************************************************************
def StartActivity():
	for usr2 in const.GTabUser :
		btn = usr2[1]
		if btn.selected == 1:
			const.GRepPersoUser = os.path.join(const.GRepUsersPysycache, btn.name)

			filenameuser = os.path.join(const.GRepUsersPysycache, btn.name, "pysycacherc")
			const.GPrefUserInit.ReadConfigOfUser(filenameuser)
			pysymenu.ShowWindow(0)

			const.GSelectedUser = 9999999

			#on reaffiche le tout
			ShowAllSelection()

			break



#*******************************************************************************
# Event detection                                                              #
#*******************************************************************************
def DetectEvent():
	""" Traitement des evenements """
	if const.GTypeSouris == const.EVENT_NOVENT:
		return 1

	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.key == K_RETURN:
				if const.GAdmin == 1:
					#mode administration : on ne peut pas faire d'action sur le bouton ENTREE
					pass
				else:
					StartActivity()
				break
			elif event.key == K_RIGHT:
				#page d'apres
				if len(const.GTabUser) - const.GFirsUser > 15:
					screen = pygame.display.get_surface()
					const.GFirsUser = const.GFirsUser + 15
					if const.GFirsUser > len (const.GTabUser) :
						const.GFirsUser = const.GFirsUser - 15
					DrawUsers()
					const.GLstSouris.draw(screen)
					pygame.display.update()
			elif event.key == K_LEFT:
				#page d'avant
				if const.GFirsUser != 0 :
					screen = pygame.display.get_surface()
					const.GFirsUser = const.GFirsUser - 15
					DrawUsers()
					const.GLstSouris.draw(screen)
					pygame.display.update()
		elif event.type == pygame.MOUSEMOTION:
			#*************** evenement deplacement de la souris ***************
			event0 = event.pos[0] 
			event1 = event.pos[1] 
			screen = pygame.display.get_surface()

			#redessin de la souris a sa position actuelle
			const.GMaSourisCurrentPositionX = event0 
			const.GMaSourisCurrentPositionY = event1 
			for o in const.GLstSouris.sprites():
				o.move(const.Gbackground_image)

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

			return 1
		elif event.type == MOUSEBUTTONUP:
			#---------------------- on relache la souris -----------------------
			ok = 0
			event0 = event.pos[0]
			event1 = event.pos[1]
			screen = pygame.display.get_surface()  

			#recherche de l'utilisateur clique
			for obj2 in const.GTabUser :
				obj = obj2[1]
				if ( event0 >= obj.left ) & ( event0 <= obj.left + obj.largeur ) & ( event1 >= obj.top  ) & ( event1 <= obj.top + obj.hauteur ) :
					if (obj.id >= const.GFirsUser) & (obj.id <= const.GFirsUser + 15 - 1):
						#on selectionne un utilisateur
						#on va tout initialiser
						const.GSelectedUser = obj.id
						DrawUsers()
						ok = 1
						break

			ok1 = 0
			#recherche du bouton concerne
			for btn in TabBtnSelect :
				if ( event0 >= btn.left ) & ( event0 <= btn.left + btn.largeur ) & ( event1 >= btn.top  ) & ( event1 <= btn.top + btn.hauteur ) :
					ok1 = 1
					#----------- show the correct window -----------------
					if ( btn.id == 1 ) :
						#add new user
						title =  datas.GetTextInLang("IB0", "Name of the new user")
						valutf, nvrep, returnvalue = pysyihm.ShowInputBox(title)
						if returnvalue == 1:
							olddir = os.getcwdu()
							os.chdir(const.GRepUsersPysycache)
							os.mkdir(valutf)
							os.chdir(olddir)
							screen.blit(const.Gbackground_image, (0, 0))
						const.GFirsUser = 0
						const.GSelectedUser = 9999999
						ShowAllSelection()

						break
					elif ( btn.id == 2) :
						#edit user
						for obj in const.GTabUser :
							obj2 = obj[1]
							if obj2.selected == 1:
								const.GRepPersoUser = os.path.join(const.GRepUsersPysycache, obj2.name)
								filenameuser = os.path.join(const.GRepUsersPysycache, obj2.name, "pysycacherc")
								const.GPrefUserInit.ReadConfigOfUser(filenameuser)

								#on reaffiche le tout
								pysypreferences.ShowWindow(0, obj2.name)
								const.GSelectedUser = 9999999
								const.GFirsUser = 0
								ShowAllSelection()
					elif ( btn.id == 3) :
						#delete user
						for obj in const.GTabUser :
							obj2 = obj[1]
							if obj2.selected == 1:
								title =  datas.GetTextInLang("IB3", "Confirmation")
								returnvalue = pysyihm.ShowMessageBox(title, 2)
								if returnvalue == 1:
									mypath = os.path.join(const.GRepUsersPysycache, obj2.name)
									shutil.rmtree(mypath)
								#on reaffiche le tout
								const.GSelectedUser = 9999999
								const.GFirsUser = 0
								ShowAllSelection()
					elif ( btn.id == 4) :
						#Quitter
						return 0
					elif ( btn.id == 6) :
						#page d'avant
						if const.GFirsUser != 0 :
							const.GFirsUser = const.GFirsUser - 15
						DrawUsers()
					elif ( btn.id == 7) :
						#page d'apres
						const.GFirsUser = const.GFirsUser + 15
						if const.GFirsUser > len (const.GTabUser) :
							const.GFirsUser = const.GFirsUser - 15
						DrawUsers()
					elif ( btn.id == 10) :
						#start the activities
						ok1 = 0
						StartActivity()
					break

			if (ok + ok1) > 0:
				const.GLstSouris.draw(screen)
				pygame.display.update()

	return 1


#*******************************************************************************
#
#*******************************************************************************
def DrawUsers(WithSound = True):
	screen = pygame.display.get_surface()
	const.Gbackground_image.blit(Background_Restore, (0,0))
	screen.blit(Background_Restore, (0,0))

	#tri des utilisateurs
	const.GTabUser.sort()
	i = 0
	for usr2 in const.GTabUser:
		usr = usr2[1]
		usr.id = i
		i += 1

	#redessin des utilisateurs
	col = 0
	rng = 1
	cpt = 0
	for usr2 in const.GTabUser:
		usr = usr2[1]

		if (usr.id >= const.GFirsUser) & (usr.id <= const.GFirsUser + 15 - 1) :
			usr.colonne = col
			usr.rangee = rng

			#copie de la photo
			if const.GSelectedUser == usr.id :
				imgtmp, rect = datas.Load_image("images", "img-user1.png")
				usr.selected = 1
			else:
				imgtmp, rect = datas.Load_image("images", "img-user0.png")
				usr.selected = 0

			filephoto = os.path.join(const.GRepPysycache, "images", "faces", usr.photo).encode(const.GConsoleLocale)
			if os.path.isfile(filephoto):
				photouser = pygame.image.load(filephoto).convert_alpha()
				imgtmp.blit(photouser, (17, 17)	)		

			theleft = LG * (col) + const.MARGELEFT + 7		#7 = (140 - 126) / 2 
			usr.left = theleft
			thetop = 4 + 175 * (usr.rangee - 1) + const.MARGETOP	#170 = 525 / 3
			usr.top = thetop
			const.Gbackground_image.blit(imgtmp, (theleft, thetop))
			(usr.largeur, usr.hauteur) = imgtmp.get_size()
			screen.blit(imgtmp, (theleft, thetop))

			#ecriture du nom de l'utilisateur
			WriteUserNames(usr.id, usr.name, col, rng)
			cpt += 1
			col += 1
			if cpt == 5:
				cpt = 0
				rng += 1
				col = 0

	#mise a jour des boutons
	for btn in TabBtnSelect:
		if btn.id == 6 :
			#c'est le bouton d'avant
			if const.GFirsUser == 0 :
				btn.LoadNormalPicture(Background_Restore)
				btn.LoadSecondPicture(Background_Restore, 'btnmenu.wav', WithSound)
			else:
				btn.LoadNormalPicture(Background_Restore)
		elif btn.id == 7:
			#c'est le bouton d'apres
			if len(const.GTabUser) - const.GFirsUser <= 15:
				btn.LoadNormalPicture(Background_Restore)
				btn.LoadSecondPicture(Background_Restore, 'btnmenu.wav', WithSound)
			else:
				btn.LoadNormalPicture(Background_Restore)
		else:
			btn.LoadNormalPicture(Background_Restore)

	pygame.display.update()


#*******************************************************************************
#
#*******************************************************************************
def SearchAllUsers(WithSound = True):
	""" Search all users (in unicode format) managed by Pysycache """
	const.GTabUser[:] = []

	i = 0
	datas.DebugMessage("")
	datas.DebugMessage("Search all users managed by PySyCache in %s " % const.GRepUsersPysycache )

	if os.path.isdir(const.GRepUsersPysycache) == True:
		for f in os.listdir(const.GRepUsersPysycache):
			if (os.path.isdir(os.path.join(const.GRepUsersPysycache, f))):
				datas.DebugMessage("...found %s " % f )

				usr = PysyUser()
				usr.photo = ""
				#lecture du fichier de configuration pour avoir l'image associee a l'utilisateur
				filename = os.path.join(const.GRepUsersPysycache, f, "pysycacherc")
				datas.DebugMessage("Reading of the config file %s " % filename )

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

						if len(lig) == 0:
							continue

						if string.upper(lig[0]) == 'LOGO' :
							#logo
							usr.photo = lig[1]
							datas.DebugMessage("...Picture name %s " % usr.photo)
							break
					myfile.close()

				usr.name = f
				usr.withsound = 0
				usr.level = 2
				usr.id = i
				const.GTabUser.append((f, usr))

				i += 1

		DrawUsers(WithSound)
	else:
		datas.DebugMessage("")
		datas.DebugMessage("The directory of users (%s) doesn't exist..." % const.GRepUsersPysycache )

	const.GSelectedUser = 9999999


#*******************************************************************************
# Main of the program 
# parameters    typfull = 0 : in window
#                       = 1 : fullscreen
#*******************************************************************************
def ShowWindow(typfull, foradmin):
	global TabBtnSelect 			#tableau des boutons de l'application
	TabBtnSelect = []
	TabBtnSelect[:]= []
	global Background_Restore

	datas.DebugMessage("")
	datas.DebugMessage("**************** Selection of user *******************")

	#-------------------------- image vide de fond -----------------------------
	if foradmin == 0:
		#-------------------------  Initialise son ---------------------------------
		if const.GWithSound == 1:
			try:
				pygame.mixer.pre_init(44100, -16, 2, 2048)
			except  Exception, err:
				const.GWithSound = 0
				const.GSoundError = 1
				print ""
				print ""
				print "*************************************************************"
				print "*"
				print '*           Error in sound initialization : ', err
				print "*"
				print "*************************************************************"

		(nbtry, nbfail) = pygame.init()
		if nbfail != 0:
			const.GWithSound = 0
			const.GSoundError = 1
			datas.DebugMessage("Some errors occurs in pygame.init() : all sounds will be desactivated ")

		#whe hide the mouse for all the game
		pygame.mouse.set_visible(const.CACHE)

		if typfull == 0:
			#mode fenetre
			screen = pygame.display.set_mode((800, 600))
			imgicone, img_rect = datas.Load_image("images", "pysycache-32x32.png")
			pygame.display.set_icon(imgicone)
		else:
			#mode plein ecran
			screen = pygame.display.set_mode((800, 600), FULLSCREEN)

		background_image, background_rect = datas.Load_image("images", "fond1.png")
		screen.blit(background_image, (0,0))
		pygame.display.update()

		#attende de 1/2 seconde
		pygame.time.delay(500)

		#musique de fond
		datas.Load_sound("sounds", "startup.ogg")
	else:
		screen = pygame.display.get_surface()
		background_image, background_rect = datas.Load_image("images", "fond-select.png")
		screen.blit(background_image, (0,0))

	#----------------------- transition vers le menu ---------------------------
	const.Gbackground_image, background_rect = datas.Load_image("images", "fond-select.png")
	datas.ShowTransitionOfTheme(const.GDureeTransition, "fond-select.png", 0)
	Background_Restore, background_rect = datas.Load_image("images", "fond-select.png")

	#----------------------------- liste des utilisateurs ---------------------------
	const.GBtnMenu = 999
	const.GFirsUser = 0
	const.GTabUser[:] = []   	#vider

	const.GBtnMenu = 999

	#----------------------------- liste des boutons ---------------------------
	TabBtnSelect.append(BtnOfMenu("fond-select.png", 4, 'btn-quitter-gd.png', 'btn-quitter.png', 690, 545) )	#quitter
	if os.path.isdir(const.GRepUsersPysycache) == True:
		if foradmin == 1:
			#on rajoute les boutons d'administration des utilisateurs
			TabBtnSelect.append(BtnOfMenu("fond-select.png", 1, 'btn-admin-add.png', 'btn-admin-add.png', 735, 184) )			#menu ajouter utilisateur
			TabBtnSelect.append(BtnOfMenu("fond-select.png", 2, 'btn-admin-edit.png', 'btn-admin-edit.png', 735, 271) )			#menu editer utilisateur
			TabBtnSelect.append(BtnOfMenu("fond-select.png", 3, 'btn-admin-delete.png', 'btn-admin-delete.png', 735, 358) )		#menu supprimer utilisateur
		else:
			TabBtnSelect.append(BtnOfMenu("fond-select.png", 10, 'btn-enter.png', 'btn-enter.png', 276, 550) )					#entrer dans le jeu
		TabBtnSelect.append(BtnOfMenu("fond-select.png", 6, 'btn-prev-gris-gd.png', 'btn-prev-gd.png', 735, 10) )				#avant
		TabBtnSelect.append(BtnOfMenu("fond-select.png", 7, 'btn-next-gris-gd.png', 'btn-next-gd.png', 735, 97) )				#apres

		for btn in TabBtnSelect:
			btn.visible = 1
	else:
		#message d'avertissement
		myfont = os.path.join(const.GRepPysycache, 'fonts', const.GFontName).encode(const.GConsoleLocale)
		font = pygame.font.Font(myfont, 30)
		textcolor = 46, 113, 169
		libel = datas.GetTextInLang("NOUSR1", "The directory of users doesn't exist !")
		text = font.render(libel, 1, textcolor).convert_alpha()
		(larg, haut) = text.get_size()
		const.Gbackground_image.blit(text, ( int((720 - larg) / 2 ) , 100 ))
		libel = datas.GetTextInLang("NOUSR2", "Configure correctly PySyCache")
		text = font.render(libel, 1, textcolor).convert_alpha()
		(larg, haut) = text.get_size()
		const.Gbackground_image.blit(text, ( int((720 - larg) / 2 ) , 200 ))

		#mise a jour des boutons
		for btn in TabBtnSelect:
			if btn.id == 4:
				btn.visible = 1
				btn.LoadNormalPicture(Background_Restore)

	#recherche des utilisateurs (a partir des repertoires)
	SearchAllUsers(False)

	screen.blit(const.Gbackground_image, (0,0))

	#------------------- changer la souris en main -------------------------
	const.GLstSouris.empty()
	const.GLstSouris.add(MouseOfActivity(400, 300, "souris.png") )
	for o in const.GLstSouris.sprites():
		o.move(const.Gbackground_image)
	const.GLstSouris.draw(screen)
	pygame.display.update()
	pygame.event.clear()

	const.GTypeSouris = const.EVENT_JEU0
	const.GWithIMH = 0

	#---------------------- entree dans la boucle principale -------------------
	running = 1
	while running:
		if const.GWithIMH == 0:
			datas.Temporisation()

			#----------------- recherche des evt -------------------------------
			running = DetectEvent()

			datas.ShowFPS()
