# -*- coding: utf-8 -*-
from __future__ import division, print_function

import logging

import pygame

from game import features
from game.intro import Intro
from game.level import Level
from game.levelloader import LevelLoader

logger = logging.getLogger(__name__)


class Game:
    running = True

    def __init__(self):
        self.level_loader = LevelLoader()

    def run(self, screen):

        images = [pygame.image.load(p) for p in [
            "game/data/images/01calender.png",
            "game/data/images/02city.png",
            "game/data/images/03incity.png",
            "game/data/images/04wait.png",
            "game/data/images/05elevator.png",
            "game/data/images/06up.png",
            "game/data/images/07boom.png",
        ]]
        music_path = "game/data/music/Motivational-Ambient-by-Alex-Productions-No-Copyright-Music-_-ALONE-_(chosic.com).ogg"
        Intro().run(images, music_path)

        level = self.load_map()
        level.initialize()

        clock = pygame.time.Clock()
        ups_clock = pygame.time.Clock()
        accumulator = 0
        up_dt = 1 / 120  # 120 ups

        fps_clock = pygame.time.Clock()
        draw_countdown = 0
        draw_dt = 1 / 60  # 60 fps

        debug_print_countdown = 0

        while self.running:
            if level.done:
                self.running = False
            dt = clock.tick() / 1000.0
            dt = dt if dt < 0.1 else 0.1  # restrict to max 100 ms

            accumulator += dt
            while accumulator > up_dt:
                ups_clock.tick()
                self.handle_events()
                self.update(level, 0 if features.time_freeze else up_dt)
                accumulator -= up_dt

            draw_countdown -= dt
            if draw_countdown <= 0:
                fdt = fps_clock.tick() / 1000.0
                self.draw(screen, level, fdt)
                draw_countdown += draw_dt

            if features.debug_print_fps:
                debug_print_countdown -= dt
                if debug_print_countdown < 0:
                    debug_print_countdown += 1  # every second
                    logger.warning("ups: %s  fps: %s  clock: %s", ups_clock.get_fps(), fps_clock.get_fps(),
                                   clock.get_fps())

        images = [pygame.image.load(p) for p in [
            "game/data/images/20uptown.png",
            "game/data/images/21fin.png",
        ]]

        Intro().run(images, music_path)

    def draw(self, screen, level: Level, fdt):
        level.draw(screen, fdt)

    def handle_events(self):
        # events
        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                self.running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.running = False
                elif event.key == pygame.K_0:
                    features.debug_print_fps = not features.debug_print_fps
                    logger.warning("toggled debug_print_fps: %s", features.debug_print_fps)
                elif event.key == pygame.K_9:
                    features.debug_cam = not features.debug_cam
                    logger.warning("toggled debug_cam: %s", features.debug_cam)
                elif event.key == pygame.K_8:
                    features.time_freeze = not features.time_freeze
                    logger.warning("toggled time_freeze: %s", features.time_freeze)
                elif event.key == pygame.K_7:
                    features.debug_draw = not features.debug_draw
                    logger.warning("toggled debug_draw: %s", features.debug_draw)
                elif event.key == pygame.K_6:
                    features.cheats_enable = not features.cheats_enable
                    logger.warning("toggled cheats_enable: %s", features.cheats_enable)
                elif event.key == pygame.K_5:
                    features.draw_blit_rects = not features.draw_blit_rects
                    logger.warning("toggled draw_blit_rects: %s", features.draw_blit_rects)

    def update(self, level: Level, dt):
        level.update(dt)

    def load_map(self):
        level = Level()
        self.level_loader.load("game/data/maps/tower.json", level)
        return level
