# -*- coding: utf-8 -*-

# Copyright (c) 2006 Stas Zykiewicz <stas.zytkiewicz@gmail.com>
#
#           packid.py
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public License
# as published by the Free Software Foundation.  A copy of this license should
# be included in the file GPL-2.
#
# 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

RCFILE = 0

import os,random,operator,string,locale,sys
import pygame
from pygame.constants import *
from utils import load_image,load_sound,load_music,MyError,font2surf,MazeGen,\
                trace_error,get_files,read_unicode_file
from CPConstants import DATADIR

#0= wall 1=go
#matrix =   ((0,0,0,0,0),\
#            (0,1,0,1,0),\
#            (0,1,0,1,0),\
#            (0,1,1,1,0),\
#            (0,0,0,0,0))

class Img:
    pass
class Snd:
    pass

class PacKid:
    def __init__(self,matrix,startx,starty,speed=24):
        self.speed = speed
        self.pac_r = Img.pac_r
        self.pac_r_c = Img.pac_r_c
        self.pac_l = Img.pac_l
        self.pac_l_c = Img.pac_l_c
        self.pac_u = Img.pac_u
        self.pac_u_c = Img.pac_u_c
        self.pac_d = Img.pac_d
        self.pac_d_c = Img.pac_d_c
        self.pac_smile = Img.pac_smile
        self.img = self.pac_smile
        
        self.rect = self.img.get_rect()
        self.rect.move_ip(startx,starty)
        
        self.startrect = self.img.get_rect()
        self.startrect.move_ip(startx,starty)
        self.matrix = matrix
        self.row = 1
        self.col = 1
        self.dir_dic = {'UP':self._up,'DOWN':self._down,'LEFT':self._left,'RIGHT':self._right}
                
    def update(self,direc):
        Snd.waka.play()
        apply(self.dir_dic[direc])
        return (self.row,self.col)
        #print self.row,self.col,self.rect
       
    def _up(self):
        if self.img == self.pac_u_c:
            self.img = self.pac_u
        else:
            self.img = self.pac_u_c
        if self.matrix[self.row-1][self.col]: # can we go here?
            self.row -= 1
            self.rect.move_ip(0,-self.speed)
        
    def _down(self):
        if self.img == self.pac_d_c:
            self.img = self.pac_d
        else:
            self.img = self.pac_d_c
        if self.matrix[self.row+1][self.col]: # can we go here?
            self.row += 1
            self.rect.move_ip(0,self.speed)
        
    def _left(self):
        if self.img == self.pac_l_c:
            self.img = self.pac_l
        else:
            self.img = self.pac_l_c
        if self.matrix[self.row][self.col-1]: # can we go here?
            self.col -= 1
            self.rect.move_ip(-self.speed,0)
    
    def _right(self):
        if self.img == self.pac_r_c:
            self.img = self.pac_r
        else:
            self.img = self.pac_r_c
        if self.matrix[self.row][self.col+1]: # can we go here?
            self.col += 1
            self.rect.move_ip(self.speed,0)
    
class Memory:
    def __init__(self,points=('1','2','3','4','5')):
        self.memory = {}
        self.stack = [None]* len(points)
        
    def remember(self,(key,item)):
        #print key,item
        self.memory[key] = item
        self.stack.insert(0,key)
        try:
            del self.memory[self.stack.pop()]
        except KeyError:
            pass
            
    def recall(self,key):
        if self.memory.has_key(key):
            return self.memory[key] 

