import imgui
import glfw
import OpenGL.GL as gl
from imgui.integrations.glfw import GlfwRenderer
from PIL import ImageColor
from dataclasses import dataclass 

@dataclass
class Lecture:
    name: str
    points: float
    max_points: int

@dataclass
class Student:
    name: str
    jupyter_id: str
    project: str
    lectures: list

# Global Color Pallet
COLOR_BACKGROUND = tuple([e/255 for e in ImageColor.getcolor("#29132E","RGBA")])
COLOR_1 = tuple([e/255 for e in ImageColor.getcolor("#321450","RGBA")])
COLOR_2 = tuple([e/255 for e in ImageColor.getcolor("#860029","RGBA")])
COLOR_3 = tuple([e/255 for e in ImageColor.getcolor("#DE004E","RGBA")])
COLOR_TEXT = tuple([e/255 for e in ImageColor.getcolor("#F887FF","RGBA")])
COLOR_TEXT_PASSED = tuple([e/255 for e in ImageColor.getcolor("#1AFE49","RGBA")])
COLOR_TEXT_FAILED = tuple([e/255 for e in ImageColor.getcolor("#FF124F","RGBA")])

def impl_glfw_init(window_name="minimal ImGui/GLFW3 example", width=1280, height=720):
    if not glfw.init():
        print("Could not initialize OpenGL context")
        exit(1)

    # OS X supports only forward-compatible core profiles from 3.2
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

    glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, gl.GL_TRUE)

    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(int(width), int(height), window_name, None, None)
    glfw.make_context_current(window)

    if not window:
        glfw.terminate()
        print("Could not initialize Window")
        exit(1)

    return window


class GUI(object):
    def __init__(self):
        super().__init__()
        self.backgroundColor = COLOR_BACKGROUND 
        self.window = impl_glfw_init()
        gl.glClearColor(*self.backgroundColor)
        imgui.create_context()
        self.impl = GlfwRenderer(self.window)

        
        # Global GUI Setting
        win_w, win_h = glfw.get_window_size(self.window)
        fb_w, fb_h = glfw.get_framebuffer_size(self.window)
        font_scaling_factor = max(float(fb_w) / win_w, float(fb_h) / win_h) 
        font_size_in_pixels = 30
        io = imgui.get_io()
        io.fonts.add_font_from_file_ttf(
            "assets/MPLUSRounded1c-Regular.ttf", font_size_in_pixels
        )
        io.font_global_scale /= font_scaling_factor

        self.loop()
   
    def student_info(self, student: Student):

        # Window Position and Sizing
        io = imgui.get_io()
        imgui.set_next_window_size(io.display_size.x*0.3, io.display_size.y*0.3)
        imgui.set_next_window_position(io.display_size.x*0.7, io.display_size.y*0.05)
   
        # Student accumulated Info
        overall_points = sum([lecture.points for lecture in student.lectures])
        if overall_points.is_integer():
            overall_points = int(overall_points)
        overall_max = sum([lecture.max_points for lecture in student.lectures])

        with imgui.begin("Student Info", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
            if not student:
                imgui.text("No Student selected")
                return
            
            s = f"{student.name} {overall_points}/{overall_max}"
            imgui.text_colored(s, *COLOR_TEXT)
            imgui.text("Jupyter ID:")
            imgui.text_colored(student.jupyter_id.rjust(4+len(student.jupyter_id), " "), *COLOR_TEXT)
            
            imgui.separator()
            imgui.text("Project:")
            imgui.text_colored(student.project.rjust(4+len(student.project), " "), *COLOR_TEXT)
            imgui.text("Lectures:")
            for lecture in student.lectures:
                COLOR = COLOR_TEXT_PASSED if lecture.points >= lecture.max_points/3 else COLOR_TEXT_FAILED
                s = f"{lecture.name}: {lecture.points}/{lecture.max_points}"
                imgui.text_colored(s.rjust(4+len(s), " "), *COLOR)

    def table(self, students: list):

        # Window Position and Sizing
        io = imgui.get_io()
        imgui.set_next_window_size(max(min(io.display_size.x*0.2, 200), 120), io.display_size.y*0.9)
        imgui.set_next_window_position(io.display_size.y*0.01, io.display_size.y*0.05)

        # Boiler
        selected = [False for _ in range(len(students))]
        visible = True

        with imgui.begin("Student Table", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
            if not students:
                imgui.text("No Dataset selected")
                return 
    
            for i, student in enumerate(students):
                _, selected[i] = imgui.selectable(student, selected[i])

    def loop(self):

        phil = Student(
            "Phil Keier", "772fb04b24caa68fd38a05ec2a22e62b", "Geomapping",
            [Lecture("1. Tutorial 1", 28.5, 31), Lecture("2. Tutorial 2", 4.5, 15), Lecture("3. Extended Application", 18, 18)]
        )

        while not glfw.window_should_close(self.window):
            glfw.poll_events()
            self.impl.process_inputs()
            imgui.new_frame()
            
            self.table(["Phil Keier", "Nova Eib", "Katharina Walz"])
            self.student_info(phil)
            #imgui.show_test_window()

            imgui.render()

            gl.glClearColor(*self.backgroundColor)
            gl.glClear(gl.GL_COLOR_BUFFER_BIT)

            self.impl.render(imgui.get_draw_data())
            glfw.swap_buffers(self.window)

        self.impl.shutdown()
        glfw.terminate()


if __name__ == "__main__":

    gui = GUI()

