# Path: pycho/gui/widgets.py
# class GLPlotWidget(QGLWidget):
# 
#     def __init__(self, width, height, game, *args):
#         QGLWidget.__init__(self, *args)
#         self.width = width
#         self.height = height
#         self.game = game
#         self.last_level = game.world.current_level
#  
#     def initializeGL(self):
#         """Initialize OpenGL, VBOs, upload data on the GPU, etc.
#         """
#         # background color
#         gl.glClearColor(0, 0, 1, 1)
#         gl.glViewport(0, 0, self.width, self.height)
#         gl.glMatrixMode(gl.GL_PROJECTION)
#         gl.glLoadIdentity()
# 
#     def paintGL(self):
#         """Paint the scene.
#         """
#         # clear the buffer
# 
#         if self.last_level != self.game.world.current_level:
#             self.last_level = self.game.world.current_level
#             self.resizeGL(self.width, self.height)
# 
#         r, g, b = self.game.world.floor_color
#         gl.glClearColor(r, g, b, 1)
#         gl.glClear(gl.GL_COLOR_BUFFER_BIT)
# 
#         self.game.world.draw()
#         
#     def resizeGL(self, width, height):
#         """Called upon window resizing: reinitialize the viewport.
#         """
#         # update the window size    
#         self.width, self.height = width, height
#         # paint within the whole window
#         gl.glViewport(0, 0, self.width, self.height)
#         # set orthographic projection (2D only)
#         gl.glMatrixMode(gl.GL_PROJECTION)
#         gl.glLoadIdentity()
#         # the window corner OpenGL coordinates are the same as the world height and width
#         gl.glOrtho(0, self.game.world.width, 0, self.game.world.height, -1, 1)
# 
# Path: pycho/world/navigation.py
# DIRECTIONS = {
#     'still' : 0,
#     'up' : 1,
#     'down' : -1,
#     'right' : 20,
#     'left' : -20,
#     'up-left' : -19,
#     'up-right' : 21,
#     'down-left' : -21,
#     'down-right' : 19
# }
# 
# Path: pycho/gui/interaction.py
# QT_KEYS = {k[4:]: Q.__getattribute__(Q, k) for k in dir(Q) if k.startswith('Key_')}
# 
# def is_left(key, left_keys=LEFT_KEYS):
#     return key in left_keys
# 
# def is_right(key, right_keys=RIGHT_KEYS):
#     return key in right_keys
# 
# def is_up(key, up_keys=UP_KEYS):
#     return key in up_keys
# 
# def is_down(key, down_keys=DOWN_KEYS):
#     return key in down_keys
# 
# Path: pycho/world/helpers.py
# def box_around(x, y, width, height):
# 
#     populated = []
#     populate = lambda i, j : populated.append((i, j, None))
# 
#     for i in range(x - width, x + width):
#         for j in range(y - height, y + height):
#             populate(i, j)
#     return populated


from PyQt5 import QtCore, QtWidgets
from pycho.gui.widgets import GLPlotWidget
from pycho.world.navigation import DIRECTIONS
from pycho.gui.interaction import QT_KEYS, is_left, is_right, is_up, is_down
from pycho.world.helpers import box_around
import logging
        if key_press_handlers is None:
            key_press_handlers = {'*' : key_press_handler}

        if mouse_click_handlers is None:
            mouse_click_handlers = {'*' : mouse_click_handler}

        if mouse_release_handlers is None:
            mouse_release_handlers = {'*' : mouse_release_handler}

        self.key_press_handlers = key_press_handlers
        self.mouse_click_handlers = mouse_click_handlers
        self.mouse_release_handlers = mouse_release_handlers

        self.is_paused = False

    def timerEvent(self, event):
        self.callbacks[event.timerId() - 1]()

    def _defaultKeyPressHandler(self, event):
        key = event.key()

        logging.debug('Key {} was pressed'.format(key))

        if is_left(key):
            face_movement = DIRECTIONS['left']
        elif is_right(key):
            face_movement = DIRECTIONS['right']
        elif is_up(key):
            face_movement = DIRECTIONS['up']
        elif is_down(key):