class Letters(Memory):
    instance = 0
    def __init__(self,char,fcol,dest,ttf):
        Letters.instance += 2
        self.wait = Letters.instance
        Memory.__init__(self)
        #print "char",char
        self.char = char
        self.img,spam = font2surf(char,16,fcol,ttf)
        self.rect = self.img.get_rect()
        self.lifetime = 50 # if we get in a loop
        # calculate the pix pos row*24+60, col*24+150
        self.row = 8
        self.col = 12
        self.rect.move_ip(self.col*24+150,self.row*24+60)
        self.dest = dest
        
        self.old_move = None
        #self.org = (self.row,self.col)
        #self.vector = self.dest[0]-self.org[0],self.dest[1]-self.org[1]
        self.matrix = Img.matrix
        self.speed = 24

    def update(self):
        if self.wait:
            self.wait -= 1
            return 0
        self.lifetime -= 1
        if self.lifetime < 0:
            #print 'died'
            return 1 # he died :-(
        self.org = (self.row,self.col)
        stop = self._iq((self.dest[0]-self.org[0],self.dest[1]-self.org[1]))
        return stop
            
    def _iq(self,vector):
        direcs = self._where_to_go()
        if (self.row,self.col) == (8,12):# still in the box
            direcs = ['u']
        if len(direcs) == 1:
            self._move(direcs[0])
            stop = self.dest == (self.row,self.col)
            return stop
        else:
            try:
                direcs.remove(self.old_move)
            except ValueError:
                pass
        if len(direcs) == 1:
            self._move(direcs[0])
            stop = self.dest == (self.row,self.col)
            return stop
        else:
            prior = [None]*4
            #print vector
            if abs(vector[0]) > abs(vector[1]): # y is pref.
                if vector[0] < 0:
                    prior[0] = 'u'
                    prior[3] = 'd'
                else:
                    prior[0] = 'd'
                    prior[3] = 'u'
                
                if vector[1] < 0:
                    prior[1] = 'l'
                    prior[2] = 'r'
                else:
                    prior[1] = 'r'
                    prior[2] = 'l'
                
            else:
                if vector[1] < 0:
                    prior[0] = 'l'
                    prior[3] = 'r'
                else:
                    prior[0] = 'r'
                    prior[3] = 'l'
                if vector[0] < 0:
                    prior[1] = 'u'
                    prior[2] = 'd'
                else:
                    prior[1] = 'd'
                    prior[2] = 'u'
        
        #print 'direcs',direcs,'prior',prior,'row/col',self.row,self.col
        for d in prior:
            if d in direcs:
                if self.recall((self.row,self.col)) == d:
                    #print self.recall((self.row,self.col))
                    d = random.choice(direcs)
                    self._move(d)
                    break
                else:
                    #print d
                    self.remember(((self.row,self.col),d))
                    self._move(d)
                    break
        stop = self.dest == (self.row,self.col)
        #print 'stop-iq',stop
        return stop
        
    def _where_to_go(self):
        direcs = []
        if self.matrix[self.row-1][self.col]: # up
            direcs.append(('u'))
        if self.matrix[self.row+1][self.col]: # down
            direcs.append(('d'))
        if self.matrix[self.row][self.col-1]: # left
            direcs.append(('l'))
        if self.matrix[self.row][self.col+1]: # right
            direcs.append(('r'))
        return direcs
        
    def _move(self,choice):
        
        if choice == 'u':
            self.row -= 1
            self.rect.move_ip(0,-self.speed)
            self.old_move = 'd'
        elif choice == 'd':
            self.row += 1
            self.rect.move_ip(0,self.speed)
            self.old_move = 'u'
        elif choice == 'l':
            self.col -= 1
            self.rect.move_ip(-self.speed,0)
            self.old_move = 'r'
        elif choice == 'r':
            self.col += 1
            self.rect.move_ip(self.speed,0)
            self.old_move = 'l'
        return        

