import sys
import pygame
from app_window import App_window
from button import Button
from snake import Snake
from food import Food
from settings import WIDTH, HEIGHT, FONT, BG_COL, QUIT_BUTTON_COLOUR, PLAY_BUTTON_COLOUR, BLACK, FPS, RED


class App:
    def __init__(self):
        pygame.init()
        self.clock = pygame.time.Clock()
        self.window = pygame.display.set_mode((WIDTH, HEIGHT))
        self.gameover = pygame.font.SysFont("Comicsansms",
                                            90,
                                            bold=False,
                                            italic=True)
        self.font = pygame.font.SysFont(FONT, 20, bold=1)
        self.running = True
        self.state = "intro"
        self.intro_buttons = []
        self.playing_buttons = []
        self.gameover_buttons = []
        self.active_buttons = self.intro_buttons
        self.app_window = App_window(self)
        self.snake = Snake(self)
        self.food = Food(self)
        self.make_buttons()

    def make_buttons(self):
        # INTRO PLAY AND QUIT BUTTON

        intro_play_button = Button(self,
                                   50,
                                   300,
                                   WIDTH - 100,
                                   50,
                                   PLAY_BUTTON_COLOUR,
                                   hover_colour=(49, 218, 46),
                                   function=self.intro_to_play,
                                   text="PLAY")
        self.intro_buttons.append(intro_play_button)

        intro_quit_button = Button(self,
                                   50,
                                   HEIGHT - 100,
                                   WIDTH - 100,
                                   50,
                                   QUIT_BUTTON_COLOUR,
                                   hover_colour=(219, 53, 43),
                                   function=self.intro_quit,
                                   text="QUIT")
        self.intro_buttons.append(intro_quit_button)

        # PLAYING QUIT BUTTON

        playing_quit_button = Button(self, (WIDTH // 2) - 50,
                                     20,
                                     100,
                                     33,
                                     QUIT_BUTTON_COLOUR,
                                     hover_colour=(219, 53, 43),
                                     function=self.playing_quit,
                                     text="QUIT")
        self.playing_buttons.append(playing_quit_button)

        # GAMEOVER BUTTON

        gameover_play_again_button = Button(self,
                                            50,
                                            300,
                                            WIDTH - 100,
                                            50,
                                            PLAY_BUTTON_COLOUR,
                                            hover_colour=(36, 183, 23),
                                            function=self.reset,
                                            text="PLAY AGAIN")
        self.gameover_buttons.append(gameover_play_again_button)

        gameover_quit_button = Button(self,
                                      50,
                                      HEIGHT - 100,
                                      WIDTH - 100,
                                      50,
                                      QUIT_BUTTON_COLOUR,
                                      hover_colour=(216, 53, 43),
                                      function=self.intro_quit,
                                      text="QUIT")
        self.gameover_buttons.append(gameover_quit_button)

    def show_text(self, text, pos):
        text = self.font.render(text, False, BLACK)
        self.window.blit(text, (pos[0], pos[1]))

    def reset(self):
        # reset the game
        self.state = "play"
        self.active_buttons = self.playing_buttons
        self.snake = Snake(self)
        FPS[0] = 5

    def run(self):
        while self.running:
            self.events()
            self.update()
            self.draw()
            self.clock.tick(FPS[0])
        pygame.quit()
        sys.exit()

    def events(self):
        if self.state == "intro":
            self.intro_events()
        if self.state == "play":
            self.playing_events()
        if self.state == "dead":
            self.gameover_events()

    def update(self):
        if self.state == "intro":
            self.intro_update()
        if self.state == "play":
            self.playing_update()
        if self.state == "dead":
            self.gameover_update()

    def draw(self):
        self.window.fill(BG_COL)
        if self.state == "intro":
            self.intro_draw()
        if self.state == "play":
            self.playing_draw()
        if self.state == "dead":
            self.gameover_draw()
        pygame.display.update()

    # INTRO FUNCTIONS

    def intro_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                self.running = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                for button in self.active_buttons:
                    if button.hovered:
                        button.click()

    def intro_update(self):
        for button in self.active_buttons:
            button.update()

    def intro_draw(self):
        for button in self.active_buttons:
            button.draw()

    def intro_to_play(self):
        self.state = "play"
        self.active_buttons = self.playing_buttons

    def intro_quit(self):
        self.running = False

    # PlAY FUNCTIONS

    def playing_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
                # checks if a key is pressed down
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.running = False
                if event.key == pygame.K_LEFT and self.snake.direction != [
                        1, 0
                ]:
                    self.snake.direction = [-1, 0]
                if event.key == pygame.K_RIGHT and self.snake.direction != [
                        -1, 0
                ]:
                    self.snake.direction = [1, 0]
                if event.key == pygame.K_UP and self.snake.direction != [0, 1]:
                    self.snake.direction = [0, -1]
                if event.key == pygame.K_DOWN and self.snake.direction != [
                        0, -1
                ]:
                    self.snake.direction = [0, 1]
            if event.type == pygame.MOUSEBUTTONDOWN:
                for button in self.active_buttons:
                    if button.hovered:
                        button.click()

    def playing_update(self):
        for button in self.active_buttons:
            button.update()
        self.app_window.update()

    def playing_draw(self):
        self.app_window.draw()
        for button in self.active_buttons:
            button.draw()
        self.show_text("Score: " + str(self.snake.length - 1), [20, 20])

    def playing_quit(self):
        self.running = False

    # GAMEOVER FUNCTIONS

    def gameover_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                self.running = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                for button in self.active_buttons:
                    if button.hovered:
                        button.click()

    def gameover_update(self):
        for button in self.active_buttons:
            button.update()

    def gameover_draw(self):
        for button in self.active_buttons:
            button.draw()
        self.game_over("GAME OVER", [WIDTH - 440, 30])

    def game_over(self, text, pos):
        text = self.gameover.render(text, False, RED)
        self.window.blit(text, (pos[0], pos[1]))

[((282, 295), 'pygame.init', 'pygame.init', ([], {}), '()\n', (293, 295), False, 'import pygame\n'), ((317, 336), 'pygame.time.Clock', 'pygame.time.Clock', ([], {}), '()\n', (334, 336), False, 'import pygame\n'), ((359, 399), 'pygame.display.set_mode', 'pygame.display.set_mode', (['(WIDTH, HEIGHT)'], {}), '((WIDTH, HEIGHT))\n', (382, 399), False, 'import pygame\n'), ((424, 487), 'pygame.font.SysFont', 'pygame.font.SysFont', (['"""Comicsansms"""', '(90)'], {'bold': '(False)', 'italic': '(True)'}), "('Comicsansms', 90, bold=False, italic=True)\n", (443, 487), False, 'import pygame\n'), ((640, 677), 'pygame.font.SysFont', 'pygame.font.SysFont', (['FONT', '(20)'], {'bold': '(1)'}), '(FONT, 20, bold=1)\n', (659, 677), False, 'import pygame\n'), ((911, 927), 'app_window.App_window', 'App_window', (['self'], {}), '(self)\n', (921, 927), False, 'from app_window import App_window\n'), ((949, 960), 'snake.Snake', 'Snake', (['self'], {}), '(self)\n', (954, 960), False, 'from snake import Snake\n'), ((981, 991), 'food.Food', 'Food', (['self'], {}), '(self)\n', (985, 991), False, 'from food import Food\n'), ((1115, 1247), 'button.Button', 'Button', (['self', '(50)', '(300)', '(WIDTH - 100)', '(50)', 'PLAY_BUTTON_COLOUR'], {'hover_colour': '(49, 218, 46)', 'function': 'self.intro_to_play', 'text': '"""PLAY"""'}), "(self, 50, 300, WIDTH - 100, 50, PLAY_BUTTON_COLOUR, hover_colour=(49,\n    218, 46), function=self.intro_to_play, text='PLAY')\n", (1121, 1247), False, 'from button import Button\n'), ((1606, 1744), 'button.Button', 'Button', (['self', '(50)', '(HEIGHT - 100)', '(WIDTH - 100)', '(50)', 'QUIT_BUTTON_COLOUR'], {'hover_colour': '(219, 53, 43)', 'function': 'self.intro_quit', 'text': '"""QUIT"""'}), "(self, 50, HEIGHT - 100, WIDTH - 100, 50, QUIT_BUTTON_COLOUR,\n    hover_colour=(219, 53, 43), function=self.intro_quit, text='QUIT')\n", (1612, 1744), False, 'from button import Button\n'), ((2136, 2272), 'button.Button', 'Button', (['self', '(WIDTH // 2 - 50)', '(20)', '(100)', '(33)', 'QUIT_BUTTON_COLOUR'], {'hover_colour': '(219, 53, 43)', 'function': 'self.playing_quit', 'text': '"""QUIT"""'}), "(self, WIDTH // 2 - 50, 20, 100, 33, QUIT_BUTTON_COLOUR, hover_colour\n    =(219, 53, 43), function=self.playing_quit, text='QUIT')\n", (2142, 2272), False, 'from button import Button\n'), ((2651, 2781), 'button.Button', 'Button', (['self', '(50)', '(300)', '(WIDTH - 100)', '(50)', 'PLAY_BUTTON_COLOUR'], {'hover_colour': '(36, 183, 23)', 'function': 'self.reset', 'text': '"""PLAY AGAIN"""'}), "(self, 50, 300, WIDTH - 100, 50, PLAY_BUTTON_COLOUR, hover_colour=(36,\n    183, 23), function=self.reset, text='PLAY AGAIN')\n", (2657, 2781), False, 'from button import Button\n'), ((3227, 3365), 'button.Button', 'Button', (['self', '(50)', '(HEIGHT - 100)', '(WIDTH - 100)', '(50)', 'QUIT_BUTTON_COLOUR'], {'hover_colour': '(216, 53, 43)', 'function': 'self.intro_quit', 'text': '"""QUIT"""'}), "(self, 50, HEIGHT - 100, WIDTH - 100, 50, QUIT_BUTTON_COLOUR,\n    hover_colour=(216, 53, 43), function=self.intro_quit, text='QUIT')\n", (3233, 3365), False, 'from button import Button\n'), ((4010, 4021), 'snake.Snake', 'Snake', (['self'], {}), '(self)\n', (4015, 4021), False, 'from snake import Snake\n'), ((4209, 4222), 'pygame.quit', 'pygame.quit', ([], {}), '()\n', (4220, 4222), False, 'import pygame\n'), ((4231, 4241), 'sys.exit', 'sys.exit', ([], {}), '()\n', (4239, 4241), False, 'import sys\n'), ((4947, 4970), 'pygame.display.update', 'pygame.display.update', ([], {}), '()\n', (4968, 4970), False, 'import pygame\n'), ((5044, 5062), 'pygame.event.get', 'pygame.event.get', ([], {}), '()\n', (5060, 5062), False, 'import pygame\n'), ((5875, 5893), 'pygame.event.get', 'pygame.event.get', ([], {}), '()\n', (5891, 5893), False, 'import pygame\n'), ((7472, 7490), 'pygame.event.get', 'pygame.event.get', ([], {}), '()\n', (7488, 7490), False, 'import pygame\n')]