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

#Copyright © 2005 Pol Danilov
###############################################################################
#    This file is part of "SIL".
#
#    A copy of the GNU General Public License should be included with any
#    redistribution of this program in a file named "COPYING".
#
#    "SIL" 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.
#
#    "SIL" 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 "SIL"; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
###############################################################################

def Initialization():
    """
    All the initial SIL loading/pre-caching should be done here.
    """
    
    # load module to pre-compile / speed up the executed code
    try:
        import psyco
        psyco.full()
        print 'psyco initialized'
    except ImportError:
        print 'psyco initialization failed',
        

    captions = ['el silenciador'] # default tilebar caption if data/captions is empty
    caption_file = open('data/captions')
    
    for line in caption_file:
        if line[0] not in ('#','\n'):
            captions.append(line)
    caption_file.close()
    from random import randint
    caption = 'SIL: ' + captions[randint(0,len(captions)-1)]

    global pygame
    import pygame # module needed to control SDL graphics screens
    pygame.init()
    pygame.display.set_caption(caption)    
    pygame.display.set_icon(pygame.image.load('1n7r0/SIL.png')) # Taskbar icon
    pygame.mouse.set_cursor(*pygame.cursors.load_xbm('data/cursor.xbm','data/cursor.xbm.mask'))
    pygame.mouse.set_visible(False)                             # Invisible mouse!

    
    # Display options
    size = width, height = (640, 480)
    flags = pygame.ASYNCBLIT+pygame.RLEACCEL # +pygame.FULLSCREEN # +pygame.HWSURFACE+pygame.DOUBLEBUF
    depth = pygame.display.mode_ok(size, flags)

    # Main Surface
    MainSurface = pygame.display.set_mode(size, flags, depth)

    # Create our Engine object!
    global SIL_Engine
    SIL_Engine = SILEngine('Alpha Version - 0326', MainSurface)

    from os import getcwd
    print SIL_Engine.ver, '(' + getcwd() + ')'

    MARS = pygame.image.load('1n7r0/MARS.png').convert() # Load background
    SIL_Engine.SIL_Surface.blit(MARS, (0,0))
    
    global exit, sys_exit
    from sys import exit
    sys_exit = exit
    def exit():
        """
        Allows exit() to fade out before terminating.
        """
        
        Fade('out')
        pygame.quit()
        # Delete the python compiled bytecode .pyc files
        from os import remove
        try:
            remove('menu.pyc')
            remove('config.pyc')
        except: pass
        sys_exit()
    
    pygame.mixer.music.set_volume(1.00)
    pygame.mixer.music.load('sound/CLOSER2.ogg')

    global config
    from config import config
    try:
        pygame.get_sdl_version()
        pygame.mixer.set_num_channels(len(config.CONTROLLER_LIST)*2) # pygame 1.6 may crash
    except: pass
    global Controller_Buttons
    global CLOCK
    CLOCK = pygame.time.Clock()
    
    Controller_Buttons = list()
    for buttonText,key1,key2 in config.CONTROLLER_LIST:
        Controller_Buttons.append( (buttonText, (76,480), None) )
#        Controller_Buttons.append( (config.KEY_LIST[key1], (302,480), None) )
#        Controller_Buttons.append( (config.KEY_LIST[key2], (423,480), None) )                     
    Controller_Buttons = tuple(Controller_Buttons)
    from menu import InitializeDescriptions
    InitializeDescriptions()

    from menu import credScreen, SILCrd,makeKeyButtons
    credScreen.Menu.add(SILCrd())
    makeKeyButtons()



    
    pygame.time.delay(2000) # temporary delay until initialization takes longer
    
    Fade('in') # Fade in from black

    for x in range(26): # play "A FREE GAME" animation
        if pygame.event.get(pygame.QUIT): exit()
        for event in pygame.event.get(pygame.KEYDOWN):
            if event.key == pygame.K_ESCAPE: return None
        img = pygame.image.load('1n7r0/FRE%02d.png'%x).convert_alpha()
        SIL_Engine.SIL_Surface.blit(MARS, (85,227), pygame.Rect(85,227,130,21))
        SIL_Engine.SIL_Surface.blit(img, (85,227))
        pygame.time.delay(130)
        pygame.display.update(pygame.Rect(85,227,130,21))
        
    for x in range(29): # play "-SIL-" animation
        if pygame.event.get(pygame.QUIT): exit()
        for event in pygame.event.get(pygame.KEYDOWN):
            if event.key in (pygame.K_RETURN, pygame.K_KP_ENTER, pygame.K_ESCAPE): return None
        img = pygame.image.load('1n7r0/SIL%02d.png'%x).convert_alpha()
        SIL_Engine.SIL_Surface.blit(MARS, (83,217), pygame.Rect(83,217,135,41))
        SIL_Engine.SIL_Surface.blit(img, (83,217))
        pygame.time.delay(130)
        pygame.display.update(pygame.Rect(83,217,135,41))


class SILEngine(object):
    """
    Keeps track of various engine variables

    ScreenStack     List that keeps track of which screen to display
    Entities        List of objects that need to be updated?
    UpdateRects     List of pygame.Rect to show which part of screen to update
    ver             Current game version
    SIL_Surface     Current surface to work on
    DisplayScreen   Current screen to display
    
    """

    # Constructor
    def __init__(self, version, surface):
        
        self.ScreenStack = list()
#        self.UpdateRects = list()
        self.ver = version
        self.DisplayScreen = None
        self.SIL_Surface = surface


class SILScreen(object):
    """
    'Keeps track of a particular screen'

    background      Main background that should be displayed
    Menu            SILMnu object to display a menu
    fade_out        Should screen fade out? Boolean
    fade_in         Should screen fade in? Boolean
    title           String, will display the screen Title
    extra           Extra objects to display on the screen
    mouse           Boolean, mouse visible?
    
    """
    # Constructor, sets up all the values, but does not display
    def __init__(self,title,background,screenMenu,fade_out,fade_in,mouse,extras=None):
        global SILTxt
        from menu import SILTxt
        self.background = pygame.image.load(background).convert()
        self.Menu = screenMenu
        self.fade_out = fade_out
        self.fade_in = fade_in
        self.title = SILTxt(title, None, 26, (64,148,84))
        self.title.textPos = ( 320 - self.title.Surface.get_width() / 2, 4 )
        self.extras = extras
        self.mouse = mouse
    
    # Displays the screen to the main surface
    def display(self):
        pygame.mouse.set_visible(self.mouse)
        from menu import SIL_Engine
        if (self.fade_out): Fade('out')
        SIL_Engine.SIL_Surface.blit(self.background, (0,0)) # Background
        self.title.blit()

        self.Menu.draw(SIL_Engine.SIL_Surface)

        # Draw the extras.  If Position is specified as False then
        # the extra is a SILTxt object and already has a position defined
        if (self.extras):
            for (Surface, Position) in self.extras:
                if (Position):
                    SIL_Engine.SIL_Surface.blit(Surface, Position)
                else:
                    SIL_Engine.SIL_Surface.blit(Surface.Surface, Surface.textPos)

        # Fade in? Then flip
        if (self.fade_in): Fade('in')
        else: pygame.display.flip()
    
    
def Fade(InOrOut):
    if InOrOut == 'in': InOrOut = (255,-1,-7) # arguments to range() to create alpha levels
    else: InOrOut = (0,256,7)   # 0, 7, 14, 21, etc...
    try: background = SIL_Engine.SIL_Surface.copy()    # pygame 1.6 doesn't support this
    except: background = pygame.Surface((640,480));background.blit(SIL_Engine.SIL_Surface, (0,0))
    black = pygame.Surface((640,480))  # 640x480 black surface
    for alpha in range(*InOrOut):
        black.set_alpha(alpha)
        SIL_Engine.SIL_Surface.blit(background, (0,0))
        SIL_Engine.SIL_Surface.blit(black, (0,0))
        pygame.display.flip()

def __main__():
    
    Initialization()

    pygame.mixer.music.play(-1)


    from menu import ShowScreen
    ShowScreen('MAIN')   #enter the main menu event loop function
    
    ####
    # The MENU_screen() should exit to here once the
    # game is into the silencer lobby or something
    ####


if __name__ == '__main__': __main__() # Execution starts here...
