class ConfirmPayement(Window):
    def __init__(self, master):
        Window.__init__(self, master=master, bg_music=master.bg_music)
        self.bg = RectangleShape(*self.size, (0, 0, 0, 170))
        self.frame = RectangleShape(0.50 * self.width,
                                    0.50 * self.height,
                                    GREEN,
                                    outline=3)
        self.text = Text("Are you sure you want\nto buy this car ?",
                         (RESOURCES.FONT["algerian"], 60),
                         justify=Text.T_CENTER)
        self.button_yes = Button(self,
                                 "Yes",
                                 self.text.font,
                                 bg=GREEN,
                                 hover_bg=GREEN_LIGHT,
                                 active_bg=GREEN_DARK,
                                 hover_sound=RESOURCES.SFX["select"],
                                 on_click_sound=RESOURCES.SFX["validate"],
                                 highlight_color=YELLOW,
                                 callback=self.buy)
        self.button_red_cross = ImageButton(
            self,
            img=RESOURCES.IMG["red_cross"],
            active_img=RESOURCES.IMG["red_cross_hover"],
            hover_sound=RESOURCES.SFX["select"],
            on_click_sound=RESOURCES.SFX["back"],
            callback=self.stop,
            highlight_color=YELLOW)
        self.buyed = False
        self.bind_key(pygame.K_ESCAPE,
                      lambda event: self.stop(sound=RESOURCES.SFX["back"]))
        self.bind_joystick(
            0, "B", lambda event: self.stop(sound=RESOURCES.SFX["back"]))

    def place_objects(self):
        self.text.center = self.frame.center = self.center
        self.button_red_cross.move(left=self.frame.left + 5,
                                   top=self.frame.top + 5)
        self.button_yes.move(bottom=self.frame.bottom - 10,
                             centerx=self.frame.centerx)

    def set_grid(self):
        self.button_red_cross.set_obj_on_side(on_bottom=self.button_yes)
        self.button_yes.set_obj_on_side(on_top=self.button_red_cross)

    def buy(self):
        self.buyed = True
        self.stop()
class LocalPlayingSection(Section):
    def __init__(self, master, gameplay: FourInARowGameplay):
        Section.__init__(self, master, "Local Multiplaying", gameplay)
        self.form = Form(self)
        self.form.add_entry("P1", Text("P1 Name:", theme="form"), Entry(self))
        self.form.add_entry("P2", Text("P2 Name:", theme="form"), Entry(self))
        self.button_play = Button(self,
                                  "Play",
                                  theme=["option", "section"],
                                  callback=self.play)

    def on_start_loop(self) -> None:
        super().on_start_loop()
        self.button_play.focus_set()

    def place_objects(self) -> None:
        Section.place_objects(self)
        self.form.move(left=self.frame.left + 10, top=self.title.bottom + 50)
        self.button_play.move(centerx=self.frame.centerx,
                              bottom=self.frame.bottom - 10)

    def set_grid(self) -> None:
        self.button_back.set_obj_on_side(on_bottom=self.form[0],
                                         on_right=self.form[0])
        self.form.set_obj_on_side(on_top=self.button_back,
                                  on_left=self.button_back,
                                  on_bottom=self.button_play)
        self.button_play.set_obj_on_side(on_top=self.form[-1])

    def play(self) -> None:
        player_1_name = self.form.get("P1") or None
        player_2_name = self.form.get("P2") or None
        self.gameplay.start(LOCAL_PLAYER,
                            player_name=player_1_name,
                            enemy_name=player_2_name)
        self.stop()
