#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
MicroWar 2.0
see exact version with k_VERSION in mwarbasic.py

Handle appliction screens (intro, main menu, game, options, high scores, help...)

Build with :
    Python 2.5.4
    Pygame 1.9.1
    py2app 0.4.2

See Source.rtf for licence and usage
"""
# Import Python Modules
from BeautifulSoup import *
from urllib2 import urlopen
import urllib
    
# Import source
from fgame import *
from mwarbasic import *
from sprites import *

class FInternetScore(object):
    """ score saved and read on internet 
        interact with the MySQL database throught http interface (server side php) using BeautifulSoup and Urllib2 """
    
    def __init__(self):
        self.version=kPrefVersion
        self.highId=[]
        self.highScore=[]
        self.highName=[]
        self.highLevel=[]
        self.highDate=[]
        self.highVersion=[]
        self.highPlatform=[]
        
    def load(self,start=0):
        # read the URL over internet
        url="%s=%d&start=%d&version=%s" % (k_HSCORE_URL,k_HSCORE_LEN,start,k_VERSION)
        try:
            stream=urlopen(url, None)
            if stream:
                html=stream.read()
                stream.close()
                
                # parse URL : find table, extract line by line (tr), then extract cells (td)
                soup=BeautifulSoup(html) 
                table=soup.table
                if table :
                    for tr in table.findAll('tr'):
                        index=0
                        idStr=""
                        playerStr=""
                        scoreStr=""
                        levelStr=""
                        dateStr=""
                        versionStr=""
                        platStr=""
                        for td in tr.findAll('td'):
                            if index==0 and len(td.contents)>0:
                                idStr=td.contents[0]
                            if index==1 and len(td.contents)>0:
                                playerStr=td.contents[0]
                            if index==2 and len(td.contents)>0:
                                scoreStr=td.contents[0]
                            if index==3 and len(td.contents)>0:
                                levelStr=td.contents[0]
                            if index==4 and len(td.contents)>0:
                                dateStr=td.contents[0]
                            if index==5 and len(td.contents)>0:
                                versionStr=td.contents[0]
                            if index==6 and len(td.contents)>0:
                                platStr=td.contents[0]
                            index=index+1
                        id=int(idStr)
                        if id>0:    # store data
                            self.highId.append(id)
                            self.highScore.append(scoreStr)
                            self.highName.append(playerStr)
                            self.highLevel.append(levelStr)
                            self.highDate.append(dateStr)
                            self.highVersion.append(versionStr)
                            self.highPlatform.append(platStr)
        except:
            print "error can't load over internet"
            print sys.exc_info()
        

    def save(self,name,score,level):
        # save the score on URL
        d=datetime.date.today()
        date=d.isoformat()
        url="%s&GAMER_ID=%s&GAMER_SCORE=%s&SCORE_YEAR=%s&SCORE_DATE=%s&GAME_VERSION=%s&PLATFORM=%s" % (k_SENDSCORE_URL,name,score,level,date,k_VERSION,sys.platform)
        
        print "save %s %s (%s)" % (name,score,level)

        try:
            stream=urlopen(url.replace(" ","%20"), None)
            if stream:
                html=stream.read()
                stream.close()
                soup=BeautifulSoup(html)
                body=soup.body
                try:
                    id=int(body.contents[0])
                    print "score saved : %d" % id
                except:
                    print "save score over internet error"
                    print body.contents[0]
                    raise
            else:
                print "bad url when saving score at <%s>" % url
                raise
        except:
            print "error can't save over internet"
            print sys.exc_info()
            id=-1
            
        return id
               
class IntroScreen(FScreen):
    """ intro screen, just a splash screen during loading """
    
    def __init__(self,game,name):
        FScreen.__init__(self,game,name)
        
        img=game.load_image('splash.jpg',path=kBackgroundPath)
        self.set_background(img)
        game.build_splash_labels(True)
        loadingLabel=game.get_widget('loading')
        self.loadingBar=LoadingZone(100.0,game)
        self.loadingBar.set_value(0.0)
        self.chrono=time.time()

        pygame.mouse.set_visible(0)

    def do_one_frame(self,value):
        self.loadingBar.set_value(value)
        t=time.time()
        d=t-self.chrono
        self.chrono=t
        # print "Loading %.0f : %.2f seconds" % (value,d)
        
        FScreen.do_one_frame(self)
                    
class GenericMenuScreen(FScreen):
    """ the ancestor class for all menu """
    
    def __init__(self,game,name,withCredits=False):
        """ init the menu screen : default text, empty button list... """
        FScreen.__init__(self,game,name)
        
        game.build_splash_labels(withCredits)
        game.fps=game.get_widget('fps')

        self.allWidgets=[]            
        self.currentButton=None

        pygame.mouse.set_visible(1)
        
    def update(self):
        """ update the menu screen : change button colors according to the current one """
        FScreen.update(self)
        
        for button in self.allWidgets:
            if button.interactive:
                if self.currentButton==button:
                    button.set_color(kFontMenuOnColor)
                    button.set_background_color(kFontMenuOnBackColor)
                else:
                    button.set_color(kFontMenuOffColor)
                    button.set_background_color(kFontMenuOffBackColor)
                    
    def do_events(self,event):
        """ handle events for the menu screen """
        FScreen.do_events(self,event)
        
        playMoveBeep=False
        playValidBeep=False
        # HandleKey events
        if event.type==KEYDOWN:
            if event.key==K_ESCAPE: # quit the current screen (return to previous one)
                self.game.userChoice="quit"
                playValidBeep=True
                self.game.stop()
            elif event.key==K_DOWN: # down arrow : select next button
                if self.currentButton:
                    if self.currentButton.interactive:
                        index=self.allWidgets.index(self.currentButton)
                        index+=+1
                        if index>=len(self.allWidgets):
                            index=0
                        b=self.allWidgets[index]
                        while not b.interactive:
                            index+=1
                            if index>=len(self.allWidgets):
                                index=0
                            b=self.allWidgets[index]
                        self.currentButton=b
                        playMoveBeep=True
            elif event.key==K_UP:   # up arrow : select prevouis button      
                if self.currentButton:
                    if self.currentButton.interactive:
                        index=self.allWidgets.index(self.currentButton)
                        index-=1
                        if index<0:
                            index=len(self.allWidgets)-1
                        b=self.allWidgets[index]
                        while not b.interactive:
                            index-=1
                            if index<0:
                                index=len(self.allWidgets)-1
                            b=self.allWidgets[index]
                        self.currentButton=b
                        playMoveBeep=True
            elif event.key==K_RIGHT:    # right arrow : increment current option/button
                if self.currentButton:
                    if self.currentButton.type=='numscroller' or self.currentButton.type=='listscroller':
                        self.currentButton.do_increment()
                        playMoveBeep=True
            elif event.key==K_LEFT: # left arrow : decrement current option/button
                if self.currentButton:
                    if self.currentButton.type=='numscroller' or self.currentButton.type=='listscroller':
                        self.currentButton.do_decrement()
                        playMoveBeep=True
            elif event.key==K_RETURN:   # ENTER : active current button
                if self.currentButton:
                    self.game.userChoice=self.currentButton.action
                    playValidBeep=True
                    self.game.stop()
            else:   # any other key : handle the keyin special label, if any
                kList=self.get_objects("keyin")
                if (len(kList)>0):
                    for k in kList:
                        k.key(event.key)
                elif event.key==K_f:    # F : display frame-rate on screen
                    self.game.showFPS=not self.game.showFPS
                    if not self.game.showFPS:
                        self.game.fps.set_text("")
                elif event.key==K_SPACE:    # SPACEBAR
                    if self.currentButton:
                        self.game.userChoice=self.currentButton.action
                        playValidBeep=True
                        self.game.stop()
                else:
                    print "no keyin object to handle this key"
                    
        #mouse handling
        if event.type==MOUSEBUTTONDOWN:
            for button in self.allWidgets:
                if button.interactive:
                    if button.rect.collidepoint(event.pos):
                        button.active = True
                        if self.currentButton!=button:
                            self.currentButton=button
                            playMoveBeep=True
        if event.type==MOUSEBUTTONUP:
            for button in self.allWidgets:
                if button.interactive and button==self.currentButton:
                    button.active=False
                    if button.rect.collidepoint(event.pos):
                        button.clicked = True
                        self.game.userChoice=button.action
                        playValidBeep=True
                        if button.type=="button":
                            self.game.stop()
                        # for scroller, check click position to do the scroll
                        if button.type=='numscroller' or button.type=='listscroller':
                            if event.pos[0]<button.rect.centerx-button.rect.width/6:
                                button.do_decrement()
                            if event.pos[0]>button.rect.centerx+button.rect.width/6:
                                button.do_increment()

        # play interface sounds if necessary
        if playMoveBeep:
            sound=self.game.interfaceSounds[0]
            if sound!=None:
                sound.set_volume(self.game.pref.audioVolume)
                sound.play()
            else:
                print "no sound 'interface0'"

        if playValidBeep:
            sound=self.game.interfaceSounds[1]
            if sound!=None:
                sound.set_volume(self.game.pref.audioVolume)
                sound.play()
            else:
                print "no sound 'interface1'"
                    
class MenuScreen(GenericMenuScreen):
    """ Main menu screen """
    def __init__(self,game,name):
        GenericMenuScreen.__init__(self,game,name,True)
        
        self.set_background(game.screenImages[0])
        game.build_splash_labels(True)

        # create buttons
        playButton=game.get_widget('bplay')
        scoreButton=game.get_widget('bscore')
        helpButton=game.get_widget('bhelp')
        optionButton=game.get_widget('boption')
        quitButton=game.get_widget('bmainquit')

        self.allWidgets=[playButton,scoreButton,helpButton,optionButton,quitButton]            
        self.currentButton=playButton
                    
class FirstScreen(GenericMenuScreen):
    """ first runtime screen (chosse default language) """
    def __init__(self,game,name):
        GenericMenuScreen.__init__(self,game,name,True)
        
        game.build_splash_labels()

        # create buttons to choose the default language
        game.get_widget('choose')
        lang=game.language
        game.language=0
        englishButton=game.get_widget('benglish')
        game.language=1
        frenchButton=game.get_widget('bfrench')
        game.language=2
        germanButton=game.get_widget('bgerman')
        game.language=2
        spanishButton=game.get_widget('bspanish')
        game.language=2
        italianButton=game.get_widget('bitalian')
        game.language=lang

        self.allWidgets=[englishButton,frenchButton,germanButton,spanishButton,italianButton]            
        self.currentButton=englishButton
                    
class AskUpdateScreen(GenericMenuScreen):
    """ update confirmation screen """
    def __init__(self,game,name):
        GenericMenuScreen.__init__(self,game,name,True)
        
        game.build_splash_labels()

        # create buttons
        game.get_widget('askupdate')
        vstr=game.get_widget('strversion')
        vname=game.get_widget('versionname')
        vname.set_text(vstr.get_text(self.game.language) % (game.updateVersion,sys.platform))
        yesButton=game.get_widget('byes')
        noButton=game.get_widget('bno')
        neverButton=game.get_widget('bnever')

        self.allWidgets=[yesButton,noButton,neverButton]            
        self.currentButton=yesButton
                    
class HelpScreen(GenericMenuScreen):
    """ help screen """
    def __init__(self,game,name):
        GenericMenuScreen.__init__(self,game,name)
        
        self.set_background(game.screenImages[1])
        game.build_splash_labels()

        # create buttons

        text=MultiLabel(game,kMenuFontName,kFontTextSize)
        text.set_color(kFontTextColor)
        text.set_background_mode("background")
        text.set_background_color(kBlackColor)
        text.set_position((0,220))
        text.set_margin((5,5))
        txt=game.get_widget('slIntro')
        text.set_text_lines(txt.get_text(self.game.pref.language))
        text.register(self.allSprites,kFrontLayer)

        game.get_widget('help1')
        game.get_widget('help2')
        game.get_widget('help3')
        game.get_widget('help4')
        game.get_widget('help5')
        game.get_widget('help6')
        game.get_widget('help7')
        game.get_widget('help8')
        game.get_widget('help9')
        game.get_widget('help10')
        game.get_widget('help10')
        game.get_widget('help11')
        
        k=FSprite(game)
        k.set_image(game.helpImages[0])
        k.set_pos((104,385))
        k.register(game.get_sprites(), kEffectLayer)
        
        k=FSprite(game)
        k.set_image(game.helpImages[3])
        k.set_pos((104,432))
        k.register(game.get_sprites(), kEffectLayer)
        
        k=FSprite(game)
        k.set_image(game.helpImages[4])
        k.set_pos((104,480))
        k.register(game.get_sprites(), kEffectLayer)
        
        k=FSprite(game)
        k.set_image(game.helpImages[6])
        k.set_pos((104,527))
        k.register(game.get_sprites(), kEffectLayer)
        
        k=FSprite(game)
        k.set_image(game.helpImages[5])
        k.set_pos((104,574))
        k.register(game.get_sprites(), kEffectLayer)
        
        k=FSprite(game)
        k.set_image(game.helpImages[1])
        k.set_pos((530,385))
        k.register(game.get_sprites(), kEffectLayer)
        
        k=FSprite(game)
        k.set_image(game.helpImages[0])
        k.set_pos((530,432))
        k.register(game.get_sprites(), kEffectLayer)
        
        k=FSprite(game)
        k.set_image(game.helpImages[2])
        k.set_pos((530,480))
        k.register(game.get_sprites(), kEffectLayer)
        
        k=FSprite(game)
        k.set_image(game.helpImages[4])
        k.set_pos((530,527))
        k.register(game.get_sprites(), kEffectLayer)
      
        quitButton=game.get_widget('blowquit')

        self.allWidgets=[quitButton]            
        self.currentButton=quitButton
    
class ScoreScreen(GenericMenuScreen):
    """ high score screen """
    def __init__(self,game,name):
        GenericMenuScreen.__init__(self,game,name)
        
        self.set_background(game.screenImages[1])
        game.build_splash_labels()

        # create buttons : the score list
        game.get_widget('scoretitle')
        if self.game.bestScore>0:
            game.get_widget('scorehelp')
        yPos=kMenuButtonYStart
        for p in range(kHighScoreLen):
            if p==game.bestScore: 
                l=KeyIn(game,kMenuFontName,kMenuFontSmallSize)
                l.set_color(kFontAlertColor)
                l.set_keytext(game.scores.highName[p])
                l.set_aftertext(" (%s) : %s" % (game.scores.highLevel[p],game.scores.highScore[p]))
            else:
                l=Label(game,kMenuFontName,kMenuFontSmallSize)
                if game.scores.highID[p]<0:
                    l.set_color(kFontNormalColor)
                else:
                    l.set_color(kFontAlternateColor)
                l.set_text("%s (%s) : %s" % (game.scores.highName[p],game.scores.highLevel[p],game.scores.highScore[p]))
            l.set_position((140,yPos))
            l.register(self.allSprites,kFrontLayer)
            yPos+=kMenuButtonYDeltaSmallest
        
        if game.pref.update:                  
            iScoreButton=game.get_widget('biscore')
        quitButton=game.get_widget('blowquit')

        if game.pref.update:                  
            self.allWidgets=[iScoreButton,quitButton]       
        else:     
            self.allWidgets=[quitButton]       
        self.currentButton=quitButton
        
    def do_events(self,event):
        """ handle keys when there is player name to get (for high score) """
        GenericMenuScreen.do_events(self,event)
        if self.game.bestScore>=0:
            kList=self.get_objects("keyin")
            if kList!=None:
                for k in kList:
                    self.game.scores.highName[self.game.bestScore]=k.get_keytext()
                    self.game.pref.userName=k.get_keytext()
                    
class SharedScoreScreen(GenericMenuScreen):
    """ high score screen """
    def __init__(self,game,name):
        GenericMenuScreen.__init__(self,game,name)
        
        self.set_background(game.screenImages[1])
        game.build_splash_labels()

        # get score from internet    
        self.offset=0
        self.iScore=FInternetScore()
        self.iScore.load(self.offset)
        
        # create buttons : the score list
        game.get_widget('iscoretitle')
        yPos=kMenuButtonYStartUp
        for p in range(len(self.iScore.highName)):
            l=Label(game,kMenuFontName,kMenuFontSmallSize)
            
            if game.scores.search(self.iScore.highId[p]):
                l.set_color(kFontAlternateColor)
            else:
                l.set_color(kFontNormalColor)
            l.set_text("%d. %s [%s] (%s) : %s" % (self.offset+p+1,self.iScore.highName[p],self.iScore.highVersion[p],self.iScore.highLevel[p],self.iScore.highScore[p]))
            l.set_position((140,yPos))
            l.subtype="%d" % p
            l.register(self.allSprites,kFrontLayer)
            yPos+=kMenuButtonYDeltaSmallest
        
        nextButton=game.get_widget('blnext')
        if nextButton!=None:
            nextButton.set_values(0,0,500,k_HSCORE_LEN)
            nextButton.set_value(self.offset)
        scoreButton=game.get_widget('blscore')
        quitButton=game.get_widget('blowquit')

        self.allWidgets=[nextButton,scoreButton,quitButton]            
        self.currentButton=quitButton
        
    def do_events(self,event):
        GenericMenuScreen.do_events(self,event)
        
        old=self.offset
        for button in self.allWidgets:
            if button.action=='next':
                self.offset=button.value
        if self.offset!=old:
            self.iScore.__init__()
            self.iScore.load(self.offset)
            for sprite in self.allSprites:
                if sprite.type=="label":
                    if hasattr(sprite,'subtype'):
                        p=int(sprite.subtype)
                        try:
                            if self.game.scores.search(self.iScore.highId[p]):
                                sprite.set_color(kFontAlternateColor)
                            else:
                                sprite.set_color(kFontNormalColor)
                            txt="%d. %s [%s] (%s) : %s" % (self.offset+p+1,self.iScore.highName[p],self.iScore.highVersion[p],self.iScore.highLevel[p],self.iScore.highScore[p])
                        except:
                            txt=""
                        sprite.set_text(txt)
                
class OptionScreen(GenericMenuScreen):
    """ option screen : preferences """
    def __init__(self,game,name):
        GenericMenuScreen.__init__(self,game,name)
        
        self.set_background(game.screenImages[1])
        game.build_splash_labels()

        # create buttons
        game.get_widget('optionhelp')
        languageScroller=game.get_widget('slanguage')
        if languageScroller!=None:
            languageScroller.set_value(self.game.pref.language)
        interfaceScroller=game.get_widget('sinterface')
        if interfaceScroller!=None:
            str1=self.game.get_widget('strkeyboard')
            str2=self.game.get_widget('strmouse')
            interfaceScroller.set_list([str1.get_text(self.game.pref.language),str2.get_text(self.game.pref.language)])
            interfaceScroller.set_value(self.game.pref.interface)
        videoScroller=game.get_widget('svideo')
        if videoScroller!=None:
            str1=self.game.get_widget('strwindow')
            str2=self.game.get_widget('strfscreen')
            videoScroller.set_list([str1.get_text(self.game.pref.language),str2.get_text(self.game.pref.language)])
            if self.game.pref.fullScreen:
                videoScroller.set_value(1)
            else:
                videoScroller.set_value(0)
        fpsScroller=game.get_widget('sfps')
        if fpsScroller!=None:
            fps=self.game.pref.maxFrameRate
            if fps==0:
                str="-"
            else:
                str="%d" % fps
            try:
                index=fpsScroller.list.index(str)
            except:
                index=0
            fpsScroller.set_value(index)
        soundScroller=game.get_widget('nsound')
        if soundScroller!=None:
            soundScroller.set_values(0.0,100.0*self.game.pref.audioVolume,100.0)
        musicScroller=game.get_widget('nmusic')
        if musicScroller!=None:
            musicScroller.set_values(0.0,100.0*self.game.pref.musicVolume,100.0)
        updateScroller=game.get_widget('supdate')
        if updateScroller!=None:
            str1=self.game.get_widget('strtrue')
            str0=self.game.get_widget('strfalse')
            updateScroller.set_list([str0.get_text(self.game.pref.language),str1.get_text(self.game.pref.language)])
            updateScroller.set_value(self.game.pref.update)
        quitButton=game.get_widget('blowquit')

        self.allWidgets=[languageScroller,interfaceScroller,videoScroller,fpsScroller,soundScroller,musicScroller,updateScroller,quitButton]            
        self.currentButton=quitButton
        
    def do_events(self,event):
        GenericMenuScreen.do_events(self,event)

        for button in self.allWidgets:
            if button.action=='lang':
                self.game.pref.language=button.value
                self.game.language=self.game.pref.language
                button.set_format_from_widget('slanguage')
                for b in self.allWidgets:  # force all button update
                    self.changed=True
                #self.refreshBackground=True
            if button.action=='interface':
                self.game.pref.interface=button.value
                str1=self.game.get_widget('strkeyboard')
                str2=self.game.get_widget('strmouse')
                button.set_list([str1.get_text(self.game.pref.language),str2.get_text(self.game.pref.language)])
                button.set_format_from_widget('sinterface')
                self.refreshBackground=True
            if button.action=='video':
                str1=self.game.get_widget('strwindow')
                str2=self.game.get_widget('strfscreen')
                button.set_list([str1.get_text(self.game.pref.language),str2.get_text(self.game.pref.language)])
                fs=(button.value==1)
                if (fs!=self.game.pref.fullScreen):
                    self.game.display=toggle_fullscreen()
                    self.game.pref.fullScreen=fs
                button.set_format_from_widget('svideo')
                #self.refreshBackground=True
            if button.action=='fps':
                if button.value==0:
                    self.game.pref.maxFrameRate=0
                else:
                    self.game.pref.maxFrameRate=int(button.list[button.value])
                self.game.maxFrameRate=self.game.pref.maxFrameRate
                button.set_format_from_widget('sfps')
            if button.action=='sound':
                self.game.pref.audioVolume=button.value/100
                button.set_format_from_widget('nsound')
            if button.action=='music':
                self.game.pref.musicVolume=button.value/100
                pygame.mixer.music.set_volume(self.game.pref.musicVolume)
                button.set_format_from_widget('nmusic')
            if button.action=='update':
                self.game.pref.update=(button.value==1)
                str1=self.game.get_widget('strtrue')
                str0=self.game.get_widget('strfalse')
                button.set_list([str0.get_text(self.game.pref.language),str1.get_text(self.game.pref.language)])
                button.set_format_from_widget('supdate')
                self.refreshBackground=True
            if button.action=='back':
                button.set_text_from_widget('blowquit')
                    
class PlayScreen(FScreen):
    """ play screen : the game """
    def __init__(self,game,name):
        FScreen.__init__(self,game,name)
        
        #create game groups
        self.shotGroup=pygame.sprite.RenderUpdates()
        self.bombGroup=pygame.sprite.RenderUpdates()
        self.bonusGroup=pygame.sprite.RenderUpdates()
        self.virusGroup=pygame.sprite.RenderUpdates()
        self.shipGroup=ShipGroup(game)
        self.macGroup=pygame.sprite.RenderUpdates()
        self.saucerGroup=SaucerGroup(game)
                
        # Create some sprites            
        game.fps=game.get_widget('fps') # the fps display
        
        self.playerInfo=PlayerInfo(game)    # the player info display

        self.player=Player(game,self.playerInfo)    # the player (mac)
        self.player.set_model(0)
        self.player.set_processor(0)
        self.player.set_system(0)
        self.player.add(self.macGroup)

        self.lifezone=LifeZone(game,self.player)    # player life display
        self.highScore=HighScore(game,kGameFontName,kFontNormalSize)    # highscore display
        self.score=Score(game,self.highScore,kGameFontName,kFontNormalSize) # score display
        self.level=Level(game,kGameFontName,kFontNormalSize)    # level name display

        self.mainLabel=game.get_widget('gamelabel') # info display
        if self.mainLabel!=None:
            self.mainLabel.set_position((0,kSCREEN_HEIGHT/2-kMainInfoOffset))

        self.subLabel=MultiLabel(game,kGameFontName,kFontInfoSize)
        self.subLabel.set_color(kFontLevelColor)
        self.subLabel.set_position((0,kSCREEN_HEIGHT/2+kFontMainSize-kMultiInfoOffset),"center")
        self.subLabel.set_background_mode('background')
        self.subLabel.set_background_color(kBlackColor)
        self.subLabel.register(self.allSprites,kFrontLayer)
        
        self.levelDesc=LevelSprite(game,self.subLabel)

        # init some variables for the play loop
        self.nextLevel=True         # next level sequence (see clock)
        self.nextClock=kNextLevel   # next level clock
        self.introLevel=False       # intro level sequence (after next level) (see clock)
        self.introClock=0           # intro level Clock
        self.gaming=True            # the game is runnning (no pause)
        self.cheat=False            # cheat has been activated
        self.goClock=0              # game over clock
        self.cheatAllowed=False     # cheat not allowed by default

        self.allWidgets=[]          # no widget, no button for the game
        self.currentButton=None

        pygame.mouse.set_visible(0)
        
    def update(self):
        """ update the game """
        FScreen.update(self)
        
        # handle pause : show the corresponding label
        if self.pause:
            self.mainLabel.set_color(kFontLevelColor)
            str=self.game.get_widget('strpause')
            self.mainLabel.set_text(str.get_text(self.game.pref.language))
            
        #Handle quitting game when player dead
        if not self.player.alive():
            if self.goClock==0:
                self.mainLabel.set_color(kFontAlertColor)
                str=self.game.get_widget('strover')
                self.mainLabel.set_text(str.get_text(self.game.pref.language))
                pygame.mixer.fadeout(kGameOver)
                self.gameOver=True
            self.goClock=self.goClock+self.get_clock()
            self.keepGoing=(self.goClock<kGameOver)
            self.game.gameSounds[0].set_volume(self.game.pref.audioVolume)
            self.game.gameSounds[0].play()
            
        #Handle intro and end of levels
        if self.nextLevel:
            if self.nextClock==0:   # begin next level process
                self.nextClock=self.get_clock()
                self.mainLabel.set_color(kFontNormalColor)
                str=self.game.get_widget('strlevelend')
                self.mainLabel.set_text('%s %d' % (str.get_text(self.game.pref.language),self.level.bonus()))
            else:
                self.nextClock+=self.get_clock()
                if self.nextClock>kNextLevel:   # next level when clock done
                    self.level.next_level()
                    r=int(len(self.game.backImages)*random.random()) # choose random background
                    self.set_background(self.game.backImages[r])
                    self.introLevel=True
                    self.nextLevel=False
                    self.nextClock=0

        if self.introLevel: # during game intro sequence
            if self.introClock==0:
                self.introClock=self.get_clock()
                self.mainLabel.set_color(kFontNormalColor)
                str=self.game.get_widget('strlevel')
                self.mainLabel.set_text('%s : %d' % (str.get_text(self.game.pref.language),self.level.get_level()+1984))
                tList=self.level.get_text_list()
                if (len(tList)>0):
                    self.subLabel.set_text_lines(tList)
                    self.subLabel.set_margin((10,10))
                else:
                    self.subLabel.set_text_lines([])
                    self.subLabel.set_margin((0,0))
                self.levelDesc.display(self.level.get_level())
                    
                self.introPause=kIntroPause*len(tList)
                self.introTotal=kIntroLevel+self.introPause
            else: # after game intro sequence
                self.introClock+=self.get_clock()
                if self.introClock>self.introPause and len(self.shipGroup)==0:
                    self.shipGroup.new_wave(self.level,self.game.gameSounds[1])  # new pc wave
                if self.introClock>self.introTotal:
                    self.introLevel=False
                    self.introClock=0
                    self.subLabel.set_text_lines([])
                    self.subLabel.set_margin((0,0))
                    self.levelDesc.display(-1)
                    
        self.gaming=not(self.pause or self.introLevel or self.nextLevel) and self.player.alive()
        if self.gaming:
            self.mainLabel.set_text('')
            
        #update special group
        self.shipGroup.update()
        self.saucerGroup.update()
        
        #Check collision PC ships with the player
        for alien in pygame.sprite.spritecollide(self.player,self.shipGroup,1):
            self.player.hit(alien)

        #Check collision PC ship's bombs with the player
        for bomb in pygame.sprite.spritecollide(self.player,self.bombGroup,1):
            self.player.hit(bomb)

        #Check collision saucer's bonus with the player
        for bonus in pygame.sprite.spritecollide(self.player,self.bonusGroup,1):
            bonus.catch(self.player)

        #Check collision player's shot with any ship
        collide=pygame.sprite.groupcollide(self.shipGroup,self.shotGroup,0,1)   
        for alien in collide.keys():
            alien.hit(collide[alien][0])

        #Check collision virus with any ship
        collide=pygame.sprite.groupcollide(self.shipGroup,self.virusGroup,0,1)   
        for alien in collide.keys():
            alien.hit(collide[alien][0])

        #Check collision player's shot with the saucer
        collide=pygame.sprite.groupcollide(self.saucerGroup,self.shotGroup,0,1)   
        for saucer in collide.keys():
            saucer.hit(collide[saucer][0])       
                    
    def do_events(self,event):
        """ Handle events in game
            player direct keyboard and/or mouse are handled in Player class, for direct input """
            
        FScreen.do_events(self,event)
                
        if event.type==KEYDOWN:
            if event.key==K_c:                          # C : enable cheating key (see below)
                self.cheatAllowed=True
                self.cheat=True
            elif event.key==K_f:    # F : display frame-rate on screen
                self.game.showFPS=not self.game.showFPS
            elif event.key==K_p:
                self.pause=not self.pause
            if self.cheatAllowed:
                if event.key==K_n:    # N : (cheat) next wave (kill all pc)
                    for alien in self.shipGroup:
                        alien.hit(self.player)
                elif event.key==K_k:    # K : cheat fire : accelerate player's shooting rate
                    self.player.cheatFire=1-self.player.cheatFire
                elif event.key==K_l:    # L : cheat life
                    self.player.got_damage(-kRamLife)
                elif event.key==K_g:    # G : cheat : go to 1995
                    for alien in self.shipGroup:
                        alien.hit(self.player)
                    self.level.set_level(11)    # go to 1995
                    self.player.set_processor(4)    # set Mac as PowerMac 7500
                    self.player.set_system(6)   # set Mac with System 7.5
                elif event.key==K_h:    # H : cheat : go to 2006
                    for alien in self.shipGroup:
                        alien.hit(self.player)
                    self.level.set_level(22)    # go to 2006
                    self.player.set_processor(10)    # set Mac as first Intel iMac
                    self.player.set_system(15)   # set Mac with MacOS X 10.4
                elif event.key==K_KP0:    # 0 : bonus Clarus
                    self.player.powerMode=kBonusClarus
                    self.player.powerUp=5
                    self.playerInfo.set_power_up(self.player.powerMode,self.player.powerUp)         
                elif event.key==K_KP1:    # 1 : bonus Newton
                    self.player.powerMode=kBonusNewton
                    self.player.powerUp+=5                   
                    self.playerInfo.set_power_up(self.player.powerMode,self.player.powerUp)         
                elif event.key==K_KP2:    # 2 : bonus iPod
                    self.player.powerMode=kBonusiPod
                    self.player.powerUp=5                   
                    self.playerInfo.set_power_up(self.player.powerMode,self.player.powerUp)         
                elif event.key==K_KP3:    # 3 : bonus iPhone
                    self.player.powerMode=kBonusiPhone
                    self.player.powerUp=5                                    
                    self.playerInfo.set_power_up(self.player.powerMode,self.player.powerUp)         
       
