# Path: core/config.py
# def get_sprite(frame):
# def load_image(name):
# def load_sound(name):
# def load_text(name, lang):
# def loop_sound(sound):
# def on_off(condition):
# def percent_str(var):
# def play_music(name):
# def set_volume():
# def init_music_volume():
# def show_fps():
# def take_screenshot():
# def toggle_frame_limit():
# def toggle_fullscreen():
# def toggle_pause():
#     def __init__(self, *keys):
# APP_DATA_WIN = 'APPDATA'
# APP_DATA_LIN = 'HOME'
# BLIT_FLAGS    = HWSURFACE | HWACCEL | ASYNCBLIT | RLEACCEL
# CURSOR_BEEP   = load_sound('cursor.wav')
# CURSOR_SELECT = load_sound('select.wav')
# DATA_STORE    = join(environ[APP_DATA_WIN if 'win' in sys.platform else APP_DATA_LIN], 'Invasodado')
# DEBUG         =  __debug__ and not hasattr(sys, 'frozen') #cx_freeze adds 'frozen' to the sys module
# DEPTH         = 8
# EARTH         = load_image('earth.png')
# ENCODING      = 'utf-8'
# EVENTS_OK     = (KEYDOWN, MOUSEBUTTONDOWN, QUIT)
# FONT          = pygame.font.Font(join('gfx', 'font.ttf'), 18)
# FULL_FLAGS    = FULLSCREEN | HWSURFACE | DOUBLEBUF
# GRID_BG       = load_image('bg.png')
# ON_OFF        = {
#                  'en' : ("Off", "On"),
#                  'es' : ("No" , "Sí"),
#                 }
# PAUSE         = load_sound('pause.wav')
# SCREEN_DIMS   = tuple(pygame.display.list_modes())
# SCREEN_HEIGHT = screen.get_height()
# SCREEN_RECT   = Rect((0, 0), screen.get_size())
# SCREEN_WIDTH  = screen.get_width()
# SPRITES       = load_image('sprites.png')
# EARTH = EARTH.subsurface(Rect(0, 0, EARTH.get_width(), EARTH.get_height() / 2))
# class Enum:
# 
# Path: core/color.py
# RED    = Color('#FF3333')
# GREEN  = Color('#4FFF55')
# BLUE   = Color('#585EFF')
# YELLOW = Color('#EBFF55')
# PURPLE = Color('#FF55D5')
# WHITE  = Color('#FFFFFF')
# BLACK  = Color('#000000')
# COLOR_BLIND_FRAMES  = tuple(Rect(32 * i, 32, 32, 32) for i in range(4, 10))
# COLOR_BLIND_SYMBOLS = {
#                         id(RED)    : config.get_sprite(COLOR_BLIND_FRAMES[0]),
#                         id(BLUE)   : config.get_sprite(COLOR_BLIND_FRAMES[1]),
#                         id(GREEN)  : config.get_sprite(COLOR_BLIND_FRAMES[2]),
#                         id(YELLOW) : config.get_sprite(COLOR_BLIND_FRAMES[3]),
#                         id(PURPLE) : config.get_sprite(COLOR_BLIND_FRAMES[4]),
#                         id(WHITE)  : None                                    ,
#                        }
# COLOR_KEY           = config.SPRITES.get_at((0, config.SPRITES.get_height() - 1))
# LIST                = (RED, BLUE, GREEN, YELLOW, PURPLE)
# def blend_color(surface, color):
# def get_colored_objects(frames, has_alpha=True, color_blind=False, pause_frame=True):
# def _rand_color_appear(self):
# 
# Path: game/gameobject.py
# class GameObject(Sprite, object):
#     '''
#     @invariant: self.state in self.__class__.STATES
#     @
#     '''
#     actions    = None
#     collisions = None
#     group      = None
# 
#     def __init__(self):
#         Sprite.__init__(self)
#         self.acceleration = [0.0, 0.0]
#         self.next_state   = None
#         self.position     = [-300.0, -300.0]
#         self.rect         = None
#         self.state        = None
#         self.velocity     = [0.0, 0.0]
# 
#     def on_collide(self, other):
#         '''
#         Reacts based on the type of the other object.
#         
#         @param other: The object that we collided with.
#         @type other: A subclass of GameObject
#         '''
#         other_type = other.__class__
#         collisions = self.collisions
#         if isinstance(collisions, dict):
#         #If this object can interact with more than one other type...
#             if other_type in collisions and callable(collisions[other_type]):
#             #If we can interact with the other object...
#                 collisions[other_type](self, other)
# 
#     def update(self):
#         '''
#         Acts on this object's current state.
#         '''
#         assert self.state in self.__class__.actions, \
#         "A %s tried to act on an invalid state %s!" % (self, self.state)
# 
#         method_name = self.__class__.actions[self.state]
#         if method_name and callable(getattr(self, method_name)):
#         #If this key has a function for its element...
#             getattr(self, method_name)()
#             
#     def change_state(self, next_state):
#         '''
#         Queues this object for a state change in the next frame.
#         
#         @param next_state: The state to switch to, in type(self).STATES.
#         @type next_state: The values used in config.Enum to represent constants
#         '''
#         self.next_state = next_state
#         _state_changes.add(self)