class Word:
    """  Highlight the letter in the word"""
    def __init__(self,word,ttf,cpg):
        self.chars = word
        self.ttf = ttf
        self.index = -1
        self.fsize = 18
        if cpg.locale_rtl:
            self.fsize = 24
        self.fcol = (255,255,51)
        self.hfcol = (255,0,0)
                        
    def update(self):
        if len(self.chars) > self.index:
            self.index += 1
        else: 
            return self.surf 
        #self.letter_to_speak = self.chars[self.index]
        return self._render(),self.chars[self.index]
    ### BIG TODO: fix the highlighting in RTL words.
    # They are scrambled, the words in the sidepanel are correct but here
    # we highlight it from left to right :-( AND the word itself is reversed. 
    def _render(self):
        #print self.index
        high_letter,size1 = font2surf(self.chars[self.index],self.fsize,self.hfcol,self.ttf,1)
        
        if self.index == 0 or self.index == len(self.chars)-1:
            if self.index == 0:
                split = self.chars[1:]
            else:
                split = self.chars[:-1]
            word,size2 = font2surf(split,self.fsize,self.fcol,self.ttf,1)
            surfsize = (size1[0]+size2[0],size1[1])
            surf = pygame.Surface(surfsize).convert()
            if self.index != 0:# blit first word and then the highlight (last letter)
                surf.blit(word,(0,0))
                surf.blit(high_letter,(size2[0],0))
            else:# first letter is highlight
                surf.blit(high_letter,(0,0))
                surf.blit(word,(size1[0],0))
        else: # word must be split
            word,size1a = font2surf(self.chars[:self.index],self.fsize,self.fcol,self.ttf,1)
            word1,size1b = font2surf(self.chars[self.index+1:],self.fsize,self.fcol,self.ttf,1)
            surfsize = (size1[0]+size1a[0]+size1b[0],size1[1])
            surf = pygame.Surface(surfsize).convert()
            surf.blit(word,(0,0))
            surf.blit(high_letter,(size1a[0],0))
            surf.blit(word1,(size1[0]+size1a[0],0))
        self.surf = surf # see self.update
        return self.surf        

class SidePanel:
    def __init__(self,levels,ttf,cpg):
        self.ttf = ttf
        self.surf = pygame.Surface((130,400)).convert()
        pygame.draw.rect(self.surf,(42,191,44),self.surf.get_rect(),6)
        self.when = 9# number of gooditems to play last level
        self.level_pos_list = [(10,10),(10,110),(10,210),(10,310)]
        self.inlevel_word_pos_list = [(26,10),(26,110),(26,210),(26,310)]
        self.x = 30
        self.y = 6
        self.fsize = 12
        if cpg.locale_rtl:
            self.fsize = 16
        self.fcol = (255,255,51)
        i = 0
        for l in levels[:-1]: # The last level is different
            self._set_level("Level "+str(l+1)+":",self.level_pos_list[i])
            i += 1
        self.lastlevel_y = self.level_pos_list[i]
        self.fcol = (186,184,154)
        self._set_last_level(self.level_pos_list[3])
        self.fcol = (255,255,51)
        #set x and y to the first position
        self.y = self.level_pos_list[0][1]
        self.x = self.level_pos_list[0][0]+16
        
        self.goodimg = pygame.transform.scale(Img.pac_smile,(12,12))
        self.wrongimg = pygame.transform.scale(Img.pac_sad,(12,12))
        self.gooditems = 0
        self.count,self.level = 0,0
               
    def _set_last_level(self,pos):
        self._set_level("Level "+str(4)+":",pos)
    
    def _set_level(self,level,pos):
        levelimg,spam = font2surf(level,self.fsize+2,self.fcol,self.ttf,1)
        self.surf.blit(levelimg,pos)
                               
    def set_word(self,word):
        if self.count == 3:
            self.level += 1
            self.y = self.inlevel_word_pos_list[self.level][1]
            self.count = 0
        self.count += 1
        wordimg,spam = font2surf(word,self.fsize,self.fcol,self.ttf,1)
        self.y += spam[1]
        self.surf.blit(wordimg,(self.x,self.y))
            
    def set_good_wrong(self,gw):
        if gw > 2:
            self.surf.blit(self.wrongimg,(self.x-16,self.y+4))
        else:
            self.surf.blit(self.goodimg,(self.x-16,self.y+4))
            self.gooditems += 1
    
    def get_surf(self):
        return self.surf.convert()
        
    def get_level_score(self):
        #print 'gooditems',self.gooditems
        if self.gooditems >= self.when:
            self.when = 0
            self._set_last_level()
            return 1
        else:
            return 0

class LastLevelImg:
    def __init__(self,music,img,pos):
        self.char = 'FRUIT' # to be compatible with the letters class in the loop
        self.file = os.path.join(Img.libdir,'PackidData',music)
        self.img = load_image(os.path.join(Img.libdir,'PackidData',img),1)
        self.pos = pos
        self.rect = self.img.get_rect()
        # calculate the pix pos row*24+60, col*24+150
        self.row,self.col = pos
        self.rect.move_ip(self.col*24+150,self.row*24+60)
        
    def eat(self):
        load_music(self.file).play()
        return 25 #score