# Path: pycho/gui/widgets.py
# class GLPlotWidget(QGLWidget):
# 
#     def __init__(self, width, height, game, *args):
#         QGLWidget.__init__(self, *args)
#         self.width = width
#         self.height = height
#         self.game = game
#         self.last_level = game.world.current_level
#  
#     def initializeGL(self):
#         """Initialize OpenGL, VBOs, upload data on the GPU, etc.
#         """
#         # background color
#         gl.glClearColor(0, 0, 1, 1)
#         gl.glViewport(0, 0, self.width, self.height)
#         gl.glMatrixMode(gl.GL_PROJECTION)
#         gl.glLoadIdentity()
# 
#     def paintGL(self):
#         """Paint the scene.
#         """
#         # clear the buffer
# 
#         if self.last_level != self.game.world.current_level:
#             self.last_level = self.game.world.current_level
#             self.resizeGL(self.width, self.height)
# 
#         r, g, b = self.game.world.floor_color
#         gl.glClearColor(r, g, b, 1)
#         gl.glClear(gl.GL_COLOR_BUFFER_BIT)
# 
#         self.game.world.draw()
#         
#     def resizeGL(self, width, height):
#         """Called upon window resizing: reinitialize the viewport.
#         """
#         # update the window size    
#         self.width, self.height = width, height
#         # paint within the whole window
#         gl.glViewport(0, 0, self.width, self.height)
#         # set orthographic projection (2D only)
#         gl.glMatrixMode(gl.GL_PROJECTION)
#         gl.glLoadIdentity()
#         # the window corner OpenGL coordinates are the same as the world height and width
#         gl.glOrtho(0, self.game.world.width, 0, self.game.world.height, -1, 1)
# 
# Path: pycho/world/navigation.py
# DIRECTIONS = {
#     'still' : 0,
#     'up' : 1,
#     'down' : -1,
#     'right' : 20,
#     'left' : -20,
#     'up-left' : -19,
#     'up-right' : 21,
#     'down-left' : -21,
#     'down-right' : 19
# }
# 
# Path: pycho/gui/interaction.py
# QT_KEYS = {k[4:]: Q.__getattribute__(Q, k) for k in dir(Q) if k.startswith('Key_')}
# 
# def is_left(key, left_keys=LEFT_KEYS):
#     return key in left_keys
# 
# def is_right(key, right_keys=RIGHT_KEYS):
#     return key in right_keys
# 
# def is_up(key, up_keys=UP_KEYS):
#     return key in up_keys
# 
# def is_down(key, down_keys=DOWN_KEYS):
#     return key in down_keys
# 
# Path: pycho/world/helpers.py
# def box_around(x, y, width, height):
# 
#     populated = []
#     populate = lambda i, j : populated.append((i, j, None))
# 
#     for i in range(x - width, x + width):
#         for j in range(y - height, y + height):
#             populate(i, j)
#     return populated


# Path: pycho/gui/windows.py
from PyQt5 import QtCore, QtWidgets
from pycho.gui.widgets import GLPlotWidget
from pycho.world.navigation import DIRECTIONS
from pycho.gui.interaction import QT_KEYS, is_left, is_right, is_up, is_down
from pycho.world.helpers import box_around
import logging

        if key_press_handlers is None:
            key_press_handlers = {'*' : key_press_handler}

        if mouse_click_handlers is None:
            mouse_click_handlers = {'*' : mouse_click_handler}

        if mouse_release_handlers is None:
            mouse_release_handlers = {'*' : mouse_release_handler}

        self.key_press_handlers = key_press_handlers
        self.mouse_click_handlers = mouse_click_handlers
        self.mouse_release_handlers = mouse_release_handlers

        self.is_paused = False

    def timerEvent(self, event):
        self.callbacks[event.timerId() - 1]()

    def _defaultKeyPressHandler(self, event):
        key = event.key()

        logging.debug('Key {} was pressed'.format(key))

        if is_left(key):
            face_movement = DIRECTIONS['left']
        elif is_right(key):
            face_movement = DIRECTIONS['right']
        elif is_up(key):
            face_movement = DIRECTIONS['up']
        elif is_down(key):

            face_movement = DIRECTIONS['down']