#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 28 04:20:14 2025

@author: giuseppesergioli
"""

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 27 15:48:48 2025

@author: giuseppesergioli

This script implements a simple GUI to compute the Productivity Index (PI) 
of each Scholar and the Department Productivity Index (DPI), 
using threshold values for both the current rank and the next (upper) rank.
"""

import tkinter as tk
from tkinter import ttk

class ProductivityIndexApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Productivity Index Calculation")
        self.geometry("650x500")

        # Configure the style
        style = ttk.Style(self)
        style.theme_use("clam")
        self.configure(bg="#F5F5F5")

        style.configure("Custom.TFrame", background="#F5F5F5")
        style.configure(
            "Custom.TLabel",
            background="#F5F5F5",
            font=("Helvetica", 11),
            foreground="#333333"
        )
        style.configure(
            "Title.TLabel",
            background="#F5F5F5",
            font=("Helvetica", 16, "bold"),
            foreground="#2B547E"
        )
        style.configure(
            "Custom.TLabelframe",
            background="#F5F5F5",
            relief="groove"
        )
        style.configure(
            "Custom.TLabelframe.Label",
            font=("Helvetica", 11, "bold"),
            foreground="#2B547E"
        )
        style.configure(
            "Accent.TButton",
            font=("Helvetica", 10, "bold"),
            foreground="#FFFFFF",
            background="#2B547E",
            padding=6
        )

        # Initial frame
        self.initial_frame = ttk.Frame(self, padding=20, style="Custom.TFrame")
        self.initial_frame.pack(fill="both", expand=True)

        # Main title
        ttk.Label(
            self.initial_frame,
            text="Productivity Index (PI) Calculation",
            style="Title.TLabel"
        ).pack(pady=(0,10))

        # Ask how many scholars
        ttk.Label(
            self.initial_frame,
            text="How many Scholars does your Department have?",
            style="Custom.TLabel"
        ).pack(pady=5)

        self.num_scholars_var = tk.StringVar()
        self.entry_num_scholars = ttk.Entry(
            self.initial_frame,
            textvariable=self.num_scholars_var,
            width=5
        )
        self.entry_num_scholars.pack(pady=5)

        btn_confirm = ttk.Button(
            self.initial_frame,
            text="Confirm",
            command=self.create_scholar_fields,
            style="Accent.TButton"
        )
        btn_confirm.pack(pady=10)

    def create_scholar_fields(self):
        """
        Dynamically create input fields for the Scholars 
        based on the number entered by the user.
        """
        try:
            n_scholars = int(self.num_scholars_var.get())
        except ValueError:
            return

        # Hide the initial frame
        self.initial_frame.pack_forget()

        # Main frame (for the instructions and "Calculate" button)
        self.main_frame = ttk.Frame(self, padding=10, style="Custom.TFrame")
        self.main_frame.pack(fill="both", expand=True)

        ttk.Label(
            self.main_frame,
            text="Insert threshold values (Scholar) and threshold values (upper rank):",
            style="Custom.TLabel"
        ).pack(pady=(0,10))

        # ---------------------------
        # SCROLLABLE STRUCTURE
        # ---------------------------
        self.canvas = tk.Canvas(self.main_frame, bg="#F5F5F5", highlightthickness=0)
        self.canvas.pack(side="left", fill="both", expand=True)

        self.scrollbar = ttk.Scrollbar(self.main_frame, orient="vertical", command=self.canvas.yview)
        self.scrollbar.pack(side="right", fill="y")

        self.canvas.configure(yscrollcommand=self.scrollbar.set)

        # Create a frame inside the canvas
        self.scrollable_frame = ttk.Frame(self.canvas, style="Custom.TFrame")
        
        # Place the scrollable_frame in a window within the canvas
        self.canvas_frame = self.canvas.create_window(
            (0, 0),
            window=self.scrollable_frame,
            anchor="nw"
        )

        # Bind the <Configure> event of the scrollable_frame
        self.scrollable_frame.bind("<Configure>", self.on_frame_configure)

        # List to store the Scholars' data
        self.scholars_data = []

        for i in range(n_scholars):
            scholar_frame = ttk.LabelFrame(
                self.scrollable_frame,
                text=f"Scholar {i+1}",
                padding=10,
                style="Custom.TLabelframe"
            )
            scholar_frame.pack(fill="x", pady=5, padx=5)

            ttk.Label(
                scholar_frame,
                text="Threshold values (Scholar):",
                style="Custom.TLabel"
            ).grid(row=0, column=0, columnspan=3, sticky="w")
            
            vs1 = tk.StringVar()
            vs2 = tk.StringVar()
            vs3 = tk.StringVar()
            
            ttk.Entry(scholar_frame, textvariable=vs1, width=10).grid(row=1, column=0, padx=5, pady=2)
            ttk.Entry(scholar_frame, textvariable=vs2, width=10).grid(row=1, column=1, padx=5, pady=2)
            ttk.Entry(scholar_frame, textvariable=vs3, width=10).grid(row=1, column=2, padx=5, pady=2)

            ttk.Label(
                scholar_frame,
                text="Threshold values (upper rank):",
                style="Custom.TLabel"
            ).grid(row=2, column=0, columnspan=3, sticky="w")
            
            va1 = tk.StringVar()
            va2 = tk.StringVar()
            va3 = tk.StringVar()
            
            ttk.Entry(scholar_frame, textvariable=va1, width=10).grid(row=3, column=0, padx=5, pady=2)
            ttk.Entry(scholar_frame, textvariable=va2, width=10).grid(row=3, column=1, padx=5, pady=2)
            ttk.Entry(scholar_frame, textvariable=va3, width=10).grid(row=3, column=2, padx=5, pady=2)

            self.scholars_data.append(((vs1, vs2, vs3), (va1, va2, va3)))

        # "Calculate" button (placed outside the canvas, so it stays visible)
        btn_calculate = ttk.Button(
            self.main_frame,
            text="Calculate Indices",
            command=self.calculate_results,
            style="Accent.TButton"
        )
        btn_calculate.pack(pady=15)

        # Frame for results
        self.results_frame = ttk.Frame(self.main_frame, padding=10, style="Custom.TFrame")
        self.results_frame.pack(fill="both", expand=True)

    def on_frame_configure(self, event):
        """
        Update the scroll region of the canvas to include the entire area 
        of the inner scrollable_frame, making the scrollbar functional.
        """
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))
        
        # Optionally match the canvas width to the scrollable_frame
        canvas_width = self.scrollable_frame.winfo_reqwidth()
        self.canvas.itemconfig(self.canvas_frame, width=canvas_width)

    def calculate_results(self):
        """
        Calculate and display the Productivity Index (PI) for each Scholar 
        and the Department Productivity Index (DPI).
        """
        # Clear previous results
        for widget in self.results_frame.winfo_children():
            widget.destroy()

        scholar_pis = []

        lbl_header_1 = ttk.Label(self.results_frame, text="Scholar", style="Custom.TLabel")
        lbl_header_2 = ttk.Label(self.results_frame, text="Scholar PI", style="Custom.TLabel")

        lbl_header_1.grid(row=0, column=0, padx=5, pady=5, sticky="w")
        lbl_header_2.grid(row=0, column=1, padx=5, pady=5, sticky="w")

        # Compute the PI for each Scholar
        for i, data in enumerate(self.scholars_data):
            (vs1, vs2, vs3), (va1, va2, va3) = data

            try:
                v1 = float(vs1.get()) if vs1.get() else 0.0
                v2 = float(vs2.get()) if vs2.get() else 0.0
                v3 = float(vs3.get()) if vs3.get() else 0.0

                a1 = float(va1.get()) if va1.get() else 0.0
                a2 = float(va2.get()) if va2.get() else 0.0
                a3 = float(va3.get()) if va3.get() else 0.0

                # Avoid division by zero
                a1 = a1 if a1 != 0 else 1
                a2 = a2 if a2 != 0 else 1
                a3 = a3 if a3 != 0 else 1

                pi = ((v1 / a1) + (v2 / a2) + (v3 / a3)) / 3
            except ValueError:
                pi = 0.0

            scholar_pis.append(pi)

            lbl_name = ttk.Label(self.results_frame, text=f"Scholar {i+1}", style="Custom.TLabel")
            lbl_name.grid(row=i+1, column=0, padx=5, pady=2, sticky="w")

            lbl_pi = ttk.Label(self.results_frame, text=f"{pi:.2f}", style="Custom.TLabel")
            lbl_pi.grid(row=i+1, column=1, padx=5, pady=2, sticky="w")

            # Color based on PI value
            if pi < 1:
                lbl_pi.config(foreground="red")
            else:
                lbl_pi.config(foreground="green")

        # Calculate the Department Productivity Index (DPI)
        if len(scholar_pis) > 0:
            dpi = sum(scholar_pis) / len(scholar_pis)
        else:
            dpi = 0.0

        lbl_dpi = ttk.Label(
            self.results_frame,
            text=f"Department Productivity Index (DPI): {dpi:.2f}",
            font=("Helvetica", 14, "bold")
        )
        lbl_dpi.grid(row=len(self.scholars_data)+1, column=0, columnspan=2, pady=10)

        # Color DPI based on its value
        if dpi < 1:
            lbl_dpi.config(foreground="red")
        else:
            lbl_dpi.config(foreground="green")


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