#!/usr/bin/python3

import random
import os
import json

from engine import maze, sdl2 as engine, controls, graphics, unit_manager, scoring

class MiceMaze(
    controls.KeyBindings,
    unit_manager.UnitManager,
    graphics.Graphics,
    scoring.Scoring
):

    # ==================== INITIALIZATION ====================
    
    def __init__(self, maze_file):
        self.map = maze.Map(maze_file)
        self.audio = True
        self.cell_size = 40
        self.full_screen = False
        self.render_engine = engine.GameWindow(self.map.width, self.map.height, 
                                        self.cell_size, "Mice!", 
                                        key_callback=(self.key_pressed, self.key_released, self.axis_scroll))
        self.load_assets()
        self.render_engine.window.show()
        self.pointer = (random.randint(1, self.map.width-2), random.randint(1, self.map.height-2))
        self.scroll_cursor()
        self.points = 0
        self.units = {}
        self.unit_positions = {}
        self.unit_positions_before = {}
        self.scrolling_direction = None
        self.game_status = "start_menu"
        self.game_end = (False, None)
        self.scrolling = False
        self.sounds = {}
        self.start_game()
        self.background_texture = None
        self.configs = self.get_config()

        
    def get_config(self):
        configs = {}
        for file in os.listdir("conf"):
            if file.endswith(".json"):
                with open(os.path.join("conf", file)) as f:
                    configs[file[:-5]] = json.load(f)
        return configs
    
    def start_game(self):
        self.ammo = {
            "bomb": {
                "count": 2,
                "max": 5
            },
            "nuclear": {
                "count": 1,
                "max": 1
            },
            "mine": {
                "count": 5,
                "max": 5
            }
        }
        self.blood_stains = {}
        self.background_texture = None
        for _ in range(5):
            self.spawn_rat()
    
    # ==================== GAME LOGIC ====================

    def refill_ammo(self):
        for ammo_type, data in self.ammo.items():
            if ammo_type == "bomb":
                if random.random() < 0.01:
                    data["count"] = min(data["count"] + 1, data["max"])
            elif ammo_type == "mine":
                if random.random() < 0.05:
                    data["count"] = min(data["count"] + 1, data["max"])

    def update_maze(self):
        if self.game_over():
            return
        if self.game_status == "paused":
            self.render_engine.dialog("Pause")
            return
        if self.game_status == "start_menu":
            self.render_engine.dialog("Welcome to the Mice!", subtitle="A game by Matteo because he was bored",image=self.assets["BMP_WEWIN"])
            return
        self.render_engine.delete_tag("unit")
        self.render_engine.delete_tag("effect")
        self.render_engine.draw_pointer(self.pointer[0] * self.cell_size, self.pointer[1] * self.cell_size)
        self.unit_positions.clear()
        self.unit_positions_before.clear()
        for unit in self.units.values():
            self.unit_positions.setdefault(unit.position, []).append(unit)
            self.unit_positions_before.setdefault(unit.position_before, []).append(unit)
        for unit in self.units.copy().values():
            unit.move()
            unit.collisions()
            unit.draw()
        self.render_engine.update_status(f"Mice: {self.count_rats()} - Points: {self.points}")
        self.refill_ammo()
        self.render_engine.update_ammo(self.ammo, self.assets)
        self.scroll()
        self.render_engine.new_cycle(50, self.update_maze)

    def run(self):
        self.render_engine.mainloop(update=self.update_maze, bg_update=self.draw_maze)

    # ==================== GAME OVER LOGIC ====================
    
    def game_over(self):
        if self.game_end[0]:
            if not self.game_end[1]:
                self.render_engine.dialog("Game Over: Mice are too many!", image=self.assets["BMP_WEWIN"])
            else:
                self.render_engine.dialog(f"You Win! Points: {self.points}", image=self.assets["BMP_WEWIN"], scores=self.read_score())

                
            return True
        count_rats = self.count_rats()
        if count_rats > 200:
            self.render_engine.stop_sound()
            self.render_engine.play_sound("WEWIN.WAV")
            self.game_end = (True, False)
            self.game_status = "paused"
            return True
        if not count_rats:
            self.render_engine.stop_sound()
            self.render_engine.play_sound("VICTORY.WAV")
            self.render_engine.play_sound("WELLDONE.WAV", tag="effects")
            self.game_end = (True, True)
            self.game_status = "paused"
            self.save_score()
            return True




        
if __name__ == "__main__":
    print("Game starting...")
    solver = MiceMaze('maze.json')
    solver.run()

