/*
 *	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.*;
import java.io.*;
import java.util.*;
import javax.servlet.http.*;

/** The master object for a troop.  All scouts are attached to one of these objects */
public class FileTroop implements cx.warp.scout.Troop, java.io.Serializable, java.util.Comparator {

	public static final long serialVersionUID = 6171925013868162579L;
	public static TimedHashtable recent = new TimedHashtable();
	
	/** The vector of scouts in this troop */
	protected Hashtable scoutsHash = new Hashtable();
	protected Vector scouts = new Vector();
	
	/** The vector of leaders in this troop */
	protected Vector leaders = new Vector();

	protected String name = null;
	protected String password = null;
	protected String readonly = null;
	protected String owner = null;
	protected String email = null;
	protected Date created = new Date();
	
	/** Creates a new troop object */
	public FileTroop(String name, String password) {
		this.name = name;
		this.password = password;
	}//constructor
	
	/** Saves this troop */
	public void save() throws DataException {
		FileDataGate.save(this);
	}//save
	
	/** Sets the troop name */
	public void setName(String name) throws DataException {
		this.name = name;
		FileDataGate.save(this);
	}//setName
	
	/** Returns the troop name */
	public String getName() throws DataException  {
		return name;
	}//getName
	
	/** Returns the date the troop was created on */
	public Date getCreated() throws DataException {
		return created;
	}//getCreated
	
	/** Returns the troop name, which is its unique id */
	public String getID() throws DataException {
		return name;
	}//getID
	
	/** Sets the troop password */
	public void setPassword(String pass)  throws DataException {
		this.password = pass;
		FileDataGate.save(this);
	}//setPassword
	
	/** Verifies whether the given password matches the troop password */
	public boolean verifyPassword(String pass) throws DataException {
		return (pass.equals(password));
	}//verifyPassword
	
	/** Returns the troop password */
	public String getPassword() throws DataException {
		return password;
	}//getPassword
	
	/** Sets the troop read-only password */
	public void setReadPassword(String pass) throws DataException {
		this.readonly = pass;
		FileDataGate.save(this);
	}//setReadPassword
	
	/** Returns the troop read-only password */
	public String getReadPassword() throws DataException {
		return (readonly == null ? "" : readonly);
	}//getReadPassword
	
	
	/** Sets the owner name */
	public void setOwner(String owner) throws DataException {
		this.owner = owner;
		FileDataGate.save(this);
	}//setOwner
	
	/** Gets the owner name */
	public String getOwner() throws DataException {
		return owner;
	}//getOwner
	
	/** Sets the owner e-mail */
	public void setEmail(String email) throws DataException {
		this.email = email;
		FileDataGate.save(this);
	}//setEmail
	
	/** Returns the owner e-mail */
	public String getEmail() throws DataException {
		return email;
	}//getEmail
	
	/** Sorts the scout vector */
	protected synchronized void sortScouts() throws DataException  {
		Sort.quicksort(scouts, this);
		FileDataGate.save(this);
	}//sort
	
	/** Compares one scout to another */
	public int compare(Object o1, Object o2) {
		try {
			if (o1 instanceof Scout && o2 instanceof Scout) {
				return ((Scout)o1).getFullName().compareTo(((Scout)o2).getFullName());
			}else{   // default to a consistent ordering by class name
				return o1.getClass().toString().compareTo(o2.getClass().toString());
			}//if
		}catch (Exception e) {
			return -1;
		}//if
	}//compare
	
	/** Tests whether this comparator is equals to another comparator */
	public boolean equals(Object obj) {
		try {
			if (obj instanceof Troop) {
				if (((Troop)obj).getName().equals(this.getName())) {
					return true;
				}//if
			}//if
		}catch (DataException e) {
			e.printStackTrace();
			// do nothing, just let it return false
		}//if
		return false;
	}//equals
	
	/////////////////////////
	///   Scout methods   ///
	/////////////////////////
	
	/** Creates a new scout */
	public synchronized Scout createScout(String version) throws DataException {
		Scout scout = new FileScout(this, version);
		scoutsHash.put(scout.getID(), scout);
		scouts.addElement(scout);
		save();
		return scout;
	}//createScout
	
	/** Returns the scout with the given id */
	public Scout getScout(String id)  throws DataException {
		if (id == null) {
			return null;
		}else{
			return (Scout)scoutsHash.get(id);
		}//if
	}//getScout
	
	/** Returns an enumeration of the scouts in this troop */
	public Enumeration getScouts()  throws DataException {
		return scouts.elements();
	}//getScouts
	
	/** Returns an enumeration of this scouts in this troop, sorted by the given getter method. */
	public Enumeration getScouts(String getterMethod) throws DataException  {
		return getScouts();
	}//getScouts

	/** Returns the number of scouts in the troop */
	public int getScoutCount() throws DataException {
		return scouts.size();
	}//getScoutCount
	
	/** Deletes a scout from the list */
	public boolean deleteScout(String id) throws DataException {
		if (id != null) {
			for (int i = 0; i < scouts.size(); i++) {
				Scout scout = (Scout)scouts.elementAt(i);
				if (id.equals(scout.getID())) {
					scouts.removeElementAt(i);
					scoutsHash.remove(id);
					save();
					return true;
				}//if
			}//for
		}//if
		return false;
	}//deleteScout
	
	//////////////////////////
	///   Leader methods   ///
	//////////////////////////
	
	/** Creates a new leader */
	public synchronized Leader createLeader() throws DataException {
		Leader leader = new FileLeader(this);
		leaders.addElement(leader);
		save();
		return leader;
	}//createLeader
	
	/** Returns the leader with the given id */
	public Leader getLeader(String id) throws DataException {
		if (id != null) {
			for (Enumeration enum = leaders.elements(); enum.hasMoreElements(); ) {
				Leader leader = (Leader)enum.nextElement();
				if (id.equals(leader.getID())) {
					return leader;
				}//if
			}//for
		}//if
		return null;
	}//getLeader
	
	/** Returns an enumeration of the leaders in this troop */
	public Enumeration getLeaders() throws DataException {
		return leaders.elements();
	}//getLeaders
	
	/** Returns the number of leaders in the troop */
	public int getLeaderCount() throws DataException {
		return leaders.size();
	}//getLeaderCount

	/** Deletes a leader from the list */
	public synchronized boolean deleteLeader(String id) throws DataException {
		if (id != null) {
			for (int i = 0; i < leaders.size(); i++) {
				Leader leader = (Leader)leaders.elementAt(i);
				if (id.equals(leader.getID())) {
					leaders.removeElementAt(i);
					save();
					return true;
				}//if
			}//for
		}//if
		return false;
	}//deleteLeader

	
	//////////////////////////
	///  Utility methods   ///
	//////////////////////////
	
	/** Prints out the name of the troop */
	public String toString() {
		return name;
	}//toString
	
	/** Writes the contents of this Troop to an XML buffer */
	public void writeXML(PrintWriter out) throws DataException {
		// xml version tag
		out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		
		// xml header
		out.println("<Troop id=\"" + Utils.xml(getID()) + "\">");
		out.println("  <Name>" + Utils.xml(getName()) + "</Name>");
		out.println("  <Owner>" + Utils.xml(getOwner()) + "</Owner>");
		out.println("  <Email>" + Utils.xml(getEmail()) + "</Email>");
		out.println("  <Password>" + Utils.xml(getPassword()) + "</Password>");
		out.println("  <ReadOnly>" + Utils.xml(getReadPassword()) + "</ReadOnly>");
		out.println("  <Created>" + Utils.xml(getCreated()) + "</Created>");
		out.flush();
		
		// leaders
		for (Enumeration e = getLeaders(); e.hasMoreElements(); ) {
			FileLeader leader = (FileLeader)e.nextElement();
			leader.writeXML(out);
			out.flush();
		}//for e
		
		// scouts
		for (Enumeration e = getScouts(); e.hasMoreElements(); ) {
			FileScout scout = (FileScout)e.nextElement();
			scout.writeXML(out);
			out.flush();
		}//for e
		
		// xml footer
		out.println("</Troop>");
		out.flush();
	}//writeXML
	
}//Troop class