class Game(Img,Snd):    
    """  packid.py - part of childsplay.py, a suite of educational games for
  young children."""

    def __init__(self,screen,backgr,rcdic,basepath,libdir,cpg):
        Img.screen = screen
        Img.libdir = libdir
        self.screen = screen
        self.level = 1
        self.gamelevels = range(4)
        self.gameitems = range(3)
        self.rcdic = rcdic
        self.basedir  = basepath
        self.libdir = libdir
        self.cpg = cpg
        
        self.ttf = os.path.join(DATADIR,'VeraSeBd.ttf')
        self.stop = 0
        self.stopflag = None# used to stop the loop when not level 4
        self.score = 0
        self.letters_spots = []
        self._setup()
        
    def __del__(self):
        #print 'Reached del'
        try:
            Snd.walk.stop()
        except:
            pass
        
    def _setup(self):
        Snd.waka = load_sound(os.path.join(self.libdir,'PackidData','waka.wav'))
        Snd.walk = load_sound(os.path.join(self.libdir,'PackidData','walk.wav'))
        Snd.finlevel = load_sound(os.path.join(self.libdir,'PackidData','finlevel.wav'))
        Snd.bummer = load_sound(os.path.join(DATADIR,'bummer.wav'))
        Snd.eat = load_sound(os.path.join(self.libdir,'PackidData','eat.wav'))
        
        Img.pac_u = load_image(os.path.join(self.libdir,'PackidData','pac_u.png'),1)
        Img.pac_u_c = load_image(os.path.join(self.libdir,'PackidData','pac_u_c.png'),1)
        Img.pac_d = load_image(os.path.join(self.libdir,'PackidData','pac_d.png'),1)
        Img.pac_d_c = load_image(os.path.join(self.libdir,'PackidData','pac_d_c.png'),1)
        Img.pac_l = load_image(os.path.join(self.libdir,'PackidData','pac_l.png'),1)
        Img.pac_l_c = load_image(os.path.join(self.libdir,'PackidData','pac_l_c.png'),1)
        Img.pac_r = load_image(os.path.join(self.libdir,'PackidData','pac_r.png'),1)
        Img.pac_r_c = load_image(os.path.join(self.libdir,'PackidData','pac_r_c.png'),1)
        Img.pac_smile = load_image(os.path.join(self.libdir,'PackidData','pac_smile.png'),0)
        Img.pac_sad = load_image(os.path.join(self.libdir,'PackidData','pac_sad.png'),0)
        
        self.sidepan = SidePanel(self.gamelevels,self.ttf,self.cpg)
        
        # test if we have a words list for the locale
        try:
            #loc = locale.setlocale(locale.LC_ALL,'')
            wordsloc = self.cpg.language
            wordlist = 'words-'+wordsloc
            if not os.path.exists(os.path.join(self.libdir,'PackidData',wordlist)):
                raise IndexError
        except IndexError,info:
            print >> sys.stderr,info,"\n Can't find words for locale",wordsloc,"\n Using english for the words and sounds."
            wordlist = 'words-en'
            wordsloc = 'en'
        if self.cpg.locale_rtl:
            items = read_unicode_file(os.path.join(self.libdir,'PackidData',wordlist))
        else:
            try:
                f = open(os.path.join(self.libdir,'PackidData',wordlist))
                items = f.readlines()
                f.close()
            except IOError,info:
                print 'can\'t open/read words file'
                trace_error()
                MyError.name = 'Module packid.py'
                MyError.line = 'IOError in Game.start, words file'
                raise MyError

        if self.cpg.locale_rtl:
            self.words = filter(None,map(operator.getslice,items,\
                                        (0,)*len(items),(-1,)*len(items)))
        else:
            self.words = map(string.upper,filter(None,map(operator.getslice,items,\
                                        (0,)*len(items),(-1,)*len(items))))
        
        # Look for alphabet sounds for this locale.
        # If all fails we fall back to the "old" wahoo sound.
        alphabetdir = os.path.join(DATADIR,'AlphabetSounds',wordsloc)
        if not os.path.exists(alphabetdir):
            print >> sys.stderr, "Can't find",alphabetdir
            alphabetdir = None
        self.alphabetdir = alphabetdir
        
    def _setup_last_level(self):
        self.fruits,spots = [],[]
        self.letters_spots = []# use this again for the fruits
        music = ['pac1.ogg','pac2.ogg','pac3.ogg','pac4.ogg','pac5.ogg','pac6.ogg']
        random.shuffle(music)
        for file in ('kers.png','banaan.png','aardbei.png','citroen.png','appel.png','peer.png'):
            spot = self._rand_spot()
            if spot in spots or spot in ((1,1),(15,23),(15,24),(16,23),(16,24)):
                spot = self._rand_spot()
            spots.append((spot))
            self.letters_spots.append((spot))
            self.fruits.append((LastLevelImg(music.pop(),file,spot)))
        self.letters_spots.append(((15,23)))
   
    def start(self,level,i):
        """"""
        #print "Begin",self
        pygame.display.update(self.screen.fill((0,0,0)))
        self.level = level
        if level == 0:
            self.brick = load_image(os.path.join(self.libdir,'PackidData','brick.png'),0)
            matrix = self._read_grid('grid0.txt')
            self._build_field(matrix)
                    
        elif level == 1:
            self.brick = load_image(os.path.join(self.libdir,'PackidData','leafs.png'),0)
            matrix = self._read_grid('grid1.txt')
            self._build_field(matrix,1)
        elif level == 2:
            self.brick = load_image(os.path.join(self.libdir,'PackidData','sea.png'),0)
            matrix = self._read_grid('grid2.txt')
            self._build_field(matrix,1)
        elif level == 3 and i < 1:
            if self.sidepan.get_level_score():
                load_music(os.path.join(self.libdir,'PackidData','feelgood.ogg')).play()
                
                self.brick = load_image(os.path.join(self.libdir,'PackidData','camo.png'),0)
                m = MazeGen(17,25)
                matrix = m.get_maze()
                
                #matrix = self._read_grid('grid3.txt')
                self._build_field(matrix)
                self._setup_last_level()
            else:
                self.stopflag = 1# stop loop
                return
        else:
            self.stopflag = 1
            return
                       
        Img.backgr = self.screen.convert()
        Img.backgr_start = self.screen.convert()# keep a begin situation surface
        
        txt = _("Find all the letters in the right order. The word to find is: ")
        # now starts a horrible hack to split the line in two without adjusting the po files
        line1,line2 = txt.split('.')
        # end of horrible hack 
        ### TODO fix RTL issues here
        if level != 3:
            if self.cpg.locale_rtl:
                surf,spam = font2surf(line1,24,(183,255,50),self.ttf,1)
                pygame.display.update(self.screen.blit(surf,(780-spam[0],0)))
                surf,self.surfword_offset = font2surf(line2,24,(183,255,50),self.ttf,1)
                pygame.display.update(self.screen.blit(surf,(780-self.surfword_offset[0],24)))
                word = random.choice(self.words)
            else:
                surf,spam = font2surf(line1,16,(183,255,50),self.ttf,1)
                pygame.display.update(self.screen.blit(surf,(28,4)))
                surf,self.surfword_offset = font2surf(line2,16,(183,255,50),self.ttf,1)
                pygame.display.update(self.screen.blit(surf,(8,30)))
                word = random.choice(self.words)
        
        # start the show and set some initial values
        self.gw = 0 #good/wrong counter
        if level == 3:
            self.letter_objs = []
            for obj in self.fruits:
                pygame.display.update(self.screen.blit(obj.img,obj.rect))
                self.letter_objs.append((obj))
                r = self.screen.blit(self.packid.img,(174,84))# blit packid
                pygame.display.update(r)
                PLAYWALK = 0
        else:
            self._start_letters(word)
            self.sidepan.set_word(word)
            self._update_sidepanel()
            PLAYWALK = 1
            self.surfword = Word(word,self.ttf,self.cpg)
            self._update_surfword()
        x = 174
        y = 84
        self.packid = PacKid(matrix,x,y,24)
        #print self.packid # test
        #print self
        self.pack_pos = (self.packid.row,self.packid.col)# start postion
        if PLAYWALK:
            Snd.walk.play(-1)# stop when the letters are stopped (in def _move_objs)
        
    def _update_surfword(self):
        surf, letter_to_speak = self.surfword.update()
        if self.cpg.locale_rtl:
            # The Hebrew chars are rendered with a lot of empty space
            # So we cut of the top and bottom to get it to blit in a mal space
            cutoff_rect = surf.get_rect().inflate(0,-10)
            pygame.display.update(self.screen.blit(surf,\
                    (780-self.surfword_offset[0]-65,30),cutoff_rect))
        else:
            pygame.display.update(self.screen.blit(surf,\
                        (8+self.surfword_offset[0],30)))
        pygame.time.wait(1000)
        #self._speak_letter(letter_to_speak.lower())
    
    def _speak_letter(self,letter):
        """Not used, maybe removed in the future."""
        return 0
        file = os.path.join(self.libdir,'Speech',letter+'.wav')
        data = load_sound(file)
        data.play()
           
    def _update_sidepanel(self):
        pygame.display.update(self.screen.blit(self.sidepan.get_surf(),(0,60)))
    
    def _read_grid(self,name):
        grid = []
        filename = os.path.join(self.libdir,'PackidData',name)
        f = open(filename,'r')
        for line in f.readlines():
            grid.append((tuple(map(int,line[:-1]))))
        f.close()
        return tuple(grid)
    
    def _build_field(self,matrix,ran=0):
        Img.matrix = matrix #stash ref
        surf = pygame.Surface((620,428))
        y = 10
        for row in matrix:
            x = 10
            for item in row:
                if not item:
                    if ran:
                        brick = self.brick.convert()
                        angle = random.choice((0,90,180,270))
                        surf.blit(pygame.transform.rotate(brick,angle),(x,y))
                    else:
                        surf.blit(self.brick,(x,y))
                elif item == 2:# special
                    i = load_image(os.path.join(self.libdir,'PackidData','exit.png'),0)
                    #image = 48x48
                    #x -= 24
                    #y -= 24
                    surf.blit(i,(x,y))
                    break
                x +=24
            y += 24
        pygame.display.update(self.screen.blit(surf,(140,50)))
        
    def _start_letters(self,word):
        self.word,spots = word,[]
        self.letter_to_find = 0
        self.objs_to_move,self.letter_objs = [],[]# lists to hold Letters objects
        Letters.instance = 0 #reset instance counter
        Img.spots = []# keep track of spots so that we don't put two letters on the same spot
        for item in word:
            spot = self._rand_spot()
            if spot in spots or spot in ((8,11),(8,12),(8,13),(1,1)):# same coords or inside the box,packid
                spot = self._rand_spot()
                Img.spots.append(spot)
            spots.append((spot))
            self.objs_to_move.append((Letters(item,(255,255,255),spot,self.ttf)))
            
            #print item,spot,Img.matrix[spot[0]][spot[1]]

    def _rand_spot(self):
        #return (1,3)
        while 1:
            spot = (random.randrange(1,17),random.randrange(1,24))
            if Img.matrix[spot[0]][spot[1]] and spot not in Img.spots:
                break
        return spot
        
    
    
    def loop(self,events):
        if self.stopflag:
            return 1,0 #no last level, stop play. This is special stop see childsplay.contr
        self.stop = 0
        self.score = 0
        for event in events:
            pos = pygame.Rect(pygame.mouse.get_pos() + (4,4))
            if event.type is KEYDOWN and not self.objs_to_move:
                key = self._on_keypress(event.key)
                if key:
                    r = self.screen.blit(Img.backgr,self.packid.rect.inflate(2,2),self.packid.rect.inflate(2,2))
                    self.pack_pos = self.packid.update(key)
                    rr = self.screen.blit(self.packid.img,self.packid.rect)
                    pygame.display.update((r,rr))
        if self.objs_to_move: # Are there letters to move?
            self._move_objs()
        
        elif self.pack_pos in self.letters_spots: # Have we hit a letter?
            if self.level == 3 and self.pack_pos == (15,23):# pac hit exit in last level
                #self._end_level()
                self.stop = -1
            else:
                for item in self.letter_objs:
                    if self.pack_pos == (item.row,item.col):
                        if item.char == 'FRUIT':
                            self.score = item.eat()
                            self.letter_objs.remove(item)
                            pygame.display.update(self.screen.blit(Img.backgr_start,item.rect,item.rect))# erase fruit
                            self.packid.img = Img.pac_smile
                            pygame.display.update(self.screen.blit(Img.pac_smile,self.packid.rect))
                        else:
                            self._check_letter(item)
                        break
                
        return self.stop,self.score
        
    def _on_keypress(self,key):
        if key == K_UP:
            return 'UP'
        elif key == K_DOWN:
            return 'DOWN'
        elif key == K_LEFT:
            return 'LEFT'
        elif key == K_RIGHT:
            return 'RIGHT'
        
    def _move_objs(self):
        objs_to_remove,dirty_rects = [],[]
        for obj in self.objs_to_move:
            dirty_rects.append((self.screen.blit(Img.backgr,obj.rect.inflate(2,2),obj.rect.inflate(2,2))))
            flag = obj.update()
            if flag:
                rec = obj.rect
                rec.move_ip(4,0)
                Img.backgr.blit(obj.img,rec)
                objs_to_remove.append((obj))
                self.letter_objs.append((obj)) # store letters objs 
                # store the pos of the letter, used to check collide with packid
                # take these positions because a obj maybe died (look in class)
                self.letters_spots.append(((obj.row,obj.col))) 
            dirty_rects.append((self.screen.blit(obj.img,obj.rect)))
        pygame.time.wait(100)
        pygame.display.update(dirty_rects)
        
        if objs_to_remove:
            for item in objs_to_remove:
                self.objs_to_move.remove(item)
                if self.objs_to_move == []:
                    Snd.walk.stop()
                    r= self.screen.blit(self.packid.img,(174,84))# blit packid
                    pygame.display.update(r)
    
    def _check_letter(self,obj):
        if obj.char == self.word[self.letter_to_find]:
            # Good letter
            #print 'letter',obj.char
            self.letter_objs.remove(obj)
            Img.backgr.blit(Img.backgr_start,obj.rect,obj.rect)# erase letter
            self.packid.img = Img.pac_smile
            pygame.display.update(self.screen.blit(Img.pac_smile,self.packid.rect))
            if self.alphabetdir:
                try:
                    char = obj.char.lower()+'.ogg'
                    pygame.time.wait(500)
                    load_music(os.path.join(self.alphabetdir,char)).play()
                except Exception,info:
                    print >> sys.stderr,"error while trying to play alphabet sounds",info
                    Snd.eat.play()
            else:
                Snd.eat.play()
            pygame.time.wait(500)
            
            self.score = 10
            self.letters_spots.remove(self.pack_pos)
            #print self.letters_spots
            if self.letters_spots:
                self.letter_to_find += 1 
            else: # last letter 
                Snd.finlevel.play()
                self.score = 100
                self.stop = -1# level clear
                Img.backgr.blit(Img.backgr_start,obj.rect,obj.rect)# erase letter
                self.sidepan.set_good_wrong(self.gw)
                self._update_sidepanel()               
                pygame.time.wait(2000)
                return
            self._update_surfword()
        else:
            #wrong letter
            if self.packid.img is Img.pac_sad:
                return # still on the wrong letter
            self.gw += 1
            Snd.bummer.play()
            self.packid.img = Img.pac_sad
            pygame.display.update(self.screen.blit(Img.pac_sad,self.packid.rect))
            pygame.time.wait(500)
            
    def __str__(self):
        """Must return the original, not translated, title of this game.
        It's needed by the high score class of childsplay."""        
        return "Packid"
 
 
    def helptitle(self):
        return "Packid"
            
    def help(self):
        
        txt=[_("The aim of the game:"),
        _("Try to 'eat' all the letters in the appropriated order."),
        " ",
        _("Difficulty : 4+ years."),
        " ",
        _("Number of levels : 3"),
        " ",
        _("There are thee levels with three words each."),
        _("When you have finished all the levels, without making to much mistakes"),
        _("(max two per word), you can play the last level which is a maze."),
        _("Try to find the way out while eating the fruits for extra points and"),
        _("funny sounds :-)")]
        
        return txt