class LANPlayingP2(Section):
    def __init__(self, master, gameplay: FourInARowGameplay):
        Section.__init__(self, master, "Play as P2", gameplay)
        self.form = Form(self)
        self.form.add_entry("name", Text("Your Name:", theme="form"),
                            Entry(self))
        self.form.add_entry("IP", Text("IP address:", theme="form"),
                            Entry(self, width=15))
        self.form.add_entry("port", Text("Port:", theme="form"),
                            Entry(self, width=15))
        self.button_connect = Button(self,
                                     "Connect to P1",
                                     theme=["option", "section"],
                                     callback=self.connection)
        self.text_game_status = Text(font=RESOURCES.font("heavy", 30),
                                     shadow_x=1,
                                     shadow_y=1)

    def place_objects(self) -> None:
        Section.place_objects(self)
        self.form.move(left=self.frame.left + 10, top=self.title.bottom + 50)
        self.text_game_status.move(centerx=self.frame.centerx,
                                   top=self.form.bottom + 10)
        self.button_connect.move(centerx=self.frame.centerx,
                                 bottom=self.frame.bottom - 10)

    def update(self) -> None:
        self.button_connect.state = Button.NORMAL if self.form.get(
            "name") else Button.DISABLED

    def on_start_loop(self) -> None:
        super().on_start_loop()
        self.form.get_entry("name").focus_set()
        self.form.get_entry("name").start_edit()
        self.text_game_status.hide()

    def on_quit(self) -> None:
        super().on_quit()
        self.stop_connection()

    def set_grid(self) -> None:
        self.button_back.set_obj_on_side(on_bottom=self.form[0],
                                         on_right=self.form[0])
        self.form.set_obj_on_side(on_top=self.button_back,
                                  on_left=self.button_back,
                                  on_bottom=self.button_connect)
        self.button_connect.set_obj_on_side(on_top=self.form[-1])

    def connection(self) -> None:
        self.text_game_status.show()
        self.text_game_status.message = "Connection..."
        self.draw_and_refresh()
        try:
            address = self.form.get("IP")
            port = int(self.form.get("port"))
        except ValueError:
            self.text_game_status.message = "The port of connection must be a number."
            return
        if not self.connect_to_server(address, port, 3):
            self.text_game_status.message = "Connection failed. Try again."
        else:
            self.gameplay.start(LAN_PLAYER,
                                player=2,
                                player_name=self.form.get("name"))
            self.stop()
class LANPlayingP1(Section):
    def __init__(self, master, gameplay: FourInARowGameplay):
        Section.__init__(self, master, "Play as P1", gameplay)
        self.form = Form(self)
        self.form.add_entry("P1", Text("Your Name:", theme="form"),
                            Entry(self))
        self.button_start_server = Button(self, theme=["option", "section"])
        self.text_game_status = Text(font=RESOURCES.font("heavy", 20),
                                     shadow_x=1,
                                     shadow_y=1)
        self.text_server_ip = Text(font=RESOURCES.font("afterglow", 45),
                                   shadow_x=2,
                                   shadow_y=1)
        self.text_server_port = Text(font=RESOURCES.font("afterglow", 45),
                                     shadow_x=2,
                                     shadow_y=1)

    def place_objects(self) -> None:
        Section.place_objects(self)
        self.form.move(left=self.frame.left + 10, top=self.title.bottom + 50)
        self.text_game_status.move(centerx=self.frame.centerx,
                                   top=self.form.bottom + 10)
        self.button_start_server.move(centerx=self.frame.centerx,
                                      top=self.form.bottom + 50)
        self.text_server_ip.move(centerx=self.frame.centerx,
                                 top=self.button_start_server.bottom + 30)
        self.text_server_port.move(centerx=self.frame.centerx,
                                   top=self.text_server_ip.bottom + 10)

    def update(self) -> None:
        if not self.client_socket.connected():
            self.button_start_server.state = Button.NORMAL if self.form.get(
                "P1") else Button.DISABLED
            self.form.get_entry("P1").state = Entry.NORMAL
        else:
            self.button_start_server.state = Button.NORMAL
            self.form.get_entry("P1").state = Entry.DISABLED
            if self.get_server_clients_count() == 2:
                self.set_server_listen(0)
                self.gameplay.start(LAN_PLAYER,
                                    player=1,
                                    player_name=self.form.get("P1"))
                self.stop()

    def on_start_loop(self) -> None:
        super().on_start_loop()
        self.form.get_entry("P1").focus_set()
        self.form.get_entry("P1").start_edit()
        self.stop_server()

    def on_quit(self) -> None:
        super().on_quit()
        self.stop_connection()

    def set_grid(self) -> None:
        self.button_back.set_obj_on_side(on_bottom=self.form[0],
                                         on_right=self.form[0])
        self.form.set_obj_on_side(on_top=self.button_back,
                                  on_left=self.button_back,
                                  on_bottom=self.button_start_server)
        self.button_start_server.set_obj_on_side(on_top=self.form[-1],
                                                 on_left=self.button_back)

    def start_server(self) -> None:
        try:
            ip, port = self.create_server(12800, 1)
        except OSError:
            self.text_game_status.message = "Cannot create server"
        else:
            self.text_game_status.message = "Waiting for player 2 to connect"
            self.text_server_ip.message = "IP: {}".format(ip)
            self.text_server_port.message = "Port: {}".format(port)
            self.text_server_ip.show()
            self.text_server_port.show()
            self.button_start_server.text = "Stop server"
            self.button_start_server.callback = self.stop_server
        self.text_game_status.show()
        self.place_objects()

    def stop_server(self) -> None:
        self.stop_connection()
        self.text_game_status.hide()
        self.text_server_ip.hide()
        self.text_server_port.hide()
        self.button_start_server.text = "Start server"
        self.button_start_server.callback = self.start_server
