import pygame
import threading

#Game objects have positions, update functions, draw functions, collision types etc.
class GameObject():
    def draw(self, window): abstract
    def update(self): abstract
    def collide(self, otherguy) : abstract


class Player(GameObject):
    def __init__(self, x, y):
        #define our startposition
        self.startposition = (x, y)
        self.position = self.startposition
        self.width = 22
        self.height = 22
        self.collisionType = 0
        self.image = pygame.image.load("hero.png")

    def update(self):
        #update our player based on key presses
        global upPressed, downPressed, leftPressed, rightPressed, screenWidth, screenHeight
        (x, y) = self.position
        if upPressed:
            y -= 10
        if downPressed:
            y += 10
        if leftPressed:
            x -= 10
        if rightPressed:
            x += 10
        #make sure we don't leave the screen
        if x < 0:
            x += 10
        if x+self.width > screenWidth:
            x -= 10
        if y < 0:
            y += 10
        if y+self.height > screenHeight:
            y -= 10
            

        self.position = (x, y)

    def draw(self, window):
        #pygame.draw.rect(window, pygame.Color(0, 0, 255), pygame.Rect(self.position[0], self.position[1], self.width, self.height) )
        window.blit(self.image, (self.position[0], self.position[1]) )

    def collide(self, otherguy):
        #if we collide with an enemy, send us back to the start
        if otherguy.collisionType == 1:
            self.position = self.startposition
        
        

#enemy that moves left and right
class HorizontalEnemy(GameObject):

    def __init__(self, x, y, length):
        self.position = (x, y)
        self.width = 40
        self.height = 40
        self.pathlength = length
        self.pathcount = 0
        self.collisionType = 1

    def update(self):
        (x, y) = self.position
        #if we're trying to move to the left
        if self.pathcount < self.pathlength:
            y += 10
            self.pathcount += 1
        elif self.pathcount < 2*self.pathlength:
            y -= 10
            self.pathcount += 1
        else:
            self.pathcount = 0

        self.position = (x, y)

    def draw(self, window):
        pygame.draw.rect(window, pygame.Color(255, 0, 0), pygame.Rect(self.position[0], self.position[1], self.width, self.height) )

    def collide(self, otherguy):
        #Currently, enemies don't worry about collisions, so just screw around here
        print 'I COLLIDED WITH THE PLAYER!'


#Have a seperate listener listening for key presses
class EventListener(threading.Thread):
    def run(self):
        global playing, upPressed, downPressed, leftPressed, rightPressed
        while playing:
            #wait for the next event
            event = pygame.event.wait()
            #if we see the quit event then quit
            if event.type == pygame.QUIT:
                playing = False
            #if we see a key being pressed, update our variables
            if event.type == pygame.KEYDOWN:

                key = event.dict['key']
                if(key == pygame.K_q):
                    playing = False
                    return
                if(key == pygame.K_UP):
                    upPressed = True
                if(key == pygame.K_DOWN):
                    downPressed = True
                if(key == pygame.K_LEFT):
                    leftPressed = True
                if(key == pygame.K_RIGHT):
                    rightPressed = True

            #if we see a key being released, update our variables
            if event.type == pygame.KEYUP:
                key = event.dict['key']
                if(key == pygame.K_UP):
                    upPressed = False
                if(key == pygame.K_DOWN):
                    downPressed = False
                if(key == pygame.K_LEFT):
                    leftPressed = False
                if(key == pygame.K_RIGHT):
                    rightPressed = False



def initializeGame():
    global gameObjects
    gameObjects = []
    #create our game objects from a lvl file
    loadObjectsFromFile('level1.lvl')


def loadObjectsFromFile(filename):
    global gameObjects
    f = open(filename)
    line = f.readline()
    j = 0
    while line != '':
        for i in range(len(line)):
            symbol = line[i]
            if symbol == 'p':
                gameObjects.append(Player(i*20, j*20))
            elif symbol == 'h':
                gameObjects.append(HorizontalEnemy(i*20, j*20, 40))

        j+=1
        line = f.readline()

    f.close()

    
def drawGameObjects():
    global window
    global gameObjects
    #first, clear the screen by filling it with black
    window.fill(pygame.Color(0, 0, 0))
    #now, draw all our game objects
    for guy in gameObjects:
        guy.draw(window)
   
    pygame.display.flip()

def updateGameObjects():
    global gameObjects
    #update all of our game objects
    for guy in gameObjects:
        guy.update()

    #check all of our collisions
    for guy1 in gameObjects:
        for guy2 in gameObjects:
            checkCollision(guy1, guy2)


def checkCollision(guy1, guy2):
    #if our two guys are the same typpe then don't collide 'em
    if guy1.collisionType == guy2.collisionType:
        return False
    else:
        (x1, y1) = guy1.position
        (x2, y2) = guy2.position
        #now check if they're actually touching. This code assumes everyone is a rectangle
        if( x1 < x2+guy2.width and x1+guy1.width > x2 and
            y1 < y2+guy2.height and y1+guy1.height > y2):
            guy1.collide(guy2)
            guy2.collide(guy1)
            return True
        else:
            return False
            


            



    


if __name__ == "__main__":
    
    playing = True
    pygame.init()
    #create a window 500 by 500 pixels
    screenWidth = 500
    screenHeight = 500
    window = pygame.display.set_mode( (screenWidth, screenHeight) )
    clock = pygame.time.Clock()
    #initialize all of our game objects
    initializeGame()
    #our keyboard state
    upPressed = False
    downPressed = False
    leftPressed = False
    rightPressed = False
    EventListener().start()
    

    #Our main game loop
    
    while playing:
        
        updateGameObjects()
        drawGameObjects()
        clock.tick(40)

    print 'Thanks for playing'



        
    
    
