__author__ = 'Anselmo'

# Background from tiledtmxloader example
# Link sprite from http://rpgmaker.net/games/224/images/666/

from PPlay.window import *
from PPlay.gameimage import *
from PPlay.sound import *
from PPlay.sprite import *
import math
from PPlay.tilemap import *

window = Window(800, 800)

window.set_title("Tile Map Example")
window.set_background_color((0, 0, 255))
window.update()

keyboard = window.get_keyboard()

SLOW_SPEED = 64
NORMAL_SPEED = 128
FAST_SPEED = 256

KEYBOARD_DELAY_TIME = 250

NEXT_ENEMY_SCORE_INC = 1000
TIME_SCORE_INC = 10

HERO_LEFT_BORDER = 64
HERO_RIGHT_BORDER = window.width - 64
HERO_BOTTOM_BORDER = window.height - 180

ANIMATION_DURATION = 2000
AUDIO_FADEOUT = 500
SHOT_DELAY_TIME = 500

ENTRANCE = 0
INITIALIZATION = 1
PLAYING = 2
ENDING = 3

WALKING_RIGHT = 0
WALKING_LEFT = 1
WALKING_UP = 2
WALKING_DOWN = 3
STANDING_LEFT = 4
STANDING_RIGHT = 5
STANDING_UP = 6
STANDING_DOWN = 7
JUMPING = 8

SCROLL_SPEED = 256

score = 0
lives = 3
level = 0
nextEnemyScore = 10000
beginningTime = 0

lastKeyboardInput = window.delta_time()

gameLoopState = ENTRANCE


def setAnimationSequenceHero(hero, sequence):
    hero['previousSequence'] = hero['sequence']
    hero['sequence'] = sequence
    if (sequence == WALKING_RIGHT):
        hero['sprite'].set_sequence(8, 12);
        hero['speedx'] = NORMAL_SPEED
        hero['speedy'] = 0
    elif (sequence == WALKING_LEFT):
        hero['sprite'].set_sequence(4, 8);
        hero['speedx'] = -NORMAL_SPEED
        hero['speedy'] = 0
    elif (sequence == WALKING_UP):
        hero['sprite'].set_sequence(12, 16);
        hero['speedx'] = 0
        hero['speedy'] = -NORMAL_SPEED
    elif (sequence == WALKING_DOWN):
        hero['sprite'].set_sequence(0, 4);
        hero['speedx'] = 0
        hero['speedy'] = NORMAL_SPEED
    elif (sequence == STANDING_RIGHT):
        hero['sprite'].set_sequence(8, 9);
        hero['speedx'] = 0
        hero['speedy'] = 0
    elif (sequence == STANDING_LEFT):
        hero['sprite'].set_sequence(4, 5);
        hero['speedx'] = 0
        hero['speedx'] = 0
    elif (sequence == STANDING_UP):
        hero['sprite'].set_sequence(12, 13);
        hero['speedx'] = 0
        hero['speedy'] = 0
    elif (sequence == STANDING_DOWN):
        hero['sprite'].set_sequence(0, 1);
        hero['speedx'] = 0
        hero['speedy'] = 0


