/*
 *	EasyScout Boy Scouts of America tracking software.
 *	http://www.easyscout.org/
 *
 *	Copyright (C) 2000 Conan C. Albrecht
 *	conan@warp.cx
 *
 *	This program is released under the GNU license so tech-savvy
 *	Boy Scouts and others can enhance the program for the use
 *	of all.  Please e-mail changes to my address above so I can
 *	reintegrate into the main program at http://www.easyscout.org/.
 *	This way, all users mutually benefit one another in the spirit of
 *	scouting.
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version 2
 *	of the License, or (at your option) any later version.
 *
 * 	Any and all changes to the program code must be documented with
 *  date, author name and e-mail, and a short description.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package cx.warp.scout.file;

import cx.warp.scout.lookup.*;
import cx.warp.scout.*;
import java.io.*;
import java.util.*;

/** Represents one scout */
public class FileScout extends FilePerson implements cx.warp.scout.Scout, Serializable {

	public static final long serialVersionUID = 2477221664686959973L;

	protected String registration = null;
	protected String contact = null;
	protected String emergency = null;
	protected String medicalnotes = null; 
	protected Vector positions = new Vector(3,3);
	protected Vector activities = new Vector(10, 10);
	protected Vector meritbadges = new Vector(12, 5);
	protected Vector ranks = null;
	protected String currentRank = "Pre-Scout";
	protected String requirementsVersion = null;
	protected String patrol = null;
	
	/** Creates a new scout */
	public FileScout(FileTroop troop, String requirementsVersion) throws DataException  {
		super(troop);
		ranks = XMLLookup.getRanks(requirementsVersion + ".xml");
		this.requirementsVersion = requirementsVersion;
	}//constructor
	
	/** Sets the scout's registration number */
	public void setRegistration(String reg)  throws DataException{
		this.registration = reg;
	  save();
	}
	
	/** Returns the scout's registration number */
	public String getRegistration() throws DataException {
		return registration;
	}
	
	/** Sets the scout's current patrol */
	public void setPatrol(String patrol) throws DataException {
		this.patrol = patrol;
	  save();
	}
	
	/** Returns the scout's current patrol */
	public String getPatrol() throws DataException       { 
		return patrol;
	}
	
	/** Returns the scout's current positions */
	public String getPosition()  throws DataException{
		StringBuffer current = new StringBuffer();
		for (int i = 0; i < positions.size(); i++)  {
	  	Position pos = (Position)positions.elementAt(i);
			if (pos.getEndDate() == null) {
				if (current.length() > 0) {
					current.append(", ");
				}//if
				current.append(pos.getName());
			}//if
		}//for
		return current.toString();
	}//getRank

	/** Sets the contact information */
	public void setContact(String contact)throws DataException {
		this.contact = contact;
		save();
	}//setCOntact
	
	
	/** Returns the contact information */
	public String getContact()throws DataException {
		return contact;
	}//getContact
	
	/** Sets the emergency contact information */
	public void setEmergency(String emergency)throws DataException {
		this.emergency = emergency;
		save();
	}//setEmergency
	
	/** Returns the emergency contact info */
	public String getEmergency()throws DataException {
		return emergency;
	}//getEmergency
	
	/** Sets the medical notes */
	public void setMedicalNotes(String medical)throws DataException {
		this.medicalnotes = medical;
		save();
	}//setMedicalNOtes
	
	/** Gets the medical notes */
	public String getMedicalNotes()throws DataException {
		return medicalnotes;
	}//getMedicalNotes
	
	
	/** Tests equality of scouts */
	public boolean equals(Object o){
		try {
			if (o instanceof Scout) {
				Scout scout = (Scout)o;
				return getName().equals(scout.getName());
			}//if
		}catch (DataException e) {
			// do nothing, just return false
		}//try
		return false;
	}//equals
	
	/////////////////////////////////
	///   Merit Badge accessors   ///
	/////////////////////////////////

