//*******************************************************************
//
//   Firm2.java          In Text          Application
//
//   Authors:  Lewis and Loftus
//
//   Classes:  Firm2
//             Staff
//             Staff_Member
//             Volunteer
//             Employee
//             Executive
//             Hourly
//
//*******************************************************************


//-------------------------------------------------------------------
//
//  Class Firm2 contains the driver of a program that manages a
//  group of employees.  Demonstrates polymorphism.
//
//  Methods:
//
//     public static void main (String[] args)
//
//-------------------------------------------------------------------

class Firm2 {

   //===========================================================
   //  Creates a staff and pays them.
   //===========================================================
   public static void main (String[] args) {

      Staff personnel = new Staff();

      personnel.payday();

   }  // method main

}  // class Firm2

//-------------------------------------------------------------------
//
//  Class Staff represents the entire staff of the firm.
//
//  Constructors:
//
//     public Staff()
//
//  Methods:
//
//     public void payday()
//
//-------------------------------------------------------------------

class Staff {

   Staff_Member[] staff_list = new Staff_Member[6];

   //===========================================================
   //  Sets up the list of staff members.
   //===========================================================
   public Staff() {

      staff_list[0] = new Executive ("Sam", "123 Main Line",
         "555-0469", "123-45-6789", 1923.07);
      staff_list[1] = new Employee ("Carla", "456 Off Line",
         "555-0101", "987-65-4321", 846.15);
      staff_list[2] = new Employee ("Woody", "789 Off Rocker",
         "555-0000", "010-20-3040", 769.23);
      staff_list[3] = new Hourly ("Diane", "678 Fifth Ave.",
         "555-0690", "958-47-3625", 8.55);
      staff_list[4] = new Volunteer ("Norm", "987 Suds Blvd.",
         "555-8374");
      staff_list[5] = new Volunteer ("Cliff", "321 Duds Lane",
         "555-7282");

      ((Executive)staff_list[0]).award_bonus (5000);
      ((Hourly)staff_list[3]).add_hours (40);

   }  // constructor Staff

   //===========================================================
   //  Pays all staff members.
   //===========================================================
   public void payday() {

      double amount;

      for (int count=0; count < staff_list.length; count++) {
         staff_list[count].print();
         amount = staff_list[count].pay();
         if (amount == 0.0)
            System.out.println ("Thanks!");
         else
            System.out.println ("Paid: " + amount);
         System.out.println ("**********************");
      }

   }  // method payday

}  // class Staff

//-------------------------------------------------------------------
//
//  Class Staff_Member represents a generic staff member.
//
//  Constructors:
//
//     public Staff_Member (String emp_name, String emp_address,
//            String emp_phone)
//
//  Methods:
//
//     public double pay()
//     public void print()
//
//-------------------------------------------------------------------

class Staff_Member {

   protected String name;
   protected String address;
   protected String phone_number;

   //===========================================================
   //  Sets up a staff member using the specified information.
   //===========================================================
   public Staff_Member (String emp_name, String emp_address,
          String emp_phone) {

      name = emp_name;
      address = emp_address;
      phone_number = emp_phone;

   }  // constructor Staff_Member

   //===========================================================
   //  Establishes a pay method so that all staff members can
   //  get paid.  This method is overridden in derived classes.
   //===========================================================
   public double pay() {
      return 0.0;
   }  // method pay

   //===========================================================
   //  Prints the basic information for any staff member.
   //===========================================================
   public void print() {
      System.out.println ("Name: " + name);
      System.out.println ("Address: " + address);
      System.out.println ("Phone: " + phone_number);
   }  // method print

}  // class Staff_Member

//-------------------------------------------------------------------
//
//  Class Volunteer represents an unpaid staff member.
//
//  Constructors:
//
//     public Volunteer (String emp_name, String emp_address,
//            String emp_phone)
//
//  Methods:
//
//     public double pay()
//
//-------------------------------------------------------------------

class Volunteer extends Staff_Member {

   //===========================================================
   //  Sets up a volunteer using the specified information.
   //===========================================================
   public Volunteer (String emp_name, String emp_address,
          String emp_phone) {

      super (emp_name, emp_address, emp_phone);

   }  // constructor Volunteer

   //===========================================================
   //  Explicitly returns a zero pay value for a volunteer.
   //===========================================================
   public double pay() {
      return 0.0;
   }  // method pay

}  // class Volunteer

//-------------------------------------------------------------------
//
//  Class Employee represents a paid staff member.
//
//  Constructors:
//
//     public Employee (String emp_name, String emp_address,
//            String emp_phone, String emp_ssnumber, double emp_rate)
//
//  Methods:
//
//     public double pay ()
//     public void print ()
//
//-------------------------------------------------------------------

class Employee extends Staff_Member {

   protected String social_security_number;
   protected double pay_rate;

   //===========================================================
   //  Sets up an employee using the specified information.
   //===========================================================
   public Employee (String emp_name, String emp_address,
          String emp_phone, String emp_ssnumber, double emp_rate) {

      super (emp_name, emp_address, emp_phone);
      social_security_number = emp_ssnumber;
      pay_rate = emp_rate;

   }  // constructor Employee

   //===========================================================
   //  Returns the pay rate for this employee.  Overrides the
   //  parent's pay method.
   //===========================================================
   public double pay () {
      return pay_rate;
   }  // method pay

   //===========================================================
   //  Prints information about this employee, using the
   //  print method from the parent class.
   //===========================================================
   public void print () {
      super.print();
      System.out.println ("SS number: " + social_security_number);
      System.out.println ("Pay rate: " + pay_rate);
   }  // method print

}  // class Employee

//-------------------------------------------------------------------
//
//  Class Executive represents one executive, which is an employee
//  that can possibly earn a bonus.
//
//  Constructors:
//
//     public Executive (String exec_name, String exec_address,
//                       String exec_phone, String exec_ssnumber,
//                       double exec_rate)
//
//  Methods:
//
//     public void award_bonus (double exec_bonus)
//     public double pay ()
//     public void print ()
//
//-------------------------------------------------------------------

class Executive extends Employee {

   private double bonus;

   //===========================================================
   //  Sets up an executive using the specified information.
   //===========================================================
   public Executive (String exec_name, String exec_address,
                     String exec_phone, String exec_ssnumber,
                     double exec_rate) {

      super (exec_name, exec_address, exec_phone, exec_ssnumber,
             exec_rate);

      bonus = 0;  // bonus yet to be awarded

   }  // constructor Executive

   //===========================================================
   //  Awards the specified bonus to this executive.
   //===========================================================
   public void award_bonus (double exec_bonus) {
      bonus = exec_bonus;
   }  // method award_bonus

   //===========================================================
   //  Computes and returns the pay for this executive, which
   //  includes a possible bonus.
   //===========================================================
   public double pay () {
      double paycheck = super.pay() + bonus;
      bonus = 0;
      return paycheck;
   }  // method pay

   //===========================================================
   //  Prints information about this executive, using the
   //  print method from the parent class.
   //===========================================================
   public void print () {
      super.print();
      System.out.println ("Current bonus: " + bonus);
   }  // method print

}  // class Executive

//-------------------------------------------------------------------
//
//  Class Hourly represents one hourly employee, which tracks the
//  number of hours worked during the current pay period.
//
//  Constructors:
//
//     public Hourly (String hr_name, String hr_address,
//            String hr_phone, String hr_ssnumber, double hr_rate)
//
//  Methods:
//
//     public void add_hours (int more_hours)
//     public double pay ()
//     public void print ()
//
//-------------------------------------------------------------------

class Hourly extends Employee {

   private int hours_worked;

   //===========================================================
   //  Sets up an hourly employee using the specified
   //  information.
   //===========================================================
   public Hourly (String hr_name, String hr_address,
          String hr_phone, String hr_ssnumber, double hr_rate) {

      super (hr_name, hr_address, hr_phone, hr_ssnumber, hr_rate);
      hours_worked = 0;

   }  // constructor Hourly

   //===========================================================
   //  Adds the specified number of hours to this employee's
   //  accumulated hours.
   //===========================================================
   public void add_hours (int more_hours) {
      hours_worked += more_hours;
   }  // method add_hours

   //===========================================================
   //  Computes and returns the pay for this hourly employee.
   //===========================================================
   public double pay () {
      return pay_rate * hours_worked;
   }  // method pay

   //===========================================================
   //  Prints information about this hourly employee, using
   //  the print method from the parent class.
   //===========================================================
   public void print () {
      super.print();
      System.out.println ("Current hours: " + hours_worked);
   }  // method print

}  // class Hourly


