Beispiel #1
0
class MazeUI(Frame):
    """
    Maze UI"""
    def __init__(self, parent, maze_generators, solvers):
        Frame.__init__(self, parent)
        self.parent = parent
        self.row, self.col = -1, -1

        self.solvers = solvers
        self.selected_solver_names = []

        self.maze_generators = maze_generators

        self.maze_width = None
        self.maze_height = None
        self.start_solutions = False
        self.generate_new = False

        self.start = False
        self.pause = False
        self.next = False

        self.maze = None
        self.maze_grid = None
        self.visual_grids = {}
        self.photos = {}

        self.canvas_0 = Canvas(self, width=500, height=500)
        self.canvas_0.grid(row=3,
                           column=0,
                           columnspan=3,
                           padx=(4, 4),
                           pady=(5, 5))

        self.canvas_1 = Canvas(self, width=500, height=500)
        self.canvas_1.grid(row=3,
                           column=4,
                           columnspan=3,
                           padx=(4, 4),
                           pady=(5, 5))

        self.canvas_2 = Canvas(self, width=500, height=500)
        self.canvas_2.grid(row=3,
                           column=8,
                           columnspan=3,
                           padx=(4, 4),
                           pady=(5, 5))

        self.canvas_label_0 = None
        self.canvas_label_1 = None
        self.canvas_label_2 = None

        self.photo_0 = None
        self.photo_1 = None
        self.photo_2 = None

        self.__initUI()

    def __initUI(self):
        """
        Initialize UI."""

        self.parent.title("Maze traversal")
        self.pack(fill=BOTH, expand=1)

        Label(self, text='Height').grid(row=0, column=0)
        Label(self, text='Width').grid(row=0, column=1)
        Label(self, text='Maze algorithm').grid(row=0, column=2)

        self.maze_width_entry = Entry(self)
        self.maze_width_entry.grid(row=1, column=0)
        self.maze_width_entry.insert('end', '50')

        self.maze_height_entry = Entry(self)
        self.maze_height_entry.grid(row=1, column=1)
        self.maze_height_entry.insert('end', '50')

        maze_generator_names = []
        for generator in self.maze_generators:
            maze_generator_names.append(generator.get_name())

        var = StringVar(self)
        var.set(maze_generator_names[0])
        self.selected_maze_generator = maze_generator_names[0]

        self.maze_generation_options = OptionMenu(
            self,
            var,
            *maze_generator_names,
            command=self.__select_maze_generator)
        self.maze_generation_options.grid(row=1, column=2)
        self.maze_generation_options.config(width=14)

        self.create_maze = Button(self,
                                  text="Generate maze",
                                  command=self.__generate_maze)
        self.create_maze.grid(row=2, column=1)

        self.initial_canvas = Canvas(self, width=500, height=500)
        self.initial_canvas.grid(row=3,
                                 column=0,
                                 columnspan=3,
                                 padx=(4, 4),
                                 pady=(5, 5))

        self.solver_list = Treeview(self, columns='algorithms')
        self.solver_list['show'] = 'headings'
        self.solver_list.heading('algorithms', text='Algorithms')
        self.solver_list.column('algorithms', width=250, anchor=CENTER)
        self.solver_list.grid(row=3,
                              column=0,
                              columnspan=4,
                              padx=(4, 4),
                              pady=(5, 5))

        for solver in self.solvers:
            name = '"' + solver.get_name() + '"'
            self.solver_list.insert('', 'end', values=name)

        self.start_solution = Button(self,
                                     text="Start",
                                     command=self.__start_solution)
        self.start_solution.grid(row=5, column=0, pady=(0, 10))

        self.pause_solution = Button(self,
                                     text="Pause",
                                     command=self.__pause_solution)
        self.pause_solution.grid(row=5, column=1, pady=(0, 10))

        self.next_step = Button(self, text="Next", command=self.__next_step)
        self.next_step.grid(row=5, column=2, pady=(0, 10))

    def __select_maze_generator(self, value):
        self.selected_maze_generator = value

    def __generate_maze(self):
        size_ok = False
        algos_ok = False
        # Clear previous list
        self.selected_solver_names = []

        # Size input validation
        try:
            height = int(self.maze_height_entry.get())
            width = int(self.maze_width_entry.get())
        except (ValueError, TypeError):
            height, width = '-1', '-1'

        if isinstance(height, int) and isinstance(width, int):
            if 5 <= height <= 100 and 5 <= width <= 100:
                self.maze_width = width
                self.maze_height = height
                size_ok = True
            else:
                messagebox.showwarning(
                    "Size error",
                    "Height and width need to be between 5 and 100.")
                return
        else:
            messagebox.showwarning("Input error",
                                   "Height and width need to be integers.")
            return

        # Getting solver list selections
        solver_selection = self.solver_list.selection()
        if 0 < len(solver_selection) <= 3:
            for selection in solver_selection:
                self.selected_solver_names.append(
                    self.solver_list.item(selection)['values'][0])
            algos_ok = True
        else:
            messagebox.showwarning("Selection error",
                                   "Please select 1-3 solver algorithms.")
            return

        # If inputs are okay, lose the listview and show the canvas
        if size_ok and algos_ok:
            self.solver_list.grid_forget()
            self.initial_canvas.grid_forget()
            self.start_solutions = True
            self.generate_new = True

    def __start_solution(self):
        """
        Stop pausing and start solving."""
        if self.start_solutions:
            self.start = True
            self.pause = False

    def __pause_solution(self):
        """
        Start pausing and stop solving."""
        if self.start_solutions:
            self.pause = True
            self.start = True

    def __next_step(self):
        """
        Pressing next has no meaning if solving isn't paused."""
        if self.start_solutions:
            self.next = True

    def initialize_maze(self, maze):
        self.maze = maze
        self.maze_grid = np.copy(maze.grid)
        self.create_visual_grids(maze)
        self.update_maze()

    def create_visual_grids(self, maze):
        for solver_name in self.selected_solver_names:
            invert_bw_grid = 1 - maze.grid

            # Scale the numbers to 255 and create RGB channels
            visual_grid = np.stack((invert_bw_grid.astype('uint8') * 255,
                                    invert_bw_grid.astype('uint8') * 255,
                                    invert_bw_grid.astype('uint8') * 255),
                                   axis=2)

            self.visual_grids[solver_name] = np.copy(visual_grid)
            self.paint_entrances(solver_name, maze.start, maze.end)

    def paint_entrances(self, solver_name, start, end):
        # Start to red
        self.recolor_point(solver_name, start[0], start[1], (255, 53, 22))

        # End to green
        self.recolor_point(solver_name, end[0], end[1], (2, 255, 32))

    def recolor_point(self, solver_name, r, c, rgb_values):
        self.visual_grids[solver_name][r][c][0] = rgb_values[0]
        self.visual_grids[solver_name][r][c][1] = rgb_values[1]
        self.visual_grids[solver_name][r][c][2] = rgb_values[2]

    def draw_final_path(self, solver_name, path, rgb_values):
        for point in path:
            self.recolor_point(solver_name, point[0], point[1], rgb_values)

    def update_maze(self):
        nr_solvers = len(self.selected_solver_names)

        solver_name_0 = self.selected_solver_names[0]
        pil_image = Image.fromarray(self.visual_grids[solver_name_0])

        old_size = pil_image.size
        ratio = float(480) / max(old_size)
        new_size = tuple([int(x * ratio) for x in old_size])
        pil_image = pil_image.resize(new_size)
        scaled_image = Image.new("RGB", (480, 480))
        scaled_image.paste(pil_image, ((480 - new_size[0]) // 2,
                                       (480 - new_size[1]) // 2))

        self.photo_0 = ImageTk.PhotoImage(scaled_image)
        self.canvas_0.create_image(500, 500, image=self.photo_0, anchor=SE)

        if self.canvas_label_0 is None:
            self.canvas_label_0 = Label(self,
                                        text=solver_name_0,
                                        font='Helvetica 9 bold')
            self.canvas_label_0.grid(row=4,
                                     column=0,
                                     columnspan=3,
                                     padx=(4, 4),
                                     pady=(0, 5))

        if nr_solvers > 1:
            solver_name_1 = self.selected_solver_names[1]
            pil_image = Image.fromarray(self.visual_grids[solver_name_1])

            old_size = pil_image.size
            ratio = float(480) / max(old_size)
            new_size = tuple([int(x * ratio) for x in old_size])
            pil_image = pil_image.resize(new_size)
            scaled_image = Image.new("RGB", (480, 480))
            scaled_image.paste(pil_image, ((480 - new_size[0]) // 2,
                                           (480 - new_size[1]) // 2))

            self.photo_1 = ImageTk.PhotoImage(scaled_image)
            self.canvas_1.create_image(500, 500, image=self.photo_1, anchor=SE)

            if self.canvas_label_1 is None:
                self.canvas_label_1 = Label(self,
                                            text=solver_name_1,
                                            font='Helvetica 9 bold')
                self.canvas_label_1.grid(row=4,
                                         column=4,
                                         columnspan=3,
                                         padx=(4, 4),
                                         pady=(0, 5))

        if nr_solvers > 2:
            solver_name_2 = self.selected_solver_names[2]
            pil_image = Image.fromarray(self.visual_grids[solver_name_2])

            old_size = pil_image.size
            ratio = float(480) / max(old_size)
            new_size = tuple([int(x * ratio) for x in old_size])
            pil_image = pil_image.resize(new_size)
            scaled_image = Image.new("RGB", (480, 480))
            scaled_image.paste(pil_image, ((480 - new_size[0]) // 2,
                                           (480 - new_size[1]) // 2))

            self.photo_2 = ImageTk.PhotoImage(scaled_image)
            self.canvas_2.create_image(500, 500, image=self.photo_2, anchor=SE)

            if self.canvas_label_2 is None:
                self.canvas_label_2 = Label(self,
                                            text=solver_name_2,
                                            font='Helvetica 9 bold')
                self.canvas_label_2.grid(row=4,
                                         column=8,
                                         columnspan=3,
                                         padx=(4, 4),
                                         pady=(0, 5))
Beispiel #2
0
class AddMovie:
    """AddMovie class: Add Movie window.
        - See your movie list
        - See movie Info
        - Change scheduling status
        - Remove movie
        - Add Movie Manually
        - Use Api to add movies
    "window": it is a Tk() object (tkinter object) that is passed around so we do not need to create it every single
     time
     old_window: reference to the tk() object (Login window)
     If window=None create the Tk() object for the first time
     username: User's username -_-
     """
    def __init__(self, username, window, old_window=None):
        self.state = 1

        self.all_info = None
        self.all_movie_name = None
        self.username = username
        self.old_window = old_window

        self.window = window
        self.window.title("Add Movie")

        global cinemaDB_path
        cinemaDB_path = self.window.cinemaDB_path

        # Employee Options
        self.home = Button(self.window,
                           text="Home",
                           font=("Arial", 30),
                           bd=0,
                           bg="#CBFBB5",
                           command=self.goto_home)
        self.home.grid(row=0, column=0, padx=(15, 10))
        self.add_movie_btn = Button(self.window,
                                    text=" Movie ",
                                    font=("Arial", 30),
                                    bd=0,
                                    bg="#1F8BF3")
        self.add_movie_btn.grid(row=0, column=1, padx=(0, 10))
        self.cinema_schedule = Button(self.window,
                                      text=" Scheduling ",
                                      font=("Arial", 30),
                                      bd=0,
                                      bg="#CA65F5",
                                      command=self.goto_cinema_schedule)
        self.cinema_schedule.grid(row=0, column=2, padx=(0, 10))
        self.user = Button(self.window,
                           text=" User ",
                           font=("Comic Sans", 30),
                           bd=0,
                           bg="#BDC3C7",
                           command=self.goto_user)
        self.user.grid(row=0, column=3, padx=(0, 10))
        self.sign_out = Button(self.window,
                               text=" Sign Out",
                               font=("Comic Sans", 30),
                               bd=0,
                               bg="#FF916E",
                               command=self.goto_sign_out)
        self.sign_out.grid(row=0, column=4, padx=(0, 10))

        self.show_movie_btn = Button(self.window,
                                     text="Show Movies",
                                     font=("Arial", 20),
                                     command=self.show_movie,
                                     bg="#FFBABA",
                                     bd=1)
        self.show_movie_btn.place(x=300, y=90)

        self.manually_add_btn = Button(self.window,
                                       text="Add Movie",
                                       font=("Arial", 20),
                                       command=self.manually_add,
                                       bg="#E0E3FF",
                                       bd=1)
        self.manually_add_btn.place(x=500, y=90)

        # ------------Show-Movie-----------------------------------------------------------------------------------------------------------------
        # Table and Heading
        self.movie_list_lbl = LabelFrame(self.window,
                                         text="Current Movie List",
                                         font=("Arial", 15),
                                         fg="white",
                                         bg="#414141")
        self.table = Treeview(self.movie_list_lbl)
        self.create_table()
        self.scroll_y = Scrollbar(self.window,
                                  orient="vertical",
                                  command=self.table.yview)

        # Movie Info
        self.movie_info_btn = Button(self.window,
                                     text="Movie Info",
                                     font=("Arial", 15),
                                     bd=1,
                                     command=self.movie_info,
                                     bg="#4B9F7E")

        # Scheduling Status
        self.disable_movie_btn = Button(self.window,
                                        text="Change Scheduling Status",
                                        font=("Arial", 15),
                                        bd=1,
                                        command=self.change_movie_status,
                                        bg="#646BAF")
        # Remove Movie
        self.remove_movie_btn = Button(self.window,
                                       text="Remove Movie",
                                       font=("Arial", 15),
                                       bd=1,
                                       command=self.remove_movie,
                                       bg="#AF648D")

        # ------Add-Movie-----------------------------------------------------------------------------------------------

        # -- Add movie online ------------------------------------------------------------------------------------------

        # Search online
        self.search_online_lbl = LabelFrame(self.window,
                                            text="Search for a movie:",
                                            font=("Arial", 15),
                                            fg="white",
                                            bg="#2ECC71")
        self.search_online_input = Entry(self.search_online_lbl,
                                         width=18,
                                         font=("Arial", 20))
        self.search_online_input.grid()
        self.search_btn = Button(self.window,
                                 text="Search\nMovie",
                                 font=("Arial", 15),
                                 bd=1,
                                 command=self.search_name,
                                 bg="#AED6F1")
        # Movie options
        self.online_movie_lbl = LabelFrame(self.window,
                                           text="Choose the movie:",
                                           font=("Arial", 15),
                                           fg="white",
                                           bg="#2ECC71")
        self.online_movie_option = Combobox(self.online_movie_lbl,
                                            state="readonly",
                                            width=32,
                                            font=("Arial", 15))
        # Movie detail
        self.more_detail_btn = Button(self.window,
                                      text="Movie Info",
                                      font=("Arial", 15),
                                      bd=1,
                                      bg="#CACFD2",
                                      command=self.more_detail)
        # Add Movie
        self.add_movie_btn = Button(self.window,
                                    text="Add Movie",
                                    font=("Arial", 15),
                                    bd=1,
                                    bg="#EDBB99",
                                    command=self.add_online_movie)

        # -- Add Manually ----------------------------------------------------------------------------------------------
        # Movie Name
        self.movie_name_lbl = LabelFrame(self.window,
                                         text="Movie Name:",
                                         font=("Arial", 15),
                                         fg="white",
                                         bg="#414141")
        self.movie_name_input = Entry(self.movie_name_lbl,
                                      width=15,
                                      font=("Arial", 20))

        # Release Date
        self.movie_date_lbl = LabelFrame(self.window,
                                         text="Release Date:",
                                         font=("Arial", 15),
                                         fg="white",
                                         bg="#414141")
        self.movie_date_input = Entry(self.movie_date_lbl,
                                      width=10,
                                      font=("Arial", 20))
        self.date_format = Label(self.movie_date_lbl,
                                 text="Date format (YYYY-MM-DD)",
                                 font=("Arial", 13))

        # Run time
        self.movie_runtime_lbl = LabelFrame(self.window,
                                            text="Runtime:",
                                            font=("Arial", 15),
                                            fg="white",
                                            bg="#414141")
        self.movie_runtime_input = Entry(self.movie_runtime_lbl,
                                         width=10,
                                         font=("Arial", 20))
        self.runtime_format = Label(self.movie_runtime_lbl,
                                    text="minutes (10-300)",
                                    font=("Arial", 13))

        # Description
        self.movie_description_lbl = LabelFrame(self.window,
                                                text="Movie Description",
                                                font=("Arial", 15),
                                                fg="white",
                                                bg="#414141")
        self.description_input = scrolledtext.ScrolledText(
            self.movie_description_lbl,
            width=35,
            height=8,
            font=("Arial", 12),
            wrap="word")

        # Enter New Movie
        self.enter_btn = Button(self.window,
                                text="Enter Movie",
                                bd=1,
                                font=("Arial", 16),
                                command=self.enter_movie,
                                bg="#AF7D64")

        self.add_movie_widgets = [
            self.movie_name_lbl, self.movie_name_input, self.movie_date_lbl,
            self.movie_date_input, self.date_format, self.movie_runtime_lbl,
            self.movie_runtime_input, self.runtime_format,
            self.movie_description_lbl, self.description_input, self.enter_btn,
            self.search_online_lbl, self.search_btn, self.online_movie_lbl,
            self.online_movie_option, self.more_detail_btn, self.add_movie_btn
        ]

        self.widgets = [
            self.home, self.add_movie_btn, self.cinema_schedule, self.user,
            self.sign_out, self.show_movie_btn, self.manually_add_btn,
            self.movie_list_lbl, self.table, self.movie_info_btn,
            self.disable_movie_btn, self.remove_movie_btn, self.movie_list_lbl,
            self.table, self.movie_info_btn, self.disable_movie_btn,
            self.scroll_y, self.remove_movie_btn
        ] + self.add_movie_widgets

        self.show_movie()

    def search_name(self):
        """search_name() -->
        Give the possible movie option
        """
        if not self.search_online_input.get():
            messagebox.showwarning("Invalid", "Please enter first.")
            return None
        self.online_movie_list = get_movie_online(
            name=self.search_online_input.get())
        if self.online_movie_list:
            self.online_movie_lbl.place(x=550, y=230)
            self.online_movie_option.grid()
            self.online_movie_option["values"] = [
                i for i in self.online_movie_list.keys()
            ]
            self.online_movie_option.current(0)
            self.more_detail_btn.place(x=550, y=310)
            self.add_movie_btn.place(x=750, y=310)
        else:
            if self.online_movie_list != None:
                messagebox.showwarning("Invalid", "This movie does not exist")
            self.online_movie_lbl.place_forget()
            self.online_movie_option.grid_forget()
            self.more_detail_btn.place_forget()
            self.add_movie_btn.place_forget()

    def more_detail(self):
        """more_detail() --> get the movie info online and send it to the movie info window"""
        movie_id = self.online_movie_list[self.online_movie_option.get()]
        info = get_info_online(movie_id)
        if info:
            name = info["movie_name"]
            self.window.withdraw()
            MovieInfo(movie_name=name,
                      location=False,
                      online_info=info,
                      old_window=self.window)

    def manually_add(self):
        """manually_add() --> It enables you to add movie manually by your self
        state = 0  means that the window is currently showing show movie.
        Which implies I can change it to manually add movie
        """
        if self.state == 0:
            self.reset()
            self.movie_name_lbl.place(x=100, y=150)
            self.movie_name_input.grid()
            self.movie_name_input.focus()
            self.movie_date_lbl.place(x=100, y=220)
            self.movie_date_input.grid(row=0, column=0)
            self.date_format.grid(row=0, column=1, padx=10)
            self.movie_runtime_lbl.place(x=100, y=290)
            self.movie_runtime_input.grid(row=0, column=0)
            self.runtime_format.grid(row=0, column=1, padx=10)
            self.movie_description_lbl.place(x=100, y=360)
            self.description_input.grid()
            self.enter_btn.place(x=200, y=550)
            self.search_online_lbl.place(x=550, y=150)
            self.search_btn.place(x=850, y=150)

    def show_movie(self):
        """show_movie() --> It enables you to look at the  current movies in the database
        state = 1  means that the window is currently allowing you to manually add movie.
        Which implies I can change it to show movie
        """
        if self.state == 1:
            self.reset()
            self.movie_list_lbl.grid(row=1,
                                     column=0,
                                     columnspan=5,
                                     pady=(110, 15))
            self.table.grid()
            self.create_table(update=True)
            self.movie_info_btn.place(x=180, y=450)
            self.disable_movie_btn.place(x=325, y=450)
            self.remove_movie_btn.place(x=600, y=450)
            self.scroll_y.place(x=771, y=211)

    def reset(self):
        """
        state = 0  means that the window is currently showing show movie.
        state = 1  means that the window is currently allowing you to manually add movie.
        Remove widget in state 1 or state 2
        """
        if self.state == 0:

            self.table.grid_forget()
            self.movie_list_lbl.grid_forget()
            self.movie_info_btn.place_forget()
            self.disable_movie_btn.place_forget()
            self.remove_movie_btn.place_forget()
            self.scroll_y.place_forget()

            self.state = 1
        else:
            [widget.place_forget() for widget in self.add_movie_widgets]
            self.state = 0

    def remove_movie(self):
        """
        remove_movie() --> remove from movie from the database if the condition stated bellow holds
        -If there is no future booking for the movie, then you can remove it from the database
        -If you don't choose any tickets, you will get a message saying "Please choose a movie from the table"
        Technically changing the movie status to deleted rather than removing it permanently from the database
        """
        num = self.table.focus()
        id = self.table.item(num)["values"]
        if id:
            if is_valid_remove(movie_name=id[1]):
                if messagebox.askyesno(
                        "Confirm",
                        f"Are you sure you want to delete {id[1]}."):
                    remove_movie(movie_name=id[1])
                    self.create_table(update=True)
            else:
                messagebox.showerror(
                    "Invalid",
                    f"You can not delete this movie because, in the future, there are screenings of {id[1]} taking place."
                )
        else:
            messagebox.showinfo("Invalid",
                                "Please choose a movie from the table.")

    def change_movie_status(self):
        """change_movie_status() -->
        -Update the movie status to disable if the movie status is enable
        -Update the movie status to enable if the movie status is disable
        -Movie status being disabled means that you can not create a new future
         screening of this movie
        -If you don't choose any tickets, you will get a message saying "Please choose a movie from the table"

       """

        num = self.table.focus()
        id = self.table.item(num)["values"]
        if id:
            if id[4] == "Enabled":
                update_scheduling_status(movie_name=id[1], status="Disabled")
                messagebox.showinfo(
                    "Updated",
                    """Scheduling movie status has been updated. You will not see this movie when scheduling."""
                )
            else:
                update_scheduling_status(movie_name=id[1], status="Enabled")
                messagebox.showinfo(
                    "Updated",
                    """Scheduling movie status has been updated. You will now see this movie when scheduling."""
                )
            self.create_table(update=True)
        else:
            messagebox.showinfo("Invalid",
                                "Please choose a movie from the table.")

    def destroy_all(self):
        """ destroy_all() Destroys all the widget (Clears the window, so I can use the same window for adding new
         widgets) """
        [widget.destroy() for widget in self.widgets]

    def goto_home(self):
        """Takes you to the home window"""

        self.destroy_all()
        self.window.Home(username=self.username,
                         window=self.window,
                         old_window=self.old_window)

    def goto_cinema_schedule(self):
        """Takes you to the scheduling window"""

        self.destroy_all()
        self.window.Scheduling(username=self.username,
                               window=self.window,
                               old_window=self.old_window)

    def goto_user(self):
        """Takes you to the user window"""

        self.destroy_all()
        self.window.User(window=self.window,
                         old_window=self.old_window,
                         username=self.username,
                         customer=False)

    def goto_sign_out(self):
        """Sign out the user and takes you back to the Login menu."""

        self.window.destroy()
        self.old_window.deiconify()

    def enter_movie(self):
        """This is where I validate the movie and if all condtion holds, add the new movie to the database"""

        valid_detail = False
        while not valid_detail:
            # Check the validity of the movie name
            if len(self.movie_name_input.get()) == 0:
                self.movie_name_input.config(bg="#E96A6A")
                messagebox.showerror("Invalid", "Please enter the movie name.")
                self.movie_name_input.config(bg="white")
                break

            if self.movie_name_input.get().lower() in self.all_movie_name:
                self.movie_name_input.config(bg="#E96A6A")
                messagebox.showerror("Invalid", "Movie Already Exists.")
                self.movie_name_input.config(bg="white")
                break

            if not self.movie_date_input.get():
                self.movie_date_input.config(bg="#E96A6A")
                messagebox.showerror(
                    "Invalid",
                    "Please enter the date.\nEnter the date in this format:\n(YYYY-MM-DD)"
                )
                self.movie_date_input.config(bg="white")
                break

            # Check the validity of the date
            date = self.movie_date_input.get().split("-")

            if len(date) != 3:
                self.movie_date_input.config(bg="#E96A6A")
                messagebox.showerror(
                    "Invalid",
                    "Invalid date.\nWrite the date in this format:\n(YYYY-MM-DD)"
                )
                self.movie_date_input.config(bg="white")
                break
            elif len(date[0]) != 4 or len(date[1]) != 2 or len(date[2]) != 2:
                self.movie_date_input.config(bg="#E96A6A")
                messagebox.showerror(
                    "Invalid",
                    "Invalid date.\nWrite the date in this format:\n(YYYY-MM-DD)"
                )
                self.movie_date_input.config(bg="white")

                break
            elif not date[0].isnumeric() or not date[1].isnumeric(
            ) or not date[2].isnumeric():
                self.movie_date_input.config(bg="#E96A6A")
                messagebox.showerror(
                    "Invalid",
                    "Invalid date.\nWrite the date in this format:\n(YYYY-MM-DD)"
                )
                self.movie_date_input.config(bg="white")

                break
            date = [int(i) for i in date]  # change the date into int
            try:
                date = datetime.datetime(year=date[0],
                                         month=date[1],
                                         day=date[2])
                logical_start = datetime.datetime(year=1900, month=1, day=1)
                logical_end = datetime.datetime(year=2021, month=1, day=1)
                if date < logical_start:
                    self.movie_date_input.config(bg="#E96A6A")
                    messagebox.showerror(
                        "Invalid",
                        f"Invalid.\nThis movie released in year {date.year}, which is impossible."
                    )
                    self.movie_date_input.config(bg="white")

                    break
                elif date > logical_end:
                    self.movie_date_input.config(bg="#E96A6A")
                    messagebox.showerror(
                        "Invalid",
                        f"Invalid\nThis movie is released too far in the future. "
                    )
                    self.movie_date_input.config(bg="white")

                    break

            except ValueError:
                self.movie_date_input.config(bg="#E96A6A")

                messagebox.showerror(
                    "Invalid",
                    "Invalid date. This month or date does not exist.")
                self.movie_date_input.config(bg="white")

                break

            # Check the running time
            if not self.movie_runtime_input.get():
                self.movie_runtime_input.config(bg="#E96A6A")

                messagebox.showerror("Invalid",
                                     "Please enter the movie running time.")
                self.movie_runtime_input.config(bg="white")

                break
            elif not self.movie_runtime_input.get().isnumeric():
                self.movie_runtime_input.config(bg="#E96A6A")

                messagebox.showerror("Invalid", "Running time is a number.")
                self.movie_runtime_input.config(bg="white")

                break

            time = int(self.movie_runtime_input.get())

            if time < 0:
                self.movie_runtime_input.config(bg="#E96A6A")
                messagebox.showerror("Invalid", "Invalid Movie Running Time.")
                self.movie_runtime_input.config(bg="white")

                break
            elif time < 10:
                self.movie_runtime_input.config(bg="#E96A6A")
                messagebox.showerror(
                    "Invalid",
                    "Invalid.\nRunning Time of this movie is too short.")
                self.movie_runtime_input.config(bg="white")

                break
            elif time > 300:
                self.movie_runtime_input.config(bg="#E96A6A")

                messagebox.showerror(
                    "Invalid",
                    "Invalid.\nRunning Time of this movie is too long.")
                self.movie_runtime_input.config(bg="white")

                break

            # Check the description
            if len(self.description_input.get(1.0, END)) == 1:
                self.description_input.config(bg="#E96A6A")
                messagebox.showerror(
                    "Invalid", "Please enter the description of the movie.")
                self.description_input.config(bg="white")

                break
            elif len(self.description_input.get(1.0, END)) > 2000:
                self.description_input.config(bg="#E96A6A")
                messagebox.showerror("Invalid",
                                     "The movie description to long.")
                self.description_input.config(bg="white")

                break

            valid_detail = True  # While loop statement will be false then it will go to else
        else:
            name = self.movie_name_input.get()
            date = self.movie_date_input.get()
            runtime = self.movie_runtime_input.get()
            description = self.description_input.get(1.0, END)

            self.add_movie_db(name=name,
                              date=date,
                              runtime=runtime,
                              description=description)
            self.create_table(update=True)

    def add_online_movie(self):

        movie_id = self.online_movie_list[self.online_movie_option.get()]
        info = get_info_online(movie_id)
        if info:
            name = info["movie_name"]
            date = info["release_date"]
            runtime = info["runtime"]
            description = info["description"]
            if name in [i[1] for i in self.all_info]:
                messagebox.showwarning(
                    "Invalid", "This movie already exists in the database.")
            elif messagebox.askyesno(
                    "Question",
                    f"""Are you sure you want to add "{name}" in the database?"""
            ):
                self.add_movie_db(name=name,
                                  date=date,
                                  runtime=runtime,
                                  description=description)
                messagebox.showinfo("Complete", "Movie Added")
        else:
            pass

    def add_movie_db(self, name, date, runtime, description):
        """add_movie_db() --> add the movie inside the database"""
        global cinemaDB_path
        db = sqlite3.connect(cinemaDB_path)
        cursor = db.cursor()
        cursor.execute(
            """INSERT INTO movie(name, release_date, runtime, description, scheduling_status, deleted)
          VALUES(?,?,?,?,?,?)""",
            (name, date, runtime, description, "Enabled", "False"))
        messagebox.showinfo("Complete", "Movie added to the database.")
        db.commit()
        db.close()

    def create_table(self, update=False):
        """create_table(update) --> create the table with movie information
             if the argument update=False, then the table is created from scratch
             if the argument update=True, then if will only update the information on the table
             Using method get_movie_info() to get all the movie information
             """

        self.all_info = get_movie_info()
        self.all_movie_name = [info[1].lower() for info in self.all_info]
        # all_info structure:Movie ID Movie Name, Release Date, Runtime
        if not update:
            heading_name = [
                "Num", "Movie Name", "Release Date", "Runtime", "Scheduling"
            ]

            self.table["show"] = "headings"
            self.table["columns"] = list(range(len(heading_name)))

            for i in range(len(heading_name)):
                self.table.heading(i, text=heading_name[i])

            # I am adjusting the table structure
            self.table.column(0, anchor="center", width=80)
            self.table.column(1, anchor="center", width=200)
            self.table.column(2, anchor="center", width=150)
            self.table.column(3, anchor="center", width=70)
            self.table.column(4, anchor="center", width=100)

            for i in range(len(self.all_info)):
                self.table.insert(
                    "",
                    'end',
                    text="L1",
                    values=(i + 1, self.all_info[i][1], self.all_info[i][2],
                            self.all_info[i][3], self.all_info[i][4]))
        else:
            for i in self.table.get_children():
                self.table.delete(i)
            for i in range(len(self.all_info)):
                self.table.insert(
                    "",
                    'end',
                    text="L1",
                    values=(i + 1, self.all_info[i][1], self.all_info[i][2],
                            self.all_info[i][3], self.all_info[i][4]))

    def movie_info(self):
        """movie_info() --> open the movie info window for that choose movie
        If you don't choose any tickets, you will get a message saying "Please choose a movie from the table"
        """
        num = self.table.focus()
        id = self.table.item(num)["values"]
        if id:
            self.window.withdraw()
            MovieInfo(movie_name=id[1],
                      old_window=self.window,
                      location=self.window.location)
        else:
            messagebox.showinfo("Invalid",
                                "Please choose a movie from the table.")