import java.util.*;


public class WorkerTest{
	public static void main(String[] args){
		Worker[] ws = new Worker[4];
		ws[0] = new HourlyWorker("Mike", 15);
		ws[1] = new HourlyWorker("John", 20);
		ws[2] = new SalariedWorker("Bill", 19);
		ws[3] = new SalariedWorker("Steven", 25);
		
		for(int i=0;i<ws.length;i++){
			ws[i].computePay(45-5*i);
		}
		
		System.out.println("Order by name: ");
		Arrays.sort(ws);		
		for(int i=0;i<ws.length;i++){
			System.out.println(ws[i]);
		}
		System.out.println();
		
		
		System.out.println("Order by salary rate: ");
		Arrays.sort(ws, new SalaryRateComparator());		
		for(int i=0;i<ws.length;i++){
			System.out.println(ws[i]);
		}
		System.out.println();
		
		System.out.println("Order by total salary: ");
		Arrays.sort(ws, new TotalSalaryComparator());		
		for(int i=0;i<ws.length;i++){
			System.out.println(ws[i]);
		}
		System.out.println();
	}
}


//class Worker, the superclass 
abstract class Worker implements Comparable{
	String name;
	double salaryRate;
	double totalSalary;
	
	public Worker(String n, double s){
		name = n;
		salaryRate = s;
		totalSalary = 0;
	}
	
	public int compareTo(Object w){
		String n1 = ((Worker)w).name;
		return name.compareTo(n1);
	}
	
	abstract void computePay(int hours);	
}

//subclass HourlyWorker
class HourlyWorker extends Worker{
	
	public HourlyWorker(String n, double s){
		super(n,s);	
	}
	
	
	void computePay(int hours){
		if(hours<0){
			System.err.println("Work hour has to be greater than zero.");	
			return;
		}
		if(hours<=40)
			totalSalary += hours*salaryRate;
		else 
			totalSalary += 2*hours*salaryRate;
	}
	
	public String toString(){
		return "HourlyWorker "+name+", salary rate is "+salaryRate+", got total salary "+totalSalary;
	}
}


//subclass SalariedWorker
class SalariedWorker extends Worker{
	
	public SalariedWorker(String n, double s){
		super(n,s);	
	}
	
	void computePay(int hours){
		totalSalary += 40*salaryRate;
	}
	
	public String toString(){
		return "SalariedWorker "+name+", salary rate is "+salaryRate+", got total salary "+totalSalary;
	}
}

//comparators
class SalaryRateComparator implements Comparator{
	
	public int compare(Object o1, Object o2){
		double r1 = ((Worker)o1).salaryRate;
		double r2 = ((Worker)o2).salaryRate;
		if(r1<r2)
			return -1;
		else if(r1>r2)
			return 1;
		else
			return 0;
	}
}


class TotalSalaryComparator implements Comparator{
	
	public int compare(Object o1, Object o2){
		double r1 = ((Worker)o1).totalSalary;
		double r2 = ((Worker)o2).totalSalary;
		if(r1<r2)
			return -1;
		else if(r1>r2)
			return 1;
		else
			return 0;
	}
}