import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;


public class GraduateStudent extends Student implements Iterable<String>
{
	private ArrayList<String> supervisors;
	
	public GraduateStudent(String name, List<String> supervisors)
	{
		super(name);
		// question says list of supervisors is NOT a composition
		//   so shallow copy is ok
		this.supervisors = new ArrayList<String>(supervisors);
	}
	
	public void setSupervisors(List<String> supervisors) throws Exception
	{
		ArrayList<String> s = new ArrayList<String>(supervisors);
		if(s.size() > 0)
		{
			this.supervisors = s;
		}
		else
		{
			throw new Exception("list of supervisors has length 0");
		}
	}
	
	public String[] getSupervisors()
	{
		String[] s = new String[this.supervisors.size()];
		return this.supervisors.toArray(s);
	}
	
	public Iterator<String> iterator()
	{
		return this.supervisors.iterator();
	}
	
	public List<String> getSortedSupervisors()
	{
		List<String> s = new ArrayList<String>(this.supervisors);
		Collections.sort(s);
		return s;
	}
	
	@Override
	public boolean equals(Object object)
	{
		boolean eq = super.equals(object);
		if(eq)
		{
			// the Student parts are equal; need to check the supervisors
			GraduateStudent other = (GraduateStudent) object;
			/*
			 * There is more than one correct way to implement this part.
			 * Here is the simplest way using getSortedSupervisors.
			 */
			if(!this.getSortedSupervisors().equals(other.getSortedSupervisors()))
			{
				eq = false;
			}
			/*
			 * This way also works without needing to sort.
			 * 
			 * if (this.supervisors.size() != other.supervisors.size() ||
			 *     !this.supervisors.containsAll(other.supervisors))
			 * {
			 *     eq = false;
			 * }
			 */
		}
		return eq;
	}
	
	@Override
	public String toString()
	{
		String studentPart = super.toString();
		String gradPart = "\t" + this.supervisors.size();
		return studentPart + gradPart;
	}
	
	public static void main(String[] args)
	{
		ArrayList<String> supervisors = new ArrayList<String>();
		supervisors.add("Mary");
		supervisors.add("Andy");
		supervisors.add("Ron");
		
		GraduateStudent g = new GraduateStudent("Bart", supervisors);
		
		// print grad student
		System.out.println(g.toString());
		
		// print supervisors using iterator
		for(String sname : g)
			System.out.print(sname + "\t");
		System.out.println("");
		
		// print supervisors using String[]
		String[] s = g.getSupervisors();
		for(String sname : s)
			System.out.print(sname + "\t");
		System.out.println("");
		
		// print sorted list of supervisors
		List<String> slist = g.getSortedSupervisors();
		System.out.println(slist);
		
		// test equality
		GraduateStudent h = new GraduateStudent(g.getName(), g.getSortedSupervisors());
		System.out.println("g equals h : " + g.equals(h));
		System.out.println("g equals null : " + g.equals(null));
		
		// add a supervisor
		slist.add("Carol");
		try
		{
			g.setSupervisors(slist);
		}
		catch(Exception x)
		{
		}
		System.out.println(g.getSortedSupervisors());
		
		// test equality again
		System.out.println("g equals h : " + g.equals(h));
	}
}