class Garage(Window):
    def __init__(self):
        Window.__init__(self,
                        bg_color=GRAY,
                        bg_music=RESOURCES.MUSIC["garage"])
        params_for_all_buttons = {
            "bg": GREEN,
            "hover_bg": GREEN_LIGHT,
            "active_bg": GREEN_DARK,
            "highlight_color": YELLOW,
            "hover_sound": RESOURCES.SFX["select"],
        }
        params_for_button_except_back = {
            "on_click_sound": RESOURCES.SFX["validate"],
            "disabled_sound": RESOURCES.SFX["block"],
            "disabled_bg": GRAY_LIGHT,
        }
        params_for_button_except_back.update(params_for_all_buttons)
        params_for_car_viewer = {
            k: params_for_button_except_back[k]
            for k in ["hover_sound", "on_click_sound"]
        }
        self.button_back = ImageButton(self,
                                       RESOURCES.IMG["blue_arrow"],
                                       **params_for_all_buttons,
                                       on_click_sound=RESOURCES.SFX["back"],
                                       callback=self.stop)
        self.car_viewer = CarViewer(self, SAVE["car"], **params_for_car_viewer)

        size_progress_bar = (300, 30)
        self.speed_bar = ProgressBar(*size_progress_bar, TRANSPARENT, GREEN)
        self.maniability_bar = ProgressBar(*size_progress_bar, TRANSPARENT,
                                           GREEN)
        self.braking_bar = ProgressBar(*size_progress_bar, TRANSPARENT, GREEN)

        self.left_arrow = ImageButton(
            self,
            img=RESOURCES.IMG["left_arrow"],
            active_img=RESOURCES.IMG["left_arrow_hover"],
            **params_for_button_except_back,
            callback=self.car_viewer.decrease_id)
        self.right_arrow = ImageButton(
            self,
            img=RESOURCES.IMG["right_arrow"],
            active_img=RESOURCES.IMG["right_arrow_hover"],
            **params_for_button_except_back,
            callback=self.car_viewer.increase_id)
        for arrow in [self.left_arrow, self.right_arrow]:
            arrow.take_focus(False)
        self.button_price = Button(self,
                                   font=(RESOURCES.FONT["algerian"], 40),
                                   img=Image(RESOURCES.IMG["piece"], size=40),
                                   compound="right",
                                   callback=self.buy_car,
                                   **params_for_button_except_back)
        self.button_play = Button(self,
                                  "Play",
                                  font=(RESOURCES.FONT["algerian"], 70),
                                  callback=self.play,
                                  **params_for_button_except_back)
        self.text_money = Text(format_number(SAVE["money"]),
                               (RESOURCES.FONT["algerian"], 50),
                               YELLOW,
                               img=Image(RESOURCES.IMG["piece"], height=40),
                               compound="right")
        self.text_highscore = Text(
            "Highscore: {}".format(format_number(SAVE["highscore"])),
            (RESOURCES.FONT["algerian"], 50), YELLOW)
        self.padlock = Image(RESOURCES.IMG["padlock"])
        self.bind_key(pygame.K_ESCAPE,
                      lambda event: self.stop(sound=RESOURCES.SFX["back"]))
        self.bind_joystick(
            0, "B", lambda event: self.stop(sound=RESOURCES.SFX["back"]))

    def update(self):
        self.left_arrow.set_visibility(self.car_viewer.id > 1)
        self.right_arrow.set_visibility(
            self.car_viewer.id < len(self.car_viewer))
        if not SAVE["owned_cars"][self.car_viewer.id]:
            self.padlock.show()
            price = self.car_viewer["price"]
            if isinstance(price, int):
                self.button_price.show()
                self.button_price.text = format_number(price)
                self.button_price.state = Button.NORMAL if SAVE[
                    "money"] >= price else Button.DISABLED
            else:
                self.button_price.hide()
            self.button_play.state = Button.DISABLED
        else:
            self.padlock.hide()
            self.button_price.hide()
            self.button_play.state = Button.NORMAL
            SAVE["car"] = self.car_viewer.id
        max_s = self.car_viewer.max_speed
        min_a = self.car_viewer.min_acceleration
        max_m = self.car_viewer.max_maniability
        min_b = self.car_viewer.min_braking
        s = self.car_viewer["max_speed"]
        a = self.car_viewer["acceleration"]
        m = self.car_viewer["maniability"]
        b = self.car_viewer["braking"]
        self.speed_bar.percent = (s + min_a) / (max_s + a)
        self.maniability_bar.percent = m / max_m
        self.braking_bar.percent = min_b / b

    def place_objects(self):
        self.button_back.topleft = (5, 5)
        self.car_viewer.move(center=self.center)
        self.padlock.center = self.car_viewer.center

        self.braking_bar.move(bottom=self.car_viewer.top - 40,
                              centerx=self.car_viewer.centerx + 100)
        self.maniability_bar.move(bottom=self.braking_bar.top - 10,
                                  centerx=self.car_viewer.centerx + 100)
        self.speed_bar.move(bottom=self.maniability_bar.top - 10,
                            centerx=self.car_viewer.centerx + 100)

        self.speed_bar.show_label("Speed/Acc.",
                                  ProgressBar.S_LEFT,
                                  font=(RESOURCES.FONT["algerian"], 40))
        self.maniability_bar.show_label("Maniability",
                                        ProgressBar.S_LEFT,
                                        font=(RESOURCES.FONT["algerian"], 40))
        self.braking_bar.show_label("Braking",
                                    ProgressBar.S_LEFT,
                                    font=(RESOURCES.FONT["algerian"], 40))

        self.left_arrow.move(left=self.left + 50, centery=self.centery)
        self.right_arrow.move(right=self.right - 50, centery=self.centery)
        self.button_price.move(centerx=self.centerx,
                               top=self.car_viewer.bottom + 25)
        self.button_play.move(bottom=self.bottom - 50, right=self.right - 10)

        self.text_money.move(top=5, right=self.right - 10)
        self.text_highscore.move(bottom=self.bottom - 50, left=5)

    def set_grid(self):
        self.button_back.set_obj_on_side(on_bottom=self.car_viewer)
        self.car_viewer.set_obj_on_side(on_top=self.button_back,
                                        on_bottom=self.button_price)
        self.button_price.set_obj_on_side(on_top=self.car_viewer,
                                          on_bottom=self.button_play)
        self.button_play.set_obj_on_side(on_top=self.button_price)

    def buy_car(self):
        confirm_window = ConfirmPayement(self)
        confirm_window.mainloop()
        if confirm_window.buyed:
            SAVE["money"] -= self.car_viewer["price"]
            SAVE["owned_cars"][self.car_viewer.id] = True
            self.text_money.message = format_number(SAVE["money"])
            if Clickable.MODE != Clickable.MODE_MOUSE:
                self.car_viewer.focus_set()

    def play(self):
        environment_chooser = EnvironmentChooser(self)
        environment_chooser.mainloop()
        self.text_money.message = format_number(SAVE["money"])
        self.text_highscore.message = "Highscore: {}".format(
            format_number(SAVE["highscore"]))