def updateHeroPosition(hero, tileMap):
    dt = window.delta_time()
    vx = hero['speedx']
    vy = hero['speedy']

    dx = vx * dt
    dy = vy * dt

    ndx, ndy, collidedTilesId = tileMap.check_collision(hero['sprite'], hero['posx']+hero['sprite'].width//2,\
                                       hero['posy']+hero['sprite'].height//2, dx, dy, tileMap.sprite_layers[3], 1)
    hero['posx'] += ndx
    hero['posy'] += ndy

    for id in collidedTilesId:
        print(id)
    return ndx, ndy


def keyBoardInput(hero, tileMap):
    global lastKeyboardInput
    currentTick = window.last_time

    if (keyboard.key_pressed("ESC")):
        window.close()
    elif (keyboard.key_pressed("LEFT")):
        if hero['sequence'] != WALKING_LEFT:
            setAnimationSequenceHero(hero, WALKING_LEFT)
    elif (keyboard.key_pressed("RIGHT")):
        if hero['sequence'] != WALKING_RIGHT:
            setAnimationSequenceHero(hero, WALKING_RIGHT)
    elif (keyboard.key_pressed("UP")):
        if hero['sequence'] != WALKING_UP:
            setAnimationSequenceHero(hero, WALKING_UP)
    elif (keyboard.key_pressed("DOWN")):
        if hero['sequence'] != WALKING_DOWN:
            setAnimationSequenceHero(hero, WALKING_DOWN)
    elif (keyboard.key_pressed("1")):
        if (currentTick - lastKeyboardInput > KEYBOARD_DELAY_TIME):
            lastKeyboardInput = currentTick
            tileMap.toggleLayerVisibility(1);
    elif (keyboard.key_pressed("2")):
        if (currentTick - lastKeyboardInput > KEYBOARD_DELAY_TIME):
            lastKeyboardInput = currentTick
            tileMap.toggleLayerVisibility(2);
    elif (keyboard.key_pressed("3")):
        if (currentTick - lastKeyboardInput > KEYBOARD_DELAY_TIME):
            lastKeyboardInput = currentTick
            tileMap.toggleLayerVisibility(3);
    else:
        if hero['sequence'] == WALKING_LEFT:
            setAnimationSequenceHero(hero, STANDING_LEFT)
        elif hero['sequence'] == WALKING_RIGHT:
            setAnimationSequenceHero(hero, STANDING_RIGHT)
        elif hero['sequence'] == WALKING_UP:
            setAnimationSequenceHero(hero, STANDING_UP)
        elif hero['sequence'] == WALKING_DOWN:
            setAnimationSequenceHero(hero, STANDING_DOWN)


def entrance(gameLoopState):
    window.set_background_color((0, 0, 255))
    window.draw_text("Press SPACE to start", 230, 230, 40, (255, 255, 0), "Arial", True, True)
    window.draw_text("LabGames 2014-2", 260, 300, 40, (255, 255, 0), "Helvetic", True, True)

    if (keyboard.key_pressed("SPACE")):
        gameLoopState = INITIALIZATION

    return gameLoopState


def initialization(gameLoopState):
    gameState = dict(score=0, lives=3, level=0, time=20000, beginningTime=window.last_time, heroDiedTime=0,
                     heroDied=False, nextEnemyScore=10000)

    tileMap = TileMap("001-1.tmx", window)
    tileMap.setCameraPosition(window.width, window.height)

    linkSprite = Sprite("linkhor.png", 16)
    hero = dict(sprite=linkSprite,\
                posx = 1.5 * window.width , \
                posy = 1.5 * window.height ,\
                speedx=0, speedy=0, \
                firstTimeSpawn=True, \
                sequence=STANDING_LEFT, \
                previousSequence=STANDING_LEFT)

    hero['sprite'].set_position(hero['posx'] - tileMap.cam_world_pos_x, \
                                hero['posy'] - tileMap.cam_world_pos_y)
    hero['sprite'].set_total_duration(ANIMATION_DURATION)

    setAnimationSequenceHero(hero, hero['sequence'])

    gameLoopState = PLAYING

    return gameLoopState, gameState, hero, tileMap


# ###################################################################################################



def gameStage(gameLoopState, gameState, hero, tileMap):
    keyBoardInput(hero, tileMap)
    window.set_background_color((0, 0, 0))

    dx, dy = updateHeroPosition(hero, tileMap)

    tileMap.setCameraPosition(tileMap.cam_world_pos_x + dx, tileMap.cam_world_pos_y + dy)

    tileMap.renderLayer(tileMap.sprite_layers[0], window)
    hero['sprite'].update()
    hero['sprite'].draw()
    tileMap.renderLayer(tileMap.sprite_layers[1], window)
    tileMap.renderLayer(tileMap.sprite_layers[2], window)
    tileMap.renderLayer(tileMap.sprite_layers[3], window)

    # sprite_rect = pygame.Rect(0, 0, hero['sprite'].width, hero['sprite'].height)
    # sprite_rect.center = (hero['posx'] - tileMap.cam_world_pos_x + hero['sprite'].width//2,\
    #                       hero['posy'] - tileMap.cam_world_pos_y + hero['sprite'].height//2)
    #
    # pygame.draw.circle(Window.screen, (255, 0, 0),
    #                    (int(hero['posx'] - tileMap.cam_world_pos_x + hero['sprite'].width//2 ),\
    #                     int(hero['posy'] - tileMap.cam_world_pos_y + hero['sprite'].height//2)), 2, 1)
    # pygame.draw.rect(Window.screen, (255, 0, 0), sprite_rect, 1)

    window.draw_text("Score: " + str(int(gameState['score'])), 5, 5, 30, (255, 255, 255), "Arial", True, False)
    window.draw_text("Time: " + str(int(gameState['time'])), 300, 5, 30, (255, 255, 255), "Arial", True, False)
    window.draw_text("Lives: " + str(int(gameState['lives'])), 670, 5, 30, (255, 255, 255), "Arial", True, False)

    return gameLoopState, gameState, hero, tileMap


####################################################################################################

def ending(gameLoopState, gameState):
    window.draw_text("Your score was: " + str(int(gameState['score'])), 280, 230, 32, (255, 255, 0), "Arial", True,
                     False)
    window.draw_text("Continue(Y/N)", 330, 300, 32, (255, 255, 0), "Arial", True, False)

    if keyboard.key_pressed("y"):
        gameLoopState = ENTRANCE
    elif keyboard.key_pressed("n"):
        window.close()
    return gameLoopState


gameLoopState = ENTRANCE

while True:
    if (gameLoopState == ENTRANCE):
        gameLoopState = entrance(gameLoopState)
    elif (gameLoopState == INITIALIZATION):
        gameLoopState, gameState, hero, tileMap = initialization(gameLoopState)
    elif (gameLoopState == PLAYING):
        gameLoopState, gameState, hero, tileMap = gameStage(gameLoopState, gameState, hero, tileMap)
    else:
        gameLoopState = ending(gameLoopState, gameState)
    window.update()