	/** Creates a new merit badge */
	public MeritBadge createMeritBadge() throws DataException {
		MeritBadge badge = new FileMeritBadge(this);
		meritbadges.addElement(badge);
	  save();
		return badge;
	}//createMeritBadge

	/** Sorts merit badges by date */
	public void sortMeritBadges() throws DataException {
	  save();
	}//sort

	/** Returns the merit badge with the given id */
	public MeritBadge getMeritBadge(String id) throws DataException {
		for (int i = 0; i < meritbadges.size(); i++) {
			MeritBadge badge = (MeritBadge)meritbadges.elementAt(i);
			if (badge.getID().equals(id)) {
				return badge;
			}//if
		}//for i
		return null;
	}//getMeritBaddge
	
	/** Returns an Enumeration of all MeritBadges earned by a scout, sorted by date */
	public Enumeration getMeritBadges() throws DataException {
		return meritbadges.elements();
	}//getMeritBadge
	
	/** Removes a merit badge from this scout's list */
	public MeritBadge removeMeritBadge(String id) throws DataException {
		for (int i = 0; i < meritbadges.size(); i++) {
			MeritBadge badge = (MeritBadge)meritbadges.elementAt(i);
			if (badge.getID().equals(id)) {
				meritbadges.removeElementAt(i);
			  save();
				return badge;
			}//if
		}//for i
		return null;
	}//removeMeritBadge
	
	/////////////////////////////////
	///   Activities accessors    ///
	/////////////////////////////////

	/** Creates a new activity */
	public Activity createActivity() throws DataException {
		Activity activity = new FileActivity(this);
		activities.addElement(activity);
	  save();
		return activity;
	}//createActivity
	
	/** Sorts Activity by date */
	public void sortActivities() throws DataException {
	}//sortActivity

	/** Returns the Activity with the given id */
	public Activity getActivity(String id)throws DataException {
		for (int i = 0 ; i < activities.size(); i++) {
			Activity activity = (Activity)activities.elementAt(i);
			if (activity.getID().equals(id)) {
				return activity;
			}//if
		}//for i
		return null;
	}//getActivity
	
	/** Returns an Enumeration of all Activities earned by a scout, sorted by date */
	public Enumeration getActivities()throws DataException {
		return activities.elements();
	}//getActivities
	
	/** Removes an Activity from this scout's list */
	public Activity removeActivity(String id) throws DataException {
		for (int i = 0 ; i < activities.size(); i++) {
			Activity activity = (Activity)activities.elementAt(i);
			if (activity.getID().equals(id)) {
				activities.removeElementAt(i);
			  save();
				return activity;
			}//if
		}//for i
		return null;
	}//removeActivity


	/////////////////////////////////
	///   Leadership accessors    ///
	/////////////////////////////////

	/** Creates a new leadership position */
	public Position createPosition()throws DataException {
		Position position = new FilePosition(this);
		positions.addElement(position);
	  save();
		return position;
	}//createPosition
	
	/** Sorts Position by date */
	public void sortPositions() throws DataException {
	}//sortPositions

	/** Returns the Position with the given id */
	public Position getPosition(String id)throws DataException {
		for (int i = 0; i < positions.size(); i++) {
			Position position = (Position)positions.elementAt(i);
			if (position.getID().equals(id)) {
				return position;
			}//if
		}//for i
		return null;
	}//getPosition
	
	/** Returns an Enumeration of all Position earned by a scout, sorted by date */
	public Enumeration getPositions()throws DataException {
		return positions.elements();
	}//getPositions
	
	/** Removes an Position from this scout's list */
	public Position removePosition(String id) throws DataException {
		for (int i = 0; i < positions.size(); i++) {
			Position position = (Position)positions.elementAt(i);
			if (position.getID().equals(id)) {
				positions.removeElementAt(i);
			  save();
				return position;
			}//if
		}//for i
		return null;
	}//removePosition
	