class Options(Window):
    def __init__(self, master: Window):
        Window.__init__(self, master=master, bg_music=master.bg_music)
        self.frame = RectangleShape(0.60 * self.width,
                                    0.60 * self.height,
                                    GREEN,
                                    outline=3)
        self.title = Text("Options", font=(RESOURCES.FONT["algerian"], 70))

        self.options_font = (RESOURCES.FONT["algerian"], 40)
        self.case_font = (RESOURCES.FONT["algerian"], 30)
        self.control_font = ("calibri", 20)
        params_for_all_scales = {
            "width": 0.45 * self.frame.w,
            "color": TRANSPARENT,
            "scale_color": GREEN_DARK,
            "from_": 0,
            "to": 100,
            "outline": 3,
        }
        params_for_all_buttons = {
            "highlight_color": YELLOW,
            "hover_sound": RESOURCES.SFX["select"],
            "disabled_sound": RESOURCES.SFX["block"]
        }
        params_for_option_buttons = {
            "on_click_sound": RESOURCES.SFX["validate"]
        }
        params_for_buttons = {
            "bg": GRAY_DARK,
            "fg": WHITE,
            "hover_bg": GRAY,
            "active_bg": BLACK
        }
        params_for_reset_button = {
            "bg": RED,
            "fg": WHITE,
            "hover_bg": RED_LIGHT,
            "active_bg": RED_DARK,
        }

        self.button_back = ImageButton(self,
                                       img=RESOURCES.IMG["blue_arrow"],
                                       on_click_sound=RESOURCES.SFX["back"],
                                       callback=self.stop,
                                       **params_for_all_buttons)
        self.button_change_page = Button(self,
                                         ">>",
                                         font=self.case_font,
                                         callback=self.change_page,
                                         **params_for_all_buttons,
                                         **params_for_option_buttons,
                                         **params_for_buttons)
        self.nb_pages = 2
        self.page = 1

        ## PAGE 1 ##
        valid_img = Image(RESOURCES.IMG["green_valid"])
        self.text_music = Text("Music:", self.options_font)
        self.cb_music = CheckBox(self,
                                 30,
                                 30,
                                 TRANSPARENT,
                                 image=valid_img,
                                 value=self.get_music_state(),
                                 callback=self.set_music_state,
                                 **params_for_all_buttons,
                                 **params_for_option_buttons)
        self.scale_music = Scale(
            self,
            **params_for_all_scales,
            **params_for_all_buttons,
            height=self.cb_music.height,
            default=Window.music_volume() * 100,
            callback=lambda value, percent: Window.set_music_volume(percent))
        self.text_sound = Text("SFX:", self.options_font)
        self.cb_sound = CheckBox(self,
                                 30,
                                 30,
                                 TRANSPARENT,
                                 image=valid_img,
                                 value=self.get_sound_state(),
                                 callback=self.set_sound_state,
                                 **params_for_all_buttons,
                                 **params_for_option_buttons)
        self.scale_sound = Scale(
            self,
            **params_for_all_scales,
            **params_for_all_buttons,
            height=self.cb_sound.height,
            default=Window.sound_volume() * 100,
            callback=lambda value, percent: Window.set_sound_volume(percent))
        self.text_fps = Text("FPS:", self.options_font)
        self.cb_show_fps = CheckBox(self,
                                    30,
                                    30,
                                    TRANSPARENT,
                                    image=valid_img,
                                    value=Window.fps_is_shown(),
                                    callback=self.show_fps,
                                    **params_for_all_buttons,
                                    **params_for_option_buttons)
        self.button_reset = Button(self,
                                   "Reset Save",
                                   font=(RESOURCES.FONT["algerian"], 30),
                                   callback=SAVE.reset,
                                   state=Button.DISABLED,
                                   **params_for_all_buttons,
                                   **params_for_option_buttons,
                                   **params_for_reset_button)
        ## PAGE 2 ##
        self.text_acceleration = Text("Accélérer:", self.options_font)
        self.button_auto_acceleration = Button(
            self,
            font=self.case_font,
            callback=lambda: SAVE.update(auto_acceleration=not SAVE[
                "auto_acceleration"]),
            **params_for_all_buttons,
            **params_for_option_buttons,
            **params_for_buttons)
        self.button_acceleration = Button(
            self,
            font=self.control_font,
            callback=lambda: self.choose_key("speed_up"),
            **params_for_all_buttons,
            **params_for_option_buttons,
            **params_for_buttons)
        self.text_brake = Text("Freiner:", self.options_font)
        self.button_brake = Button(self,
                                   font=self.control_font,
                                   callback=lambda: self.choose_key("brake"),
                                   **params_for_all_buttons,
                                   **params_for_option_buttons,
                                   **params_for_buttons)
        self.text_move_up = Text("Aller en haut:", self.options_font)
        self.button_move_up = Button(self,
                                     font=self.control_font,
                                     callback=lambda: self.choose_key("up"),
                                     **params_for_all_buttons,
                                     **params_for_option_buttons,
                                     **params_for_buttons)
        self.text_move_down = Text("Aller en bas:", self.options_font)
        self.button_move_down = Button(
            self,
            font=self.control_font,
            callback=lambda: self.choose_key("down"),
            **params_for_all_buttons,
            **params_for_option_buttons,
            **params_for_buttons)

        self.bind_key(pygame.K_ESCAPE,
                      lambda event: self.stop(sound=RESOURCES.SFX["back"]))
        self.bind_joystick(
            0, "B", lambda event: self.stop(sound=RESOURCES.SFX["back"]))

    def on_quit(self):
        SAVE.dump()

    def change_page(self):
        self.page = (self.page % self.nb_pages) + 1

    def update(self):
        self.hide_all(without=[
            self.frame, self.title, self.button_back, self.button_change_page
        ])
        if self.page == 1:
            self.text_music.show()
            self.text_sound.show()
            for checkbox, scale in [(self.cb_music, self.scale_music),
                                    (self.cb_sound, self.scale_sound)]:
                checkbox.show()
                if checkbox.value is True:
                    scale.show()
                    checkbox.set_obj_on_side(on_right=scale)
                else:
                    checkbox.set_obj_on_side(on_right=self.button_change_page)
            self.text_fps.show()
            self.cb_show_fps.show()
            self.button_reset.show()
            self.button_back.set_obj_on_side(on_bottom=self.cb_music,
                                             on_right=self.cb_music)
            self.button_change_page.set_obj_on_side(on_top=self.cb_show_fps,
                                                    on_left=self.button_reset)
        elif self.page == 2:
            self.text_acceleration.show()
            self.button_auto_acceleration.text = "Automatique" if SAVE[
                "auto_acceleration"] else "Manuel"
            self.button_auto_acceleration.show()
            control_text_format = "Key: {key}\nJoystick: {joy}"
            if not SAVE["auto_acceleration"]:
                self.button_acceleration.text = control_text_format.format(
                    **SAVE["controls"]["speed_up"])
                self.button_acceleration.move(
                    left=self.button_auto_acceleration.right + 10,
                    centery=self.button_auto_acceleration.centery)
                self.button_acceleration.show()
                self.button_auto_acceleration.set_obj_on_side(
                    on_right=self.button_acceleration)
            else:
                self.button_auto_acceleration.set_obj_on_side(
                    on_right=self.button_back)
            fields = [
                (self.text_brake, self.button_brake, "brake"),
                (self.text_move_up, self.button_move_up, "up"),
                (self.text_move_down, self.button_move_down, "down"),
            ]
            for text, button, action in fields:
                text.show()
                button.text = control_text_format.format(
                    **SAVE["controls"][action])
                button.show()
            self.button_back.set_obj_on_side(
                on_bottom=self.button_auto_acceleration,
                on_right=self.button_auto_acceleration)
            self.button_change_page.set_obj_on_side(
                on_top=self.button_move_down, on_left=self.button_move_down)

    def place_objects(self):
        self.frame.move(center=self.center)
        self.title.move(top=self.frame.top + 10, centerx=self.frame.centerx)
        self.button_back.move(top=self.frame.top + 5, left=self.frame.left + 5)
        self.button_change_page.move(bottom=self.frame.bottom - 5,
                                     right=self.frame.right - 5)
        ## PAGE 1 ##
        self.text_music.move(left=self.frame.left + 10,
                             top=self.title.bottom + 10)
        self.text_sound.move(right=self.text_music.right,
                             top=self.text_music.bottom + 5)
        self.cb_music.move(left=self.text_music.right + 10,
                           centery=self.text_music.centery)
        self.cb_sound.move(left=self.text_music.right + 10,
                           centery=self.text_sound.centery)
        self.scale_music.move(centerx=self.frame.centerx,
                              centery=self.cb_music.centery)
        self.scale_music.show_value(Scale.S_RIGHT, font=self.case_font)
        self.scale_sound.move(centerx=self.frame.centerx,
                              centery=self.cb_sound.centery)
        self.scale_sound.show_value(Scale.S_RIGHT, font=self.case_font)
        self.text_fps.move(right=self.text_music.right,
                           top=self.text_sound.bottom + 50)
        self.cb_show_fps.move(left=self.text_fps.right + 10,
                              centery=self.text_fps.centery)
        self.button_reset.move(bottom=self.frame.bottom - 5,
                               left=self.frame.left + 5)
        ## PAGE 2 ##
        self.text_acceleration.move(left=self.frame.left + 10,
                                    top=self.title.bottom + 50)
        self.button_auto_acceleration.move(
            left=self.text_acceleration.right + 10,
            centery=self.text_acceleration.centery)
        self.text_brake.move(left=self.text_acceleration.left,
                             top=self.text_acceleration.bottom + 50)
        self.button_brake.move(left=self.text_brake.right + 10,
                               centery=self.text_brake.centery)
        self.text_move_up.move(left=self.text_acceleration.left,
                               top=self.text_brake.bottom + 50)
        self.button_move_up.move(left=self.text_move_up.right + 10,
                                 centery=self.text_move_up.centery)
        self.text_move_down.move(left=self.text_acceleration.left,
                                 top=self.text_move_up.bottom + 50)
        self.button_move_down.move(left=self.text_move_down.right + 10,
                                   centery=self.text_move_down.centery)

    def set_grid(self):
        ## PAGE 1 ##
        self.cb_music.set_obj_on_side(on_top=self.button_back,
                                      on_left=self.button_back,
                                      on_bottom=self.cb_sound)
        self.scale_music.set_obj_on_side(on_top=self.button_back,
                                         on_left=self.cb_music,
                                         on_bottom=self.scale_sound,
                                         on_right=self.button_change_page)
        self.cb_sound.set_obj_on_side(on_top=self.cb_music,
                                      on_left=self.button_back,
                                      on_bottom=self.cb_show_fps)
        self.scale_sound.set_obj_on_side(on_top=self.scale_music,
                                         on_left=self.cb_sound,
                                         on_bottom=self.cb_show_fps,
                                         on_right=self.button_change_page)
        self.cb_show_fps.set_obj_on_side(on_left=self.button_back,
                                         on_top=self.cb_sound,
                                         on_bottom=self.button_reset,
                                         on_right=self.button_change_page)
        self.button_reset.set_obj_on_side(on_left=self.button_back,
                                          on_top=self.cb_show_fps,
                                          on_right=self.button_change_page)
        ## PAGE 2 ##
        self.button_auto_acceleration.set_obj_on_side(
            on_top=self.button_back,
            on_left=self.button_back,
            on_bottom=self.button_brake)
        self.button_acceleration.set_obj_on_side(
            on_top=self.button_back,
            on_left=self.button_auto_acceleration,
            on_bottom=self.button_brake,
            on_right=self.button_change_page)
        self.button_brake.set_obj_on_side(on_top=self.button_auto_acceleration,
                                          on_left=self.button_back,
                                          on_bottom=self.button_move_up,
                                          on_right=self.button_change_page)
        self.button_move_up.set_obj_on_side(on_top=self.button_brake,
                                            on_left=self.button_back,
                                            on_bottom=self.button_move_down,
                                            on_right=self.button_change_page)
        self.button_move_down.set_obj_on_side(
            on_top=self.button_move_up,
            on_left=self.button_back,
            on_bottom=self.button_change_page,
            on_right=self.button_change_page)

    def choose_key(self, action: str):
        AssignmentPrompt(self, action).mainloop()