/**
 * Lab 2: Person, Student, and Staff - Inheritance Hierarchy
 * PT821 - Object-Oriented Programming
 * State University of Zanzibar (SUZA)
 *
 * LEARNING OBJECTIVES:
 * - Design a multi-level class hierarchy
 * - Use protected access modifier for inherited attributes
 * - Apply method overriding with @Override annotation
 * - Use super keyword to call parent constructor and methods
 * - Understand polymorphic behavior with different subclasses
 *
 * INSTRUCTIONS:
 * Complete the following exercises step by step.
 * Follow the TODO comments and implement the required functionality.
 */

// ============================================================
// PART A: The Person Class (Superclass)
// ============================================================

/*
 * TODO 1: Create a class called "Person" with:
 *
 * Private instance variables:
 *   - name (String)
 *   - address (String)
 *
 * Constructors:
 *   - Person(String name, String address)
 *
 * Public methods:
 *   - getName(), getAddress(), setAddress(String address)
 *   - toString() - returns "Person[name=?, address=?]"
 *
 * NOTE: There is no setter for name - a person's name is fixed once set.
 */

// Write your Person class here:


// ============================================================
// PART B: The Student Class (Subclass of Person)
// ============================================================

/*
 * TODO 2: Create a class called "Student" that extends Person with:
 *
 * Private instance variables:
 *   - program (String, e.g., "BITA", "BCS")
 *   - year (int, e.g., 1, 2, 3)
 *   - fee (double)
 *
 * Constructor:
 *   - Student(String name, String address, String program, int year, double fee)
 *     Must call super(name, address)
 *
 * Public methods:
 *   - getProgram(), setProgram(String program)
 *   - getYear(), setYear(int year)
 *   - getFee(), setFee(double fee)
 *   - @Override toString() - returns
 *     "Student[Person[name=?, address=?], program=?, year=?, fee=?]"
 *     Hint: Use super.toString() for the Person part
 */

// Write your Student class here:


// ============================================================
// PART C: The Staff Class (Subclass of Person)
// ============================================================

/*
 * TODO 3: Create a class called "Staff" that extends Person with:
 *
 * Private instance variables:
 *   - department (String, e.g., "SCCMS", "SNSE")
 *   - salary (double)
 *
 * Constructor:
 *   - Staff(String name, String address, String department, double salary)
 *     Must call super(name, address)
 *
 * Public methods:
 *   - getDepartment(), setDepartment(String department)
 *   - getSalary(), setSalary(double salary)
 *   - @Override toString() - returns
 *     "Staff[Person[name=?, address=?], department=?, salary=?]"
 *     Hint: Use super.toString() for the Person part
 */

// Write your Staff class here:


// ============================================================
// PART D: Test Driver
// ============================================================

public class Lab2_PersonStudentStaff {
    public static void main(String[] args) {
        System.out.println("==============================================");
        System.out.println("  Lab 2: Person, Student, and Staff Hierarchy");
        System.out.println("==============================================\n");

        // ----- Section 1: Creating Objects -----
        System.out.println("--- Section 1: Creating Objects ---");

        // TODO 4: Create a Person object
        // Person p1 = new Person("Amina Hassan", "Stonetown, Zanzibar");
        // System.out.println(p1);

        // TODO 5: Create two Student objects
        // Student s1 = new Student("Juma Ali", "Chwaka, Zanzibar", "BITA", 2, 1500000);
        // Student s2 = new Student("Fatma Omar", "Mbweni, Zanzibar", "BCS", 1, 1800000);
        // System.out.println(s1);
        // System.out.println(s2);

        // TODO 6: Create a Staff object
        // Staff staff1 = new Staff("Dr. Khalid Salum", "Vuga, Zanzibar", "SCCMS", 3500000);
        // System.out.println(staff1);

        // ----- Section 2: Inheritance in Action -----
        System.out.println("\n--- Section 2: Inheritance in Action ---");

        // TODO 7: Show that Student and Staff inherit Person's methods
        // System.out.println("Student name: " + s1.getName());     // Inherited from Person
        // System.out.println("Student address: " + s1.getAddress()); // Inherited from Person
        // System.out.println("Student program: " + s1.getProgram()); // Student's own method
        //
        // System.out.println("\nStaff name: " + staff1.getName());      // Inherited from Person
        // System.out.println("Staff department: " + staff1.getDepartment()); // Staff's own method

        // TODO 8: Modify inherited attributes through setters
        // s1.setAddress("Fumba, Zanzibar");  // Inherited setter
        // System.out.println("\nAfter address change: " + s1);

        // ----- Section 3: Polymorphism -----
        System.out.println("\n--- Section 3: Polymorphism ---");

        // TODO 9: Demonstrate polymorphism using Person references
        // Person[] people = {
        //     new Person("Bakari Juma", "Mwanakwerekwe, Zanzibar"),
        //     new Student("Zainab Moh'd", "Kiembe Samaki, Zanzibar", "BITA", 3, 1500000),
        //     new Student("Hassan Said", "Amani, Zanzibar", "BCS", 1, 1800000),
        //     new Staff("Prof. Mwanaisha Ali", "Mazizini, Zanzibar", "SCCMS", 4500000)
        // };
        //
        // System.out.println("All people at SUZA:");
        // for (Person p : people) {
        //     System.out.println("  " + p);  // Which toString() is called for each?
        // }

        // ----- Section 4: instanceof and Type Checking -----
        System.out.println("\n--- Section 4: instanceof and Type Checking ---");

        // TODO 10: Use instanceof to identify types in the array
        // int studentCount = 0;
        // int staffCount = 0;
        //
        // for (Person p : people) {
        //     if (p instanceof Student) {
        //         Student s = (Student) p;
        //         System.out.println(s.getName() + " is a Student in " + s.getProgram() + " Year " + s.getYear());
        //         studentCount++;
        //     } else if (p instanceof Staff) {
        //         Staff st = (Staff) p;
        //         System.out.println(st.getName() + " is Staff in " + st.getDepartment());
        //         staffCount++;
        //     } else {
        //         System.out.println(p.getName() + " is a Person (visitor/other)");
        //     }
        // }
        //
        // System.out.println("\nSummary: " + studentCount + " students, " + staffCount + " staff members");

        System.out.println("\n==============================================");
        System.out.println("  End of Lab 2");
        System.out.println("==============================================");
    }
}

/*
 * EXPECTED OUTPUT (after completing all TODOs):
 *
 * ==============================================
 *   Lab 2: Person, Student, and Staff Hierarchy
 * ==============================================
 *
 * --- Section 1: Creating Objects ---
 * Person[name=Amina Hassan, address=Stonetown, Zanzibar]
 * Student[Person[name=Juma Ali, address=Chwaka, Zanzibar], program=BITA, year=2, fee=1500000.0]
 * Student[Person[name=Fatma Omar, address=Mbweni, Zanzibar], program=BCS, year=1, fee=1800000.0]
 * Staff[Person[name=Dr. Khalid Salum, address=Vuga, Zanzibar], department=SCCMS, salary=3500000.0]
 *
 * --- Section 2: Inheritance in Action ---
 * Student name: Juma Ali
 * Student address: Chwaka, Zanzibar
 * Student program: BITA
 *
 * Staff name: Dr. Khalid Salum
 * Staff department: SCCMS
 *
 * After address change: Student[Person[name=Juma Ali, address=Fumba, Zanzibar], program=BITA, year=2, fee=1500000.0]
 *
 * --- Section 3: Polymorphism ---
 * All people at SUZA:
 *   Person[name=Bakari Juma, address=Mwanakwerekwe, Zanzibar]
 *   Student[Person[name=Zainab Moh'd, address=Kiembe Samaki, Zanzibar], program=BITA, year=3, fee=1500000.0]
 *   Student[Person[name=Hassan Said, address=Amani, Zanzibar], program=BCS, year=1, fee=1800000.0]
 *   Staff[Person[name=Prof. Mwanaisha Ali, address=Mazizini, Zanzibar], department=SCCMS, salary=4500000.0]
 *
 * --- Section 4: instanceof and Type Checking ---
 * Bakari Juma is a Person (visitor/other)
 * Zainab Moh'd is a Student in BITA Year 3
 * Hassan Said is a Student in BCS Year 1
 * Prof. Mwanaisha Ali is Staff in SCCMS
 *
 * Summary: 2 students, 1 staff members
 *
 * QUESTIONS TO ANSWER:
 * 1. Why do we call super(name, address) in the Student and Staff constructors?
 * 2. What would happen if Person had no constructor with parameters?
 * 3. In Section 3, which toString() method is called for each object in the array?
 * 4. Why must we check "instanceof Student" BEFORE "instanceof Person"?
 * 5. Can a Staff object be assigned to a Student reference? Why or why not?
 *
 * SUBMISSION:
 * - Complete all TODO sections
 * - Answer all questions above in comments
 * - Submit the completed .java file
 */
