import tkinter
import tkinter.ttk

import tkinter.messagebox
import tkinter.scrolledtext
from tkinter import *

###class starts
class HDinfo():
    # Attributes:
    #     institutionName– a non-public string to store the HD institution name of the applicant.
    #     programmeTitle – a non-public string to store the HD programme name of the applicant.
    #     gpa – a non-public double to store the HD GPA of the applicant.
    #     expectedGradeYear– a non-public int to store the Expected HD Graduation Year of the applicant.

    # Methods:
    #     init – initialize all attributes in HDinfo object. It is a Parameterized constructor.
    #     str – return a string containing the Attributes of HDinfo object. This method is used to display in Summary ScrolledText.

    #constructor __init__
    def __init__(self, institutionName="",programmeTitle="", gpa="",expectedGraYear="" ):
        pass

    # __str__ method
    def __str__():
        print("helloworld string method")
        pass


class Applicant():
    # Attributes:
    #     name – a non-public string to store the name of the applicant.
    #     email – a non-public string to store the email of the applicant.
    #     gender – a non-public string to store the gender of the applicant.
    #     dateOfBirth – a non-public string to store the applicant date of birth.
    #     applyDegreeProgramme – a non-public string to store the applicant selected
    #     degree programme
    #     hdInfo– a non-public HDinfo(self-defined class) to store the applicant Higher
    #     Diploma information

    # Methods:
    #     init – initialize all attributes in Applicant object. It is a Parameterized constructor.
    #     setPeronalInfo – setter method to set the name, email, gender, dateOfBirth, applyDegreeProgrmme into the Applicant object.
    #     setHDinfo – setter method to set the HDinfo object into the Applicant object.
    #     str – return a string containing the Attributes of this Applicant. This function is used to display in Summary ScrolledText.

    #constructor __init__
    def __init__( self, name="", email="",gender="", dateOfBirth="",applyDegreeProgramme="",hdInfo = HDinfo() ):
        self.name = name
        self.email = email
        self.gender = gender
        self.dateOfBirth = dateOfBirth
        self.applyDegreeProgramme = applyDegreeProgramme

        pass

    # Set Personal Info Method
    def setPeronalInfo(self, name, email, gender,dateOfBirth, applyDegreeProgramme ):
        self.name = name
        self.email = email
        self.gender = gender
        self.dateOfBirth = dateOfBirth
        self.applyDegreeProgramme = applyDegreeProgramme

    # Set HD Info Method
    def setHDInfo(self, hd):
        pass

    # __str__ method
    def __str__(self):
        return """
Applicant Name: Ben
Applicant Email: ben@vtc.edu.hk
Gender: Male
Date of Birth: 2004/03/13
Apply Degree Programme: Bachelor of Science in Computer Science and AI
Higher Diploma Information:
Institution Name: IVE(Chai Wan)
Programme Title: HD in AI and Smart Technology
GPA: 3.8
Expected Graduation Year: 2025
""".strip()


applicant = Applicant()
###class ends


###Tkinter starts


#Parent class for Personal and HighDiploma
class ApplicationPage(tkinter.Frame):
    """Base class for managed pages. Provides methods to be overridden by subclasses."""

    def __init__(self, master):
        super().__init__(master)

    def is_complete(self) -> bool:
        """Check if the current page is complete."""
        return True


class Personal(ApplicationPage):


    def __init__(self, master):
        super().__init__(master)

        frm_base = tkinter.Frame(self)
        frm_base.pack(fill=tkinter.BOTH, expand=True)

        frm_title = tkinter.Frame(frm_base)
        frm_title.pack(fill=tkinter.BOTH)

        lbl_title = tkinter.Label(frm_title, text="Personal Infromation", font=("bold", 15))
        lbl_title.pack(anchor=tkinter.W)

        ###
        #Write your coding here
        row = 0
        frm_content = tkinter.Frame(frm_base)
        frm_content.pack(fill=tkinter.BOTH)
        frm_content.grid_columnconfigure(2,weight=1)

        lbl_name = tkinter.Label(frm_content, text="Applicant Name" , anchor="w", justify="left", width=20)
        lbl_name.grid(row=row, column=0)
        self.ent_applicant_name = tkinter.Entry(frm_content)
        self.ent_applicant_name.insert(0, "Ben")
        self.ent_applicant_name.grid(row=row, column=1, columnspan=2, sticky="nsew", pady=(10,10), padx=(10,10))
        row += 1

        lbl_name = tkinter.Label(frm_content, text="Applicant Email" , anchor="w", justify="left", width=20)
        lbl_name.grid(row=row, column=0)
        self.ent_applicant_email = tkinter.Entry(frm_content)
        self.ent_applicant_email.insert(0, "ben@vtc.edu.hk")
        self.ent_applicant_email.grid(row=row, column=1, columnspan=2, sticky="nsew", pady=(10,10), padx=(10,10))
        row += 1

        # ask genden with radio button, male or female
        self.gender_select = tkinter.StringVar(value="Male")

        lbl_gender = tkinter.Label(frm_content, text="Gender" , anchor="w", justify="left", width=20)
        lbl_gender.grid(row=row, column=0)

        rad_male = tkinter.Radiobutton(frm_content, variable=self.gender_select,text="Male",value="Male")
        rad_male.grid(row=row, column=1)

        rad_female = tkinter.Radiobutton(frm_content, variable=self.gender_select,text="Female",value="Female")
        rad_female.grid(row=row, column=2)

        row += 1

        lbl_name = tkinter.Label(frm_content, text="Date of Birth" , anchor="w", justify="left", width=20)
        lbl_name.grid(row=row, column=0)
        self.ent_applicant_DOB = tkinter.Entry(frm_content)
        self.ent_applicant_DOB.insert(0, "2004/03/13")
        self.ent_applicant_DOB.grid(row=row, column=1, columnspan=2, sticky="nsew", pady=(10,10), padx=(10,10))
        row += 1

        lbl_name = tkinter.Label(frm_content, text="Apply Programme" , anchor="w", justify="left", width=20)
        lbl_name.grid(row=row, column=0)

        # combobox for apply programme
        lst_programme=["Bachelor of Science in Cybersecurity" , "Bachelor of Science in Computer Science and AI"]
        self.applicant_programme = tkinter.ttk.Combobox(frm_content, textvariable=lst_programme, values=lst_programme, )
        self.applicant_programme.current(0)
        self.applicant_programme.grid(row=row, column=1, columnspan=2, sticky="nsew", pady=(10,10), padx=(10,10))
        row += 1



        ###


    def is_complete(self):

        ###
        #Write your coding here

        entry_valid = True
        if self.ent_applicant_name.get() == "":
            entry_valid = False
        if self.ent_applicant_email.get() == "":
            entry_valid = False
        if self.ent_applicant_DOB.get() == "":
            entry_valid = False

        if (entry_valid):
          applicant.setPeronalInfo(
              self.ent_applicant_name.get(),
              self.ent_applicant_email.get(),
              self.gender_select.get(),
              self.ent_applicant_DOB.get(),
              self.applicant_programme.get()
          )
          return True

        return False


class HighDiploma(ApplicationPage):
    def __init__(self, master):
        super().__init__(master)

        frm_base = tkinter.Frame(self)
        frm_base.pack(fill=tkinter.BOTH, expand=True)

        frm_title = tkinter.Frame(frm_base)
        frm_title.pack(fill=tkinter.BOTH)

        lbl_title = tkinter.Label(frm_title, text="Higher Diploma Information", font=("bold", 15))
        lbl_title.pack(anchor=tkinter.W)

        ###
        #Write your coding here
        row = 0
        frm_content = tkinter.Frame(frm_base)
        frm_content.pack(fill=tkinter.BOTH)
        frm_content.grid_columnconfigure(2,weight=1)

        lbl_name = tkinter.Label(frm_content, text="Institution Name", anchor="w", justify="left", width=20)
        lbl_name.grid(row=row, column=0)
        self.ent_institution_name = tkinter.Entry(frm_content)
        self.ent_institution_name.insert(0, "IVE(Chai Wan)")
        self.ent_institution_name.grid(row=row, column=1, columnspan=2, sticky="nsew", pady=(10,10), padx=(10,10))
        row += 1

        lbl_name = tkinter.Label(frm_content, text="Programme Title", anchor="w", justify="left", width=20)
        lbl_name.grid(row=row, column=0)
        self.ent_programme_title = tkinter.Entry(frm_content)
        self.ent_programme_title.insert(0, "HD in AI and Smart Technology")
        self.ent_programme_title.grid(row=row, column=1, columnspan=2, sticky="nsew", pady=(10,10), padx=(10,10))
        row += 1

        lbl_name = tkinter.Label(frm_content, text="GPA", anchor="w", justify="left", width=20)
        lbl_name.grid(row=row, column=0)
        self.ent_GPA = tkinter.Entry(frm_content)
        self.ent_GPA.insert(0, "3.8")
        self.ent_GPA.grid(row=row, column=1, columnspan=2, sticky="nsew", pady=(10,10), padx=(10,10))
        row += 1

        lbl_name = tkinter.Label(frm_content, text="Expected Graduation Year", anchor="w", justify="left", width=20)
        lbl_name.grid(row=row, column=0)
        self.expected_grad_year = tkinter.Entry(frm_content)
        self.expected_grad_year.insert(0, "2025")
        self.expected_grad_year.grid(row=row, column=1, columnspan=2, sticky="nsew", pady=(10,10), padx=(10,10))
        row += 1
        ###

    def is_complete(self):
        ###
        #Write your coding here

        entry_valid = True
        if self.ent_institution_name.get() == "":
            entry_valid = False
        if self.ent_programme_title.get() == "":
            entry_valid = False
        if self.ent_GPA.get() == "":
            entry_valid = False

        hd = HDinfo(
            self.ent_institution_name.get(),
            self.ent_programme_title.get(),
            self.ent_GPA.get(),
            self.expected_grad_year.get()
        )

        if (entry_valid):
          applicant.setHDInfo(hd)
          return True

        return False



class Result(ApplicationPage):
    def __init__(self, master):
        super().__init__(master)

        frm_base = tkinter.Frame(self)
        frm_base.pack(fill=tkinter.BOTH, expand=True)

        frm_title = tkinter.Frame(frm_base)
        frm_title.pack(fill=tkinter.BOTH)

        lbl_title = tkinter.Label(frm_base, text="Summary", font=("bold", 15))
        lbl_title.pack(anchor=tkinter.W)

        #Summary Output
        ###
        #Write your coding here
        row = 0
        frm_content = tkinter.Frame(frm_base)
        frm_content.pack(fill=tkinter.BOTH)
        frm_content.grid_columnconfigure(2,weight=1)

        # textbox for summary
        self.txt_summary = tkinter.Text(frm_content, height=12)
        self.txt_summary.grid(row=row, column=1, columnspan=2, sticky="nsew", pady=(1,1), padx=(1,1))
        row += 1

        # right justify button  with text "show"
        btn_show = tkinter.Button(frm_base, text="Show", anchor=tkinter.E)
        btn_show.pack(side=tkinter.RIGHT)

        # tkinter bind button click
        btn_show.bind("<Button-1>", self.show)

        ###

    def show(self, _  ): #Show Button method
        ###
        #Write your coding here
        self.txt_summary.insert(tkinter.INSERT, str(applicant))
        ###


class Application(tkinter.Tk):
    def __init__(self):
        super().__init__()

        # Configure GUI
        self.title("Undergraduate Application Form")
        self.geometry("450x300")

        # Content Frame
        frm_content = tkinter.Frame(self, relief=tkinter.RIDGE, borderwidth=1)
        frm_content.pack(fill=tkinter.BOTH, expand=True)
        frm_content.rowconfigure(0, weight=1)
        frm_content.columnconfigure(0, weight=1)



        # Application Pages
        self.__frames: list[ApplicationPage] = [
            Personal(frm_content),
            HighDiploma(frm_content),
            Result(frm_content),
        ]
        for i in self.__frames:
            i.grid(row=0, column=0, sticky=tkinter.NSEW)
        self.__current_page = 0
        self.__frames[self.__current_page].tkraise()

        # Bottom Frame
        frm_button = tkinter.Frame(self, padx=4, pady=4)
        frm_button.pack(side=tkinter.BOTTOM, fill=tkinter.X)

        # Next Button
        self.btn_next = tkinter.Button(frm_button, text="Next", command=self.next_page)
        self.btn_next.pack(side=tkinter.RIGHT)

        # Quit Button
        self.btn_quit = tkinter.Button(frm_button, text="Quit", command=self.destroy)

    def next_page(self):
        # Check if the current page is complete
        if not self.__frames[self.__current_page].is_complete():
            tkinter.messagebox.showinfo(
                "Information", "Please fill the missing fields."
            )
            return

        # Navigate to next page
        self.__current_page += 1
        self.__frames[self.__current_page].tkraise()

        # If we reached the last page, replace the next button with quit button
        if self.__current_page + 1 == len(self.__frames):
            self.btn_next.pack_forget()
            self.btn_quit.pack(side=tkinter.RIGHT)
###Tkinter ends


if __name__ == "__main__":
    app = Application()
    app.mainloop()
