import java.util.Scanner;

/**
 * A program to demonstrat various bits of inheritance.
 *
 * @author Mark Young (A00000000)
 */
public class MorePeopleTests {

    public static void main(String[] args) {
        introduceSelf();

        // create objects to work with
        System.out.println("Creating Person p (Pat) and Student s (Sam).");
        Person p = new Person("Pat");
        Student s = new Student("Sam");

        // work with those objects
        showNormalInheritance(p, s);
        showReplacedInheritance(p, s);
        showRevisedInheritance(p, s);
        showPolymorphism(p, s);
    }

    private static void introduceSelf() {
        System.out.println("\n\n"
                + "More Inheritance Testing using Person and Student\n"
                + "-------------------------------------------------\n\n"
                + "Inheritance is when one class 'extends' another.\n"
                + "In this example Student extends Person.\n"
                + "In this program, we look at overriding methods.");
        pause();
    }

    private static void showNormalInheritance(Person p, Student s) {
        // public methods
        System.out.println("\nStudent objects inherit public Person methods.");
        System.out.println("\nPerson p has publicPersonMethod:");
        p.publicPersonMethod();
        System.out.println("\nStudent s has publicPersonMethod:");
        s.publicPersonMethod();
        pause();

        // private methods
        System.out.println("private Person methods can only be called "
                + "from inside the Person class.");
        System.out.println("\nPerson p has public callingPrivatePersonMethod:");
        p.callingPrivatePersonMethod();
        System.out.println("\nStudent s inherits callingPrivatePersonMethod, "
                + "and *it* can call\nprivatePersonMethod:");
        s.callingPrivatePersonMethod();
        pause();
    }

    private static void showReplacedInheritance(Person p, Student s) {
        System.out.println("Inherited methods can be replaced.");
        System.out.println("\nPerson p has a replacedMethod:");
        p.replacedMethod();
        System.out.println("\nStudent s has a replacedMethod, too:");
        s.replacedMethod();
        System.out.println("\nThe replaced method should have @Override "
                + "in the child class.");
        pause();
    }

    private static void showRevisedInheritance(Person p, Student s) {
        System.out.println("Even tho' a method is replaced, "
                + "the child class can still call the\nparent's version "
                + "by using super.");
        System.out.println("\nPerson p has a revisedMethod:");
        p.revisedMethod();
        System.out.println("\nStudent s has a revisedMethod, too:");
        s.revisedMethod();
        System.out.println("\nThe revised method should have @Override "
                + "in the child class.");
        pause();
    }

    private static void showPolymorphism(Person p, Person s) {
        System.out.println("Methods expecting a Person can accept a Student.");
        System.out.println("\nPerson p is a " + p.getClass().getName());
        System.out.println("\nPerson s is a " + s.getClass().getName());
        pause();

        System.out.println("Of course it can still only do Person-y things.");
        System.out.println("\nPerson p's name is " + p.getName());
        System.out.println("\nPerson s's name is " + s.getName());
        pause();

        System.out.println("Unless you use instanceof.");
        if (p instanceof Student perStu) {
            System.out.println("\tPerson p is a Student!");
            System.out.println("\t\t" + perStu.getName() + "'s A-# is " 
                    + perStu.A_NUMBER);
        } else {
            System.out.println("\tPerson p is NOT a Student!");
        }
        if (s instanceof Student perStu) {
            System.out.println("\tPerson s is a Student!");
            System.out.println("\t\t" + perStu.getName() + "'s A-# is " 
                    + perStu.A_NUMBER);
        } else {
            System.out.println("\tPerson s is NOT a Student!");
        }
        pause();
    }

    public static void pause() {
        Scanner kbd = new Scanner(System.in);
        System.out.print("\nPress enter...");
        kbd.nextLine();
        System.out.println("\n\n\n\n");
    }

}