	/////////////////////////////
	///   Advancement ranks   ///
	/////////////////////////////

	/** Sets the current rank of the scout */
	public void setRank(String rank)throws DataException {
		this.currentRank = rank;
	}//setRank

	/** Returns the scout's current rank */
	public Rank getRank() throws DataException {
		return getRank(currentRank);
	}//getRank

	/** Returns the scout's next rank */
	public Rank getNextRank() throws DataException {
		for (int i = 0; i < ranks.size(); i++) {
			Rank rank = (Rank)ranks.elementAt(i);
			if (rank.getName().equals(currentRank) && i < ranks.size() - 1) {
				return (Rank)ranks.elementAt(i + 1);
			}//if
		}//for i
		return null;
	}//getNextRank
	
	/** Returns the given rank */
	public Rank getRank(String name) throws DataException {
		for (int i = 0; i < ranks.size(); i++) {
			Rank rank = (Rank)ranks.elementAt(i);
			if (rank.getName().equals(name)) {
				return rank;
			}//if
		}//for
		return null;
	}//getRank
	
	/** Returns the given rank number */
	public Rank getRank(int index)  throws DataException {
		if (index >= 0 && index < ranks.size()) {
			return (Rank)ranks.elementAt(index);
		}//if
		return null;
	}//getRank

	/** Returns the index of the given rank */
	public int getRankIndex(String name) throws DataException {
		for (int i = 0; i < ranks.size(); i++) {
			Rank rank = (Rank)ranks.elementAt(i);
			if (rank.getName().equals(name)) {
				return i;
			}//if
		}//for
		return -1;
	}//getRankIndex
	
	/** Returns an Enumeration of Ranks for this scout */
	public Enumeration getRanks() throws DataException {
		return ranks.elements();
	}//getRanks
	
	/** Returns the ranks vector reference.  Not exported in the interface */
	public Vector getRanksVector() {
		return ranks;
	}//getRanksVector
	
	/** Writes my information to an XML buffer */
	public void writeXML(PrintWriter out) throws DataException {
		out.println("  <Scout id=\"" + Utils.xml(getID()) + "\">");
		// my information
		super.writeXML(out);
		out.println("    <Registration>" + Utils.xml(registration) + "</Registration>");
		out.println("    <Patrol>" + Utils.xml(patrol) + "</Patrol>");
		out.println("    <CurrentRank>" + Utils.xml(currentRank) + "</CurrentRank>");
		out.println("    <RequirementsVersion>" + Utils.xml(requirementsVersion) + "</RequirementsVersion>");
		out.println("    <Contact>" + Utils.xml(contact) + "</Contact>");
		out.println("    <Emergency>" + Utils.xml(emergency) + "</Emergency>");
		out.println("    <MedicalNotes>" + Utils.xml(medicalnotes) + "</MedicalNotes>");
		
		// merit badges
		for (Enumeration enum = getMeritBadges(); enum.hasMoreElements(); ) {
			FileMeritBadge badge = (FileMeritBadge)enum.nextElement();
			badge.writeXML(out);
		}//for
		
		// leadership
		for (Enumeration enum = getPositions(); enum.hasMoreElements(); ) {
			FilePosition position = (FilePosition)enum.nextElement();
			position.writeXML(out);
		}//for
		
		// activities
		for (Enumeration enum = getActivities(); enum.hasMoreElements(); ) {
			FileActivity act = (FileActivity)enum.nextElement();
			act.writeXML(out);
		}//for
		
		// ranks
		for (Enumeration enum = getRanks(); enum.hasMoreElements(); ) {
			FileRankObject rank = (FileRankObject)enum.nextElement();
			rank.writeXML(out);
		}//for
		
		out.println("  </Scout>");
	}//writeXML
	
	/** Returns the requirements version */
	public String getRequirementsVersion() {
		return requirementsVersion;
	}//getRequirementsVersion
	
}//Scout