from pygame import Rect
from core            import config
from core            import color
from game.gameobject import GameObject
'''
Bullet is an abstract class which ShipBullet and EnemyBullet will inherit from.
Bullet should NOT be created in and of itself.
'''



### Constants ##################################################################
BULLET_STATES = ('IDLE', 'FIRED', 'MOVING', 'COLLIDE', 'RESET')
################################################################################

class Bullet(GameObject):
    FRAME  = Rect(227, 6, 26, 19)
    STATES = config.Enum(*BULLET_STATES)
    SPRITE = config.get_sprite(FRAME)

    def __init__(self):
        super().__init__()
        self.image    = self.__class__.SPRITE #@UndefinedVariable
        self.rect     = self.__class__.START_POS.copy()
        self.position = list(self.rect.topleft)
        self.state    = self.__class__.STATES.IDLE


# Path: core/config.py
# def get_sprite(frame):
# def load_image(name):
# def load_sound(name):
# def load_text(name, lang):
# def loop_sound(sound):
# def on_off(condition):
# def percent_str(var):
# def play_music(name):
# def set_volume():
# def init_music_volume():
# def show_fps():
# def take_screenshot():
# def toggle_frame_limit():
# def toggle_fullscreen():
# def toggle_pause():
#     def __init__(self, *keys):
# APP_DATA_WIN = 'APPDATA'
# APP_DATA_LIN = 'HOME'
# BLIT_FLAGS    = HWSURFACE | HWACCEL | ASYNCBLIT | RLEACCEL
# CURSOR_BEEP   = load_sound('cursor.wav')
# CURSOR_SELECT = load_sound('select.wav')
# DATA_STORE    = join(environ[APP_DATA_WIN if 'win' in sys.platform else APP_DATA_LIN], 'Invasodado')
# DEBUG         =  __debug__ and not hasattr(sys, 'frozen') #cx_freeze adds 'frozen' to the sys module
# DEPTH         = 8
# EARTH         = load_image('earth.png')
# ENCODING      = 'utf-8'
# EVENTS_OK     = (KEYDOWN, MOUSEBUTTONDOWN, QUIT)
# FONT          = pygame.font.Font(join('gfx', 'font.ttf'), 18)
# FULL_FLAGS    = FULLSCREEN | HWSURFACE | DOUBLEBUF
# GRID_BG       = load_image('bg.png')
# ON_OFF        = {
#                  'en' : ("Off", "On"),
#                  'es' : ("No" , "Sí"),
#                 }
# PAUSE         = load_sound('pause.wav')
# SCREEN_DIMS   = tuple(pygame.display.list_modes())
# SCREEN_HEIGHT = screen.get_height()
# SCREEN_RECT   = Rect((0, 0), screen.get_size())
# SCREEN_WIDTH  = screen.get_width()
# SPRITES       = load_image('sprites.png')
# EARTH = EARTH.subsurface(Rect(0, 0, EARTH.get_width(), EARTH.get_height() / 2))
# class Enum:
# 
# Path: core/color.py
# RED    = Color('#FF3333')
# GREEN  = Color('#4FFF55')
# BLUE   = Color('#585EFF')
# YELLOW = Color('#EBFF55')
# PURPLE = Color('#FF55D5')
# WHITE  = Color('#FFFFFF')
# BLACK  = Color('#000000')
# COLOR_BLIND_FRAMES  = tuple(Rect(32 * i, 32, 32, 32) for i in range(4, 10))
# COLOR_BLIND_SYMBOLS = {
#                         id(RED)    : config.get_sprite(COLOR_BLIND_FRAMES[0]),
#                         id(BLUE)   : config.get_sprite(COLOR_BLIND_FRAMES[1]),
#                         id(GREEN)  : config.get_sprite(COLOR_BLIND_FRAMES[2]),
#                         id(YELLOW) : config.get_sprite(COLOR_BLIND_FRAMES[3]),
#                         id(PURPLE) : config.get_sprite(COLOR_BLIND_FRAMES[4]),
#                         id(WHITE)  : None                                    ,
#                        }
# COLOR_KEY           = config.SPRITES.get_at((0, config.SPRITES.get_height() - 1))
# LIST                = (RED, BLUE, GREEN, YELLOW, PURPLE)
# def blend_color(surface, color):
# def get_colored_objects(frames, has_alpha=True, color_blind=False, pause_frame=True):
# def _rand_color_appear(self):
# 
# Path: game/gameobject.py
# class GameObject(Sprite, object):
#     '''
#     @invariant: self.state in self.__class__.STATES
#     @
#     '''
#     actions    = None
#     collisions = None
#     group      = None
# 
#     def __init__(self):
#         Sprite.__init__(self)
#         self.acceleration = [0.0, 0.0]
#         self.next_state   = None
#         self.position     = [-300.0, -300.0]
#         self.rect         = None
#         self.state        = None
#         self.velocity     = [0.0, 0.0]
# 
#     def on_collide(self, other):
#         '''
#         Reacts based on the type of the other object.
#         
#         @param other: The object that we collided with.
#         @type other: A subclass of GameObject
#         '''
#         other_type = other.__class__
#         collisions = self.collisions
#         if isinstance(collisions, dict):
#         #If this object can interact with more than one other type...
#             if other_type in collisions and callable(collisions[other_type]):
#             #If we can interact with the other object...
#                 collisions[other_type](self, other)
# 
#     def update(self):
#         '''
#         Acts on this object's current state.
#         '''
#         assert self.state in self.__class__.actions, \
#         "A %s tried to act on an invalid state %s!" % (self, self.state)
# 
#         method_name = self.__class__.actions[self.state]
#         if method_name and callable(getattr(self, method_name)):
#         #If this key has a function for its element...
#             getattr(self, method_name)()
#             
#     def change_state(self, next_state):
#         '''
#         Queues this object for a state change in the next frame.
#         
#         @param next_state: The state to switch to, in type(self).STATES.
#         @type next_state: The values used in config.Enum to represent constants
#         '''
#         self.next_state = next_state
#         _state_changes.add(self)


# Path: game/bullet.py
from pygame import Rect
from core            import config
from core            import color
from game.gameobject import GameObject

'''
Bullet is an abstract class which ShipBullet and EnemyBullet will inherit from.
Bullet should NOT be created in and of itself.
'''



### Constants ##################################################################
BULLET_STATES = ('IDLE', 'FIRED', 'MOVING', 'COLLIDE', 'RESET')
################################################################################

class Bullet(GameObject):
    FRAME  = Rect(227, 6, 26, 19)
    STATES = config.Enum(*BULLET_STATES)
    SPRITE = config.get_sprite(FRAME)

    def __init__(self):
        super().__init__()
        self.image    = self.__class__.SPRITE #@UndefinedVariable
        self.rect     = self.__class__.START_POS.copy()
        self.position = list(self.rect.topleft)
        self.state    = self.__class__.STATES.IDLE


        self.image.set_colorkey(color.COLOR_KEY, config.BLIT_FLAGS)