/*
 *	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;

import cx.warp.scout.lookup.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.util.zip.*;
import java.text.*;
import java.lang.reflect.*;

/** A static UI class for troop screens */
public class TroopUI {

	static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");

	/** Prints the header for this troop */
	public static void header(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		out.println("<center><h1>" + session.getTroop().getName() + "</h1></center>");
		out.println("<hr>");
	}//header
	
	/** Prints the main index screen */
	public static void mainScreen(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		
		// header
		Utils.printSection(out, "SUMMARY STATISTICS");

		// create the hashtable for required merit badges
		Vector reqVec = XMLLookup.getRequiredMeritBadges();
		int reqcount[] = new int[reqVec.size()];
		for (int i = 0; i < reqcount.length; i++) {
			reqcount[i] = 0;
		}//for i
		
		// calculate scout information
		Vector vec = XMLLookup.getRankNames();
		int counts[] = new int[vec.size()];
		for (Enumeration enum = troop.getScouts(); enum.hasMoreElements(); ) {
			Scout scout = (Scout)enum.nextElement();
			
			// rank
			String scoutrank = scout.getRank().getName();
			for (int i = 0; i < vec.size(); i++) {
				String rank = (String)vec.elementAt(i);
				if (rank.equalsIgnoreCase(scoutrank)) {
					counts[i]++;
					break;
				}//if
			}//for i
			
			// required merit badges
			for (Enumeration enum2 = scout.getMeritBadges(); enum2.hasMoreElements(); ) {
				MeritBadge m = (MeritBadge)enum2.nextElement();
				if (m.isRequired()) {
					for (int i = 0; i < reqVec.size(); i++) {
						String s = (String)reqVec.elementAt(i);
						if (s.equals(m.getName())) {
							reqcount[i]++;
						}//if
					}//for
				}//if
			}//for
			
		}//for enum
/*		
		// print the pie graphic
		String append = "";
		for (int i = 0; i < vec.size(); i++) {
			append += "&" + String.valueOf(i) + "n=" + Utils.replace((String)vec.elementAt(i), " ", "%20") + 
			          "&" + String.valueOf(i) + "v=" + String.valueOf(counts[i]);
		}//for i
		out.println("<center>");
		out.println("<img alt=\"Scout Rankings Pie Graph\" src=\"" + Utils.servletdir() +
		  "?z=" + session.getZ() +
			"&troopid=" + troop.getID() +
			"&action=piegraph" +
			append +
			"\">");
		out.println("</center>");
*/		
		// scout advancement
		out.println("<center>");
		out.println("<table border=0 cellspacing=5>");
		for (int i = 0 ; i < vec.size(); i++) {
			out.println("<tr>");
			out.println("<td>" + Utils.font() + (String)vec.elementAt(i) + "</td>");
			out.println("<td>&nbsp;&nbsp;&nbsp;&nbsp;</td>");
			out.println("<td>" + Utils.font() + String.valueOf(counts[i]) + " Scouts</td>");
			out.println("</tr>");
		}//for i
		out.println("<tr>");
		out.println("<td>" + Utils.font() + "<b>Total</td>");
		out.println("<td>&nbsp;&nbsp;&nbsp;&nbsp;</td>");
		out.println("<td>" + Utils.font() + "<b>" + String.valueOf(troop.getScoutCount()) + " Scouts</td>");
		out.println("</tr>");
		out.println("</table>");
		out.println("</center>");

		// required merit badge summary
		out.println("<p>");
		Utils.printSection(out, "Required Merit Badges", Utils.COLORS[7]);
		out.println("<p>");
		out.println("<center>");
		out.println("<table border=1 cellspacing=3>");
		out.println("<tr>");
		out.println("<th>" + Utils.font() + "Merit Badge</th>");
		out.println("<th>" + Utils.font() + "Scouts Deficient</th>");
		out.println("</tr>");
		int numScouts = troop.getScoutCount();
		for (int i = 0; i < reqVec.size(); i++) {
			String name = (String)reqVec.elementAt(i);
			out.println("<tr>");
			out.println("<td>" + Utils.font() + name + "</td>");
			out.println("<td>" + Utils.font() + String.valueOf(numScouts - reqcount[i]) + "</td>");
			out.println("</tr>");
		}//for
		out.println("</table>");
		out.println("</center>");
		
		
	}//mainScreen

	/** Prints the leaders of the troop */
	public static void leaders(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		
		Utils.printSection(out, "LEADERS");
		out.println("<p>");
		out.println("<table border=0 width=100% cellpadding=0 cellspacing=0>");
		out.println("<tr>");
		out.println("<th>" + Utils.font() + "Leader</td>");
		out.println("<th>" + Utils.font() + "Position</td>");
		if (session.isWrite()) {
			out.println("<th>" + Utils.font() + "Delete</td>");
		}//if
		out.println("</tr>");
		Leader leader = null;
		for (Enumeration enum = troop.getLeaders(); enum.hasMoreElements(); ) {
			leader = (Leader)enum.nextElement();
			out.println("<tr>");
			out.println("<td>");
			out.println("<a href=" + Utils.servletdir() + "?z=" + session.getZ() + "&leaderid=" + leader.getID() + "&action=leaderdetail>");
			out.println(Utils.font() + leader.getName());
			out.println("</a>");
			out.println("</td>");
			out.println("<td>");
			out.println(Utils.font() + leader.getPosition());
			out.println("</td>");
			if (session.isWrite()) {
				out.println("<td><center>");
				LeaderUI.printDeleteLink(request, out, session, "<img src=\"" + Utils.imagedir() + "delete.gif\" border=0>", leader.getID());
				out.println("</td>");
			}//if
			out.println("</tr>");
		}//leaders
		out.println("</table>");

		if (session.isWrite()) {
			out.println("<p>");
			out.println("<a href=" + Utils.servletdir() + "?z=" + session.getZ() + "&action=createleaderscreen>Add Leader</a>");
		}//if
	}//leaders
	
	/** Prints a drop-down box for leader selection */
	public static void leaderSelector(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		Leader selected = LeaderUI.getLeader(request, session);
		Enumeration enum = troop.getLeaders();
		if (enum.hasMoreElements()) {
			out.print("<font size=-1>");
			out.print("<form name=leaders action=" + Utils.servletdir() + " method=get>");
			out.print("<input type=hidden name=action value=leaderdetail>");
			out.print("<input type=hidden name=z value=" + session.getZ() + ">");
			out.print("<select name=leaderid onChange=\"javascript:document.leaders.submit();\">");
			Leader leader = null;
			while (enum.hasMoreElements()) {
				leader = (Leader)enum.nextElement();
				out.print("<option");
				if (selected != null && selected.getID().equals(leader.getID())) {
					out.print(" selected");
				}//if
			  out.print(" value=" + leader.getID() + ">" + leader.getSmallName() + "</option>");
			}//for
			out.print("</select>");
			out.print("&nbsp;");
			out.println("<input type=image border=0 src=\"" + Utils.imagedir() + "check.gif\">");
			out.print("</form>");
			out.print("</font>");
		}//if
	}//leaderSelector

	/** Prints a table summary of all scouts */
	public static void scoutSummary(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		Utils.printSection(out, "SCOUTS");
		out.println("<p>");
		
		if (troop.getScoutCount() == 0) {
			noScouts(request, out, session);
			return;
		}//if
			
		scoutTable(request, out, session, troop);
		
		if (session.isWrite()) {
			out.println("<p>");
			out.println("<a href=" + Utils.servletdir() + "?z=" + session.getZ() + "&action=createscoutscreen>Add Scout</a>");
		}//if
	}//printScoutSummary
	
	/** Prints the table of scouts */
	public static void scoutTable(HttpServletRequest request, PrintWriter out, Session session, Troop troop) throws IOException, DataException {
		out.println("<table border=0 width=100% cellpadding=0 cellspacing=0>");
		out.println("<tr>");
		out.println("<th>" + Utils.font() + "Scout</td>");
		out.println("<th>" + Utils.font() + "Rank</td>");
		out.println("<th>" + Utils.font() + "Age</td>");
		out.println("<th>" + Utils.font() + "Patrol</td>");
		out.println("<th>" + Utils.font() + "Position</td>");
		if (session.isWrite()) {
			out.println("<th>" + Utils.font() + "Delete</td>");
		}//if
		out.println("</tr>");
		Scout scout = null;
		for (Enumeration enum = troop.getScouts(); enum.hasMoreElements();) {
			scout = (Scout)enum.nextElement();
			out.println("<tr>");
			out.println("<td>");
			out.println("<a href=" + Utils.servletdir() + "?z=" + session.getZ() + "&scoutid=" + scout.getID() + "&action=scoutdetail>");
			out.println(Utils.font() + scout.getName() + "</a></td>");
			out.println("<td>" + Utils.font() + scout.getRank().getName() + "</td>");
			out.println("<td>" + Utils.font() + scout.getAge() + "</td>");
			out.println("<td>" + Utils.font() + scout.getPatrol() + "</td>");
			out.println("<td>" + Utils.font() + scout.getPosition() + "</td>");
			if (session.isWrite()) {
				out.println("<td>" + Utils.font());
				ScoutUI.printDeleteLink(request, out, session, "<img src=\"" + Utils.imagedir() + "delete.gif\" border=0>", scout.getID());
				out.println("</td>");
			}//if
			out.println("</tr>");
		}//for
		out.println("</table>");
	}//scoutTable
	
	/** Prints a list box with the scouts in it.  A <form> must have already been started. */
	public static void printScoutList(HttpServletRequest request, PrintWriter out, Session session, Troop troop) throws IOException, DataException {
		int size = Math.min(troop.getScoutCount(), 15);
		out.println("<select name=scoutid multiple size=" + String.valueOf(size) + ">");
		Scout scout = null;
		for (Enumeration enum = troop.getScouts(); enum.hasMoreElements();) {
			scout = (Scout)enum.nextElement();
			out.println("<option value=" + scout.getID() + ">" + scout.getFullName() + "</option>"); 
		}//for
		out.println("</select>");
	}//printScoutList
	

	/** Prints a drop-down box for scout selection */
	public static void scoutSelector(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		String screen = request.getParameter("screen");
		if (screen != null && !screen.equals("")) {
			session.setPage(screen);
		}//if
		Scout selected = ScoutUI.getScout(request, session);
		Enumeration enum = troop.getScouts();
		if (enum.hasMoreElements()) {
			out.print("<font size=-1>");
			out.print("<form name=scouts action=" + Utils.servletdir() + " method=get>");
			out.print("<input type=hidden name=action value=scoutdetail>");
			out.print("<input type=hidden name=screen value=" + session.getPage() + ">");
			out.print("<input type=hidden name=z value=" + session.getZ() + ">");
			out.print("<select name=scoutid onChange=\"javascript:document.scouts.submit();\">");
			Scout scout = null;
			while (enum.hasMoreElements()) {
				scout = (Scout)enum.nextElement();
				out.print("<option");
				if (selected != null && selected.getID().equals(scout.getID())) {
					out.print(" selected");
				}//if
			  out.print(" value=" + scout.getID() + ">" + scout.getSmallName() + "</option>");
			}//for
			out.print("</select>");
			out.print("&nbsp;");
			out.println("<input type=image border=0 src=\"" + Utils.imagedir() + "check.gif\">");
			out.print("</form>");
			out.print("</font>");
		}//if
	}//scoutSelector

	/** Export data screen */
	public static void export(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Utils.printSection(out, "BACKUP");
		out.println("<p>");
		out.println("Please backup your troop data every time you make changes.  Although every effort is made to ensure the server data");
		out.println("is never lost, there is always a possibility of the worst occurring.  <b>Ultimately, EasyScout");
		out.println("clients are responsible for backing up their data.  We disclaim all responsibility for ensuring");
		out.println("that server data is backed up</b> (we'll do our best, but this <i>is</i> a free service).");
		out.println("<p>");
	  out.println("The best defense against");
		out.println("losing data is to make an offsite backup. EasyScout makes this easy since data is stored");
		out.println("on the server and your backups are stored on your local computer.");
		out.println("We suggest you create a directory on your local machine specifically for EasyScout backups.");
		out.println("Save each backup copy in this directory.  Since the backups are almost always very small files, you");
		out.println("should keep old backup files (i.e. don't remove the old backups when you download today's backup).");
		out.println("If the server data is ever lost (including the many central backups), we will ask you for your");
		out.println("most recent backup so we can restore your troop data.");
		out.println("<p>");
		out.println("<b>To save the backup, follow these steps:</b>");
		out.println("<ul>");
		out.println("<li><i>Right-click</i> on the link below (Mac users click & hold).");
		out.println("<li>Select \"Save Target As...\" or \"Save Link As...\" to open a save dialog box.");
	  out.println("<li>Change the location to your backup directory.");
		out.println("<li>Some browsers name the file incorrectly.  Overwrite the filename with something like \"EasyScout_Backup_2000_06_01.zip\".");
		out.println("<li>Click Save.");
		out.println("</ul>");
		out.println("<center><font size=+1>");
		out.println("<a href=\"" + Utils.servletdir() +
		  "?z=" + session.getZ() +
			"&action=doexport" +
			"&settype=0" +
			"\">Right-Click Here To Backup</a>");
		out.println("</font></center>");
		out.println("<p>");
		out.println("<i>For advanced users:</i> EasyScout's backup format is a zipped XML file.  It can be unzipped with");
		out.println("most archiving programs such as PKZip, WinZip, etc.");
		out.println("The XML looks really cool when unzipped and loaded into Internet Explorer 5+ or other XML viewer.");
		out.println("Although the DTD is not yet included, the format should be quite readable.");
	}//export
	
	/** Exports data */
	public static void doexport(HttpServletRequest request, HttpServletResponse response, Session session) throws IOException, DataException {
		// create the zip file		
		response.setContentType("application/x-zip-compressed");
		ZipOutputStream zip = new ZipOutputStream(response.getOutputStream());
		zip.setMethod(ZipOutputStream.DEFLATED);
		zip.setLevel(Deflater.DEFAULT_COMPRESSION);
		
		// create the zip entry
		ZipEntry entry = new ZipEntry("EasyScout_Backup_" + SDF.format(new Date()) + ".xml");
		zip.putNextEntry(entry);
		
		// write the xml
		Troop troop = session.getTroop();
		troop.writeXML(new PrintWriter(zip));
		
		// close the entry
		zip.closeEntry();
		zip.close();
	}//export
	
	/** Prints a phone/email list */
	public static void phoneList(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();

		// header
		Utils.printSection(out, "PHONE LIST");
		out.println("<p>");
	  out.println("<table border=0 width=100% cellspacing=0 cellpadding=0>");
		out.println("<tr>");
		out.println("<th>" + Utils.font() + "Name</th>");
		out.println("<th>" + Utils.font() + "Position</th>");
		out.println("<th>" + Utils.font() + "E-mail</th>");
		out.println("<th>" + Utils.font() + "Phone Number</th>");
		out.println("</tr>");
		
		// people (leaders first, then scouts)
		Enumeration enum[] = { troop.getLeaders(), troop.getScouts() };
		for (int i = 0; i < enum.length; i++) {
			if (i > 0) {
				// separator
				out.println("<tr>");
				out.println("<td colspan=4><hr></td>");
				out.println("</tr>");
			}//if

			while (enum[i].hasMoreElements()) {
				Person person = (Person)enum[i].nextElement();
				out.println("<tr>");
				out.println("<td>" + Utils.font() + tableCell(person.getName()) + "</td>");
				out.println("<td>" + Utils.font() + tableCell(person.getPosition()) + "</td>");
				out.println("<td>" + Utils.font() + tableCell(person.getEmail()) + "</td>");
				out.println("<td>" + Utils.font() + tableCell(person.getPhone()) + "</td>");
				out.println("</tr>");
			}//while
		}//for i
		
		// footer
		out.println("</table>");
		
	}//phoneList
	
	/** Prints a cell, or &nbsp if blank or null */
	public static String tableCell(String s) {
		if (s == null || s.equals(""))
		  return "&nbsp;";
		if (s.indexOf("\n") >= 0) 
			return Utils.replace(s, "\n", "<br>");
		return s;
	}//tableCell

	/** Prints a trip reference list */
	public static void tripReference(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();

		// header
		Utils.printSection(out, "TRIP REFERENCE");
		out.println("<p>");
	  out.println("<table border=1 width=100% cellspacing=0 cellpadding=0>");
		out.println("<tr>");
		out.println("<th>" + Utils.font() + "Name</th>");
		out.println("<th>" + Utils.font() + "Age</th>");
		out.println("<th>" + Utils.font() + "Adult Contact(s)</th>");
		out.println("<th>" + Utils.font() + "Medical</th>");
		out.println("<th>" + Utils.font() + "Emergency Contact(s)</th>");
		out.println("<th>" + Utils.font() + "Notes</th>");
		out.println("</tr>");
		
		// people (leaders first, then scouts)
		for (Enumeration enum = troop.getScouts(); enum.hasMoreElements(); ) {
			Scout scout = (Scout)enum.nextElement();
			out.println("<tr>");
			out.println("<td valign=top>" + Utils.font() + tableCell(scout.getName()) + "</td>");
			out.println("<td valign=top>" + Utils.font() + tableCell(scout.getAge()) + "</td>");
			out.println("<td valign=top>" + Utils.font() + tableCell(scout.getContact()) + "</td>");
			out.println("<td valign=top>" + Utils.font() + tableCell(scout.getMedicalNotes()) + "</td>");
			out.println("<td valign=top>" + Utils.font() + tableCell(scout.getEmergency()) + "</td>");
			out.println("<td valign=top>" + Utils.font() + tableCell(scout.getNotes()) + "</td>");
			out.println("</tr>");
		}//for
		
		// footer
		out.println("</table>");
		
	}//phoneList

	/** Prints the main help menu */
	public static void menu(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		String action = request.getParameter("action");
		
		// center main menu
		out.println("<center>");
		out.println("<font size=+1><i>What Would You Like To Do?</i></font>");

		out.println("<p>");
		out.println("<table border=0><tr><td>");
		out.println(Utils.font() + "<font size=+1>");
		
		String img;
		out.println("<img alt=\"--\" border=0 src=\"" + Utils.imagedir() + "view.gif\">");
		Utils.printMenuItem(request, out, session, "View All Scouts In Database", action, "scouts");
		out.println("<p>");
		
		if (session.isWrite()) {
			out.println("<img alt=\"--\" border=0 src=\"" + Utils.imagedir() + "database.gif\">");
			Utils.printMenuItem(request, out, session, "Add A Scout", action, "createscoutscreen");
			out.println("<p>");
		}//if
		
		out.println("<img alt=\"--\" border=0 src=\"" + Utils.imagedir() + "records.gif\">");
		if (session.isWrite()) {
			Utils.printMenuItem(request, out, session, "View/Update A Scout's Information", action, "viewscouts");
		}else{
			Utils.printMenuItem(request, out, session, "View A Scout's Information", action, "viewscouts");
		}//if
		out.println("<p>");
		
		if (session.isWrite()) {
			out.println("<img alt=\"--\" border=0 src=\"" + Utils.imagedir() + "lock.gif\">");
			Utils.printMenuItem(request, out, session, "Edit Owner and Individual Scout Passwords", action, "viewpass");
			out.println("<p>");
		}//if
		
		out.println("<img alt=\"--\" border=0 src=\"" + Utils.imagedir() + "print.gif\">");
		Utils.printMenuItem(request, out, session, "Print Reports", action, "print");
		out.println("<p>");
		
		if (session.isWrite()) {
			out.println("<img alt=\"--\" border=0 src=\"" + Utils.imagedir() + "backup.gif\">");
			Utils.printMenuItem(request, out, session, "Backup My Data", action, "export");
			out.println("<p>");
		}//if

		out.println("</td></tr></table>");
		out.println("</font>");
		out.println("</center>");
		
		// right side hints
		out.println("</td>");
		out.println("<td width=200 valign=top>" + Utils.font());
		Utils.printSection(out, "HINTS");
		out.println("<p>");
		out.println("<img border=0 alt=\"--\" src=\"" + Utils.imagedir() + "bsa6.gif\">");
		out.println("To get back to this main screen, click \"Menu\" in the <i>Actions</i> category");
		out.println("    in the left column (it is bolded right now).");
		out.println("<p>");
		out.println("<img border=0 alt=\"--\" src=\"" + Utils.imagedir() + "bsa6.gif\">");
		out.println("All of the options on this menu can be also accessed from the quick links in the left column,");
		out.println("no matter which screen you are at.");
		out.println("<br><img border=0 alt=\"\" src=\"" + Utils.imagedir() + "spacer150.gif\">");
		
	}//menu

	/** Prints the print help screen */
	public static void printScreen(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		String action = request.getParameter("action");

		Utils.printSection(out, "PRINT REPORTS");
		out.println("<p>");
		
		out.println("EasyScout uses your browser's print capabilities for reporting.  Therefore, just select ");
		out.println("File | Print on your browser's menu or press the <i>Print</i> icon on the toolbar.");
		out.println("You can print any screen in EasyScout this way.");
		out.println("<p>");
		out.println("EasyScout also provides a <b>Printer Friendly</b> option for nearly all screens you come to.");
		out.println("This option opens a new browser window with your current screen displayed, less the title");
		out.println("and left-column menu.  Most users click this option before printing reports.");
		out.println("<p>");
		out.println("<img src=\"" + Utils.imagedir() + "tryit.gif\">");
		out.println("<i>Try formatting this page for your printer by clicking <b>Printer Friendly</b>");
		out.println("in the left column under \"Tools\" now.</i>");
		out.println("Note that a new window will open in front of this one.  To come back to the application,");
		out.println("close the new window (Windows users: click the 'X' in the upper right corner.");
		out.println("<p>");
		out.println("The following are just some of the screens that are often printed by users:");
		out.println("<b>");
		out.println("<ul>");
		out.println("<li>");
		String link = Utils.servletdir() +
		  "?z=" + session.getZ() +
			"&printerfriendly=1" +
			"&settype=0";
		Utils.printMenuItem(request, out, session, "Troop Phone/Email List", link + "&action=phonelist", true);
		out.println("<p>");
		out.println("<li>");
		Utils.printMenuItem(request, out, session, "Troop Statistics", link + "&action=troop", true);
		out.println("<p>");
		out.println("<li>");
		out.println("&nbsp;&nbsp;&nbsp;The Trail To Eagle (select a Scout from the left-column)");
		out.println("<p>");
		out.println("<li>");
		Utils.printMenuItem(request, out, session, "Trip Reference", link + "&action=tripreference", true);
		out.println("</ul>");
		
	}//printScreen
	
	/** Prints the view scout screen */
	public static void viewScoutScreen(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		
		// header
		Utils.printSection(out, "VIEW/UPDATE A SCOUT'S INFORMATION");
		out.println("<p>");
		
		if (troop.getScoutCount() == 0) {
			noScouts(request, out, session);
		
		}else{
			// print the table of scouts
			out.println("<b>Please select a scout:</b>");
			out.println("<p>");
			scoutTable(request, out, session, troop);
		
			out.println("<p>&nbsp;<p>");
			out.println("<i>You can also view a scout's information by selecting his name from the drop-down list");
			out.println("under the \"Scouts\" option in the left column.</i>");
		
		}//if	
		
	}//printScoutScreen

	/** Adds a blanket activity to a number of scouts at the same time */
	public static void addActivityScreen(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		
		// header
		Utils.printSection(out, "ADD TROOP ACTIVITY");
		
		// short circuit if no scouts exist
		if (troop.getScoutCount() == 0) {
			noScouts(request, out, session);
			return;
		}//if
		
		out.println("<p>");
		out.println("Use this screen to record an activity for a number of scouts.");
		out.println("<p>");
		
		// input form
		out.println("<b>Select the Scouts who attended this activity:</b>");
		out.println("<form method=post action=\"" + Utils.servletdir() + "\">");
		out.println("<input type=hidden name=action value=createblanketactivity>");
		out.println("<input type=hidden name=screen value=" + session.getPage() + ">");
		out.println("<input type=hidden name=z value=" + session.getZ() + ">");
		out.println("<table border=0>");
		out.println("<tr>");
		out.println("<td>" + Utils.font() + "Name/Type:</td>");
		out.println("<td colspan=2>" + Utils.font() + "<input type=text name=name size=30></td>");
		out.println("</tr><tr>");
		out.println("<td>" + Utils.font() + "Date:</td>");
		out.println("<td colspan=2>" + Utils.font());
		Utils.printDateField(out, "", new Date());
		out.println("</td>");
		out.println("</tr><tr>");
		out.println("<td valign=top>" + Utils.font() + "Description/Notes:</td>");
		out.println("<td colspan=2>" + Utils.font() + "<textarea name=description cols=50 rows=10></textarea></td>");
		out.println("</tr>");
		out.println("<tr>");
		out.println("<td valign=top>" + Utils.font() + "Attending<br>Scouts:</td>");
		out.println("<td valign=top>" + Utils.font());
		printScoutList(request, out, session, troop);
		out.println("</td>");
		out.println("<td valign=top><font size=1>" + Utils.font());
		out.println("Select multiple Scouts in Windows by holding down the [Ctrl] key while you click Scouts in the box.");
		out.println("</td>");
		out.println("<tr>");
		out.println("<td valign=top>" + Utils.font() + "&nbsp;</td>");
		out.println("<td colspan=2>" + Utils.font() + "<input type=submit value=Submit></td>");
		out.println("</tr>");
		out.println("</table>");
		
		out.println("</form>");
	}//addActivity
	
	/** Does the actual adding of the activity */
	public static void addActivity(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		
		// header
		Utils.printSection(out, "ADD TROOP ACTIVITY");
		out.println("<p>");
		
		// get and verify the data
		String name = request.getParameter("name");
		Date date = Utils.parseDateField(request, "");
		String desc = request.getParameter("description");
		String error = "";
		String scoutids[] = request.getParameterValues("scoutid");
		if (name == null || name.equals("")) error = "The name field was blank.";
	  if (scoutids == null || scoutids.length == 0) error = "At least one scout must be selected.";
		if (!error.equals("")) {
			out.println("<font size=+1 color=red>Error:</font>");
			out.println("<p>");
			out.println(error);
			out.println("<p>");
			out.println("Please press your browser's back button and try again.");
			return;
		}//if
		
		// step through the scoutids and record the new activities
		out.println("<b>The new activity has been added to the records of:</b>");
		out.println("<ul>");
		for (int i = 0; i < scoutids.length; i++) {
			Scout scout = troop.getScout(scoutids[i]);
			if (scout != null) {
				out.println("<li>" + scout.getName() + "</li>");
				Activity activity = scout.createActivity();
				activity.setName(name);
				activity.setDate(date);
				activity.setDescription(desc);
			}//if
		}//for i
		out.println("</ul>");
		
		// confirmation
		out.println("<b>You may click on another menu option in the left column or return to the ");
		out.println("<a href=\"" + Utils.servletdir() +
		            "?z=" + session.getZ() +
								"&action=menu" + 
								"\">");
		out.println("main menu</a>.");		
		
	}//addActivity

	/** Prints the no scout error screen */
	public static void noScouts(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		out.println("There are no scouts recorded in your database.  Click ");
		out.println("<a href=\"" + Utils.servletdir() +
		            "?z=" + session.getZ() +
								"&action=createscoutscreen" +
								"\">");
		out.println("<b>here</b></a> to add a scout now.");
	}//noScouts
	
	/** Prints the custom report options screen */
	public static void customOptions(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		
		// header
		Utils.printSection(out, "CUSTOM REPORT");
		out.println("<p>");
		out.println("<form method=post action=\"" + Utils.servletdir() + "\">");
		out.println("<input type=hidden name=action value=customreport>");
		out.println("<input type=hidden name=z value=" + session.getZ() + ">");
		out.println("Report Name: ");
		out.println("<input type=text size=30 name=reportname value=\"" + troop.getName() + "\">");
		out.println("<p>");
		out.println("Fields you would like in the report:");
		out.println("<p>");
		out.println("<table border=0 cellspacing=5>");
		for (int i = 0; i < Scout.FIELDS.length; i++) {
			out.println("<tr>");
			out.println("<td valign=top>" + Utils.font());
		  out.println("<input type=checkbox checked name=" + Scout.FIELDS[i][1] + ">");
			out.println(Scout.FIELDS[i][0]);
		  out.println("</td>");
			out.println("</tr>");
		}//for
		out.println("<tr>");
		out.println("<td><center>" + Utils.font() + "<input type=submit value=Generate></td>");
		out.println("</tr>");
		out.println("</table>");
		out.println("</form>");
		
	}//customOptions
	
	/** Prints the custom report */
	public static void customReport(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		
		Utils.printSection(out, request.getParameter("reportname"));
		out.println("<p>");

		// get the fields they want to print
		boolean checked[] = new boolean[Scout.FIELDS.length];
		for (int i = 0; i < Scout.FIELDS.length; i++) {
			String s = request.getParameter(Scout.FIELDS[i][1]);
			if (s != null && s.toLowerCase().equals("on")) {
				checked[i] = true;
			}else{
				checked[i] = false;
			}//if
		}//for
		
		// header
		out.println("<table border=1 cellspacing=0 cellpadding=0 width=100%>");
		out.println("<tr>");
		for (int i = 0; i < checked.length; i++) {
			if (checked[i]) {
				out.println("<th valign=top>" + Utils.font() + Scout.FIELDS[i][0] + "</th>");
			}//if
		}//for
		out.println("</tr>");
		
		// rows for scouts
		Method methods[] = new Method[Scout.FIELDS.length];
		Class scoutclass = null;
		Scout scout = null;
		for (Enumeration enum = troop.getScouts(); enum.hasMoreElements(); ) {
			scout = (Scout)enum.nextElement();
			out.println("<tr>");
			
			// get the methods the first time
			if (scoutclass == null) {
				try {
					scoutclass = scout.getClass();
					Method allMethods[] = scoutclass.getMethods(); 
					for (int j = 0; j < methods.length; j++) {
						if (checked[j]) {
							for (int k = 0; k < allMethods.length; k++) {
								if (allMethods[k].getName().equals(Scout.FIELDS[j][1])) {  // look for same name
									Class[] parameters = allMethods[k].getParameterTypes(); 
									if (parameters == null || parameters.length == 0) {      // must have no parameters
										methods[j] = allMethods[k];
										break;
									}//if
								}//if
							}//for
					  }//if
					}//for
				}catch (Exception ex) {
					throw new DataException("Could not create report.  Nested exception is:", ex);
				}//try
			}//if
			
			for (int j = 0; j < checked.length; j++) {
				if (checked[j]) {
					out.println("<td valign=top>" + Utils.font());
				  if (methods[j] != null) {
						try {
							Object ret = methods[j].invoke(scout, null);
							if (ret == null) {
								out.println("&nbsp;");
							}else if (ret instanceof String) {
								out.println(tableCell((String)ret));
							}else if (ret instanceof Date) {
								out.println(tableCell(Utils.format((Date)ret)));
							}else{
								out.println(tableCell(ret.toString()));
							}//if
						}catch (Exception ex) {
							ex.printStackTrace();
							out.println("&nbsp;");
						}//try
					}else {
						out.println("&nbsp;");
					}//if
					out.println("</td>");
				}//if
			}//for
			
			out.println("</tr>");
		}//for
		
		// footer
		out.println("</table>");
		out.println("<p>");
		out.println("Printed On " + Utils.NORMAL_SDF.format(new Date()) + ".");
		
	}//customReport
	
	/** Views the current passwords for the troop */
	public static void viewPasswords(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		
		// header
		Utils.printSection(out, "TROOP INFORMATION AND PASSWORDS");
		out.println("<p>");
		out.println("Use this page to set troop passwords.  Please note that a different password");
		out.println("must be used for master, reader, and each scout.");
		out.println("<p>");
		
		out.println("<form action=" + Utils.servletdir() + " method=post>");
		out.println("<input type=hidden name=action value=setpass>");
		out.println("<input type=hidden name=z value=" + session.getZ() + ">");
		
		// owner information
		Utils.printSection(out, "OWNER INFORMATION", Utils.COLORS[7]);
		out.println("<p>");
		out.println("The <b>master</b> password allows full access to all troop data.");
		out.println("<p>");
		out.println("<table border=0>");
		out.println("<tr><td>" + Utils.font() + "Master Password:</td><td>" + Utils.font() + "<input type=password size=40 name=password value=\"" + troop.getPassword() + "\"></td></tr>");
		out.println("<tr><td>" + Utils.font() + "Reenter Master Password:</td><td>" + Utils.font() + "<input type=password size=40 name=password2 value=\"" + troop.getPassword() + "\"></td></tr>");
		out.println("<tr><td>" + Utils.font() + "Owner Name:</td><td>" + Utils.font() + "<input type=text size=40 name=owner value=\"" + troop.getOwner() + "\"></td></tr>");
		out.println("<tr><td>" + Utils.font() + "Owner E-mail:</td><td>" + Utils.font() + "<input type=text size=40 name=email value=\"" + troop.getEmail() + "\"></td></tr>");
		out.println("</table>");
		out.println("<input type=submit value=Submit>");
		out.println("<p>&nbsp;<p>");
		
		// read-only passwords
		Utils.printSection(out, "READ-ONLY PASSWORD", Utils.COLORS[7]);
		out.println("<p>");
		out.println("The <b>read-only</b> password allows read access to <b>all</b> troop data.  The only difference between this");
		out.println("password and the master password is the master's write-access to your file.  Most troops give this password");
		out.println("to adult leaders who need to view Scout progress.");
		out.println("<p>");
		out.println("<table border=0>");
		out.println("<tr><td>" + Utils.font() + "Read-Only Password:</td><td>" + Utils.font() + "<input type=text size=20 name=readonly value=\"" + troop.getReadPassword() + "\"></td></tr>");
		out.println("</table>");
		out.println("<input type=submit value=Submit>");
		out.println("<p>&nbsp;<p>");
		
		// scout passwords
		Utils.printSection(out, "SCOUT PASSWORDS", Utils.COLORS[7]);
		out.println("<p>");
		out.println("<b>Scout</b> passwords allow (mostly) read-only access to individual scout records only.");
		out.println("A blank Scout password means the Scout has <i>no</i> access to his records.");
		out.println("<p>");
		out.println("<table border=0>");
		for (Enumeration enum = troop.getScouts(); enum.hasMoreElements(); ) {
			Scout scout = (Scout)enum.nextElement();
			out.println("<tr>");
			out.println("<td valign=top>" + Utils.font());
			out.println(scout.getName() + ":");
			out.println("</td>");
			out.println("<td valign=top>" + Utils.font());
			String pass = scout.getPassword();
			if (pass == null) pass = "";
			out.println("<input size=20 type=text name=" + scout.getID() + " value=\"" + pass + "\">");
			out.println("</td>");
			out.println("</tr>");
		}//for
		out.println("</table>");
		out.println("<input type=submit value=Submit>");
		
		
		out.println("</form>");
	}//viewPaSswords
	
	/** Sets the passwords for the troop */
	public static void setPasswords(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = session.getTroop();
		
		// get owner information
		String password = request.getParameter("password");
		String password2 = request.getParameter("password2");
		String readonly = request.getParameter("readonly");
		if (readonly == null)
		  readonly = "";
		String owner = request.getParameter("owner");
		String email = request.getParameter("email");
	
	  // check the data for consistency
		String error = "";
		if (error.equals("") && (password == null || password.equals(""))) error = "Password field was blank.";
		if (error.equals("") && (password2 == null || password2.equals(""))) error = "Password confirmation field was blank.";
		if (error.equals("") && (password == null || !password.equals(password2))) error = "The entered passwords did not match.";
		if (error.equals("") && (owner == null || owner.equals(""))) error = "Owner field was blank.";
		if (error.equals("") && (email == null || email.equals(""))) error = "E-mail field was blank.";
		if (error.equals("") && (readonly.equals(password))) error = "Read-only password cannot be the same as the master password."; 
		if (!error.equals("")) {
			Utils.error(out, error + "  Please press your browser's back button and try again.");
			return;
		}//if
	
		// set the owner information
		troop.setPassword(password);
		troop.setOwner(owner);
		troop.setEmail(email);
		troop.setReadPassword(readonly);
		
		// get the scout information, one by one
		TreeMap used = new TreeMap(); // keep track of used passwords
		used.put(password, "the master");
		used.put(readonly, "readonly");
		String errors = "";
		for (Enumeration enum = troop.getScouts(); enum.hasMoreElements(); ) {
			Scout scout = (Scout)enum.nextElement();
			String pass = request.getParameter(scout.getID());
			if (pass == null || pass.equals("")) {
				scout.setPassword("");
			}else{
				// check the used passwords
				String s = (String)used.get(pass);
			  if (s != null) {
					scout.setPassword("");
					errors += "<li>" + scout.getName() + "'s password has already been taken by " + s + " password.  Change " + scout.getFirstName() + "'s password to give him access to the system.";
				}else{
					scout.setPassword(pass);
					used.put(pass, scout.getName() + "'s");
				}//if
			}//if
		}//for		
		
		// show the success message
		Utils.printSection(out, "PASSWORDS CHANGED");
		out.println("<p>");
		if (errors.equals("")) {
			out.println("All passwords were successfully updated.");
		}else{
			out.println("All passwords were successfully updated, except the following:");
		  out.println("<ul>");
			out.println(errors);
			out.println("</ul>");
		}//if
		out.println("<p>");
		out.println("Return to the <a href=\"" + Utils.servletdir() + "?z=" + session.getZ() + "&action=menu\">Main Menu</a>.");
		
	}//setPasswords

}//TroopUI
