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

/** Static utility methods for the bibliography package */
public class Utils {

	static SimpleDateFormat SDF = new SimpleDateFormat("MM/d/yyyy");
	static final SimpleDateFormat NORMAL_SDF = new SimpleDateFormat("EEE, MMM d, yyyy");
	static final SimpleDateFormat GUID_SDF = new SimpleDateFormat("yyyyMMddHHmmssSSS");
	static final String MONTHS[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
	static final String DAYS[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
	public static final String COLORS[] = { 
	  "E1E4BE", // background color
	  "404000", // link color
		"448044", // green color (button color)
		"C9CCA6", // darker tan color (background of headings)
		"800000", // red  text color
		"000000", // main text color (black)
		"008000", // active/hover link color
		"A1A47E"  // double-darker tan color (button color)
	};//COLORS array
	
	public static final int COLORS2[][] = {
		{ 225, 228, 190 } // background color
	};//COLORS2 array

	protected static String lastGUID = "";
	
	/** Generates a new globally unique id, based upon current system time and system IP address */
	public static synchronized String getGUID() {
		String newGUID = "";
		do {
			// time part
			long now = Long.parseLong(GUID_SDF.format(new Date()));
			newGUID = Long.toHexString(now);
		  
			// ip part
			try {
		  	byte ip[] = InetAddress.getLocalHost().getAddress();
				for (int i = 0; i < ip.length; i++) {
					int n = ip[i];
					if (ip[i] < 0) {
						n += 256;
					}//if
					newGUID += Integer.toHexString(n);
				}//for i
			}catch (Exception e) {
				newGUID += "00000000";
			}//try
		}while (newGUID == lastGUID);
		lastGUID = newGUID;
		return lastGUID;
	}//getGUID
	
	/** Shows an error */
	public static void error(PrintWriter out, String string) {
		out.println("<font color=#660000><h3>" + string + "</h3></font>");
	}//error
	
	/** Shows the left-side menu screen */
	public static void menu(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
		Troop troop = (session == null ? null : session.getTroop());
		
		// title
		out.println("<table cellspacing=0 cellpadding=0 border=0 width=100%><tr>");
		out.println("<td bgcolor=#" + COLORS[3] + ">&nbsp;&nbsp;</td>"); // col 1 spacer
		out.println("<td bgcolor=#" + COLORS[3] + ">" + font() + "<center>");
	  out.println("<font size=+2><b>EasyScout</b><font size=1>TM</font></font><br>Web");
		out.println("</td>");
		out.println("<td bgcolor=#" + COLORS[3] + ">&nbsp;&nbsp;&nbsp;</td>"); // col 3 spacer
		out.println("<td width=100% align=right bgcolor=#" + COLORS[3] + ">"); // col 4 Troop name here
		out.println("&nbsp;<br>");
		out.println("<font size=+2 color=#" + COLORS[1] + ">" + font());
		if (troop == null) {
			out.println("Login");
		}else{
			out.println("Troop: " + troop.getName());
		}//if
		out.println("</font>");
		out.println("<br>&nbsp;");
		out.println("</td>");
		out.println("<td bgcolor=#" + COLORS[3] + ">&nbsp;&nbsp;</td>"); // col 5 spacer
		out.println("</tr>");
		
		// spacer row
		out.println("<tr>");
		out.println("<td colspan=5>&nbsp;</td>");
		out.println("</tr>");
		
		// left-side menu
		out.println("<tr>");
		out.println("<td>&nbsp;</td>"); //col 1 spacer
		if (session != null && session.isOwner()) {
			out.println("<td valign=top>"); // col 2 menu column
			out.println(font());
			if (troop != null) {
				String action = request.getParameter("action");
				if (action == null || action.equals("") || action.equalsIgnoreCase("login")) {
					action = "menu";
				}//if
			
				// "MENU" MENU GROUP
				printSection(out, "ACTIONS");
				printMenuItem(request, out, session, "Menu", action, "menu");
				out.println("<br>");
				if (session.isWrite()) {
					printMenuItem(request, out, session, "Add Activity", action, "addactivityscreen");
				}//if

				// TROOP MENU GROUP
				printSection(out, "TROOP");

				printMenuItem(request, out, session, "Statistics", action, "troop");
			  out.println("<br>");
				printMenuItem(request, out, session, "Phone List", action, "phonelist");
			  out.println("<br>");
				printMenuItem(request, out, session, "Trip Reference", action, "tripreference");
			  out.println("<br>");
				printMenuItem(request, out, session, "Custom Report", action, "customoptions");
			  out.println("<br>");
				printMenuItem(request, out, session, "Leaders", action, "leaders");
				if (troop.getLeaderCount() > 0) {
					out.println("<table border=0 cellspacing=0 cellpadding=0 width=100%><tr>");
					out.println("<td>&nbsp;&nbsp;&nbsp;&nbsp;</td>");
					out.println("<td>" + font());
				  TroopUI.leaderSelector(request, out, session);
					out.println("</td>");
					out.println("</tr></table>");
				}else{
					out.println("<br>");
				}//if
				printMenuItem(request, out, session, "Scouts", action, "scouts");
				if (troop.getScoutCount() >= 0) {
					out.println("<table border=0 cellspacing=0 cellpadding=0 width=100%><tr>");
					out.println("<td>&nbsp;&nbsp;&nbsp;&nbsp;</td>");
					out.println("<td>" + font());
					TroopUI.scoutSelector(request, out, session);
					out.println("</td>");
					out.println("</tr></table>");
				}//if
			
				// TOOLS MENU GROUP
				out.println("<p>");
				printSection(out, "TOOLS");
			
				if (session.isWrite()) {
					printMenuItem(request, out, session, "Backup", action, "export");
					out.println("<br>");
				}//if
			
				String link = null;
				if (action.indexOf("create") < 0) {
					link = Utils.servletdir() + "?";
					for (Enumeration enum = request.getParameterNames(); enum.hasMoreElements(); ) {
						String name = (String)enum.nextElement();
						link += name + "=" + request.getParameter(name) + "&";
					}//for i
					link += "settype=0&printerfriendly=1";
				}//if
				printMenuItem(request, out, session, "Printer Friendly", link, true);

				if (session.isWrite()) {
					printMenuItem(request, out, session, "Passwords", action, "viewpass");
					out.println("<br>");
				}//if
			
				// FEEDBACK MENU GROUP
			  out.println("<p>");
				printSection(out, "FEEDBACK");

				printMenuItem(request, out, session, "E-mail", "mailto:" + XMLLookup.directory("Admin"), false);
			  out.println("<br>");

				// TOOLS MENU GROUP
				out.println("<p>");
				printSection(out, "LOGOUT");

				printMenuItem(request, out, session, "Logout", action, "logout"); 
			  out.println("<br>");
				printMenuItem(request, out, session, "Home", XMLLookup.directory("Home"), false);
				
			}//if
		
			out.println("</font>");
			out.println("</td>");
		
			
			out.println("<td valign=top></td>");       // col 3 spacer
			out.println("<td valign=top width=100%>" + font()); // start of col 4 where the info goes
			
		}else{
			out.println("<td valign=top colspan=3 width=100%>" + font()); // start of col 4 where the info goes
		}//if isOwner()
		

		
		// now see footer() below for end of this table
	}//menu
	
	/** Prints a menu item */
	public static void printMenuItem(HttpServletRequest request, PrintWriter out, Session session, String title, String action, String target) throws IOException, DataException {
		if (action.equalsIgnoreCase(target)) {
			out.println("&nbsp;&nbsp;&nbsp;<b>" + title + "</b>");
		}else{
			printMenuItem(request, out, session, title, Utils.servletdir() + "?z=" + session.getZ() + "&action=" + target, false);
		}//if
	}//printMenuItem
	
	/** Prints a menu item with a URL link */
	public static void printMenuItem(HttpServletRequest request, PrintWriter out, Session session, String title, String url, boolean newWindow) throws IOException {
		if (url == null) {
			out.println("&nbsp;&nbsp;&nbsp;" + title);
		}else if (newWindow) {
			out.println("&nbsp;&nbsp;&nbsp;<a target=\"_blank\" href=\"" + url + "\">" + title + "</a>");
		}else{
			out.println("&nbsp;&nbsp;&nbsp;<a href=\"" + url + "\">" + title + "</a>");
		}//if
	}//printMenuItemURL
	
	/** Prints a section header */
	public static void printSection(PrintWriter out, String title) throws IOException {
		printSection(out, title, COLORS[2]);
	}//printSection
	
	/** Prints a section header */
	public static void printSection(PrintWriter out, String title, String buttoncolor) throws IOException {
		out.println("<p>");
		out.println("<table border=0 cellspacing=0 cellpadding=0 width=100%><tr>");
		out.println("<td bgcolor=#" + buttoncolor + ">&nbsp;&nbsp;</td>");
		out.println("<td bgcolor=#" + COLORS[3] + " width=100%>" + font() + "<b>" + title + "</b></td>");
		out.println("</tr></table>");
	}//printSection
	
	/** Prints the standard font for the application */
	public static void font(PrintWriter out) {
		out.print(font());
	}//font
	
	/** Returns the standard font for the application */
	public static String font() {
		return "<font face=Arial,Helvetica>";
	}//font
	
	/** Prints a minimal header */
	public static void minimalHeader(HttpServletRequest request, PrintWriter out) throws IOException, DataException {
		out.println("<html>");
		out.println("<head>");
		out.println("<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">");
		out.println("<META HTTP-EQUIV=\"Expires\" CONTENT=\"Tue, 26-Oct-1965 12:00:00\">");
		out.println("<META HTTP-EQUIV=\"Expires\" CONTENT=\"NOW\">");
		out.println("<META HTTP-EQUIV=\"last modified\" CONTENT=\"NOW\">");
		out.println("<title>EasyScout Web</title>");
		out.println("</head>");
		out.println("<body bgcolor=#" + COLORS[0] + " link=#" + COLORS[1] + " vlink=#" + COLORS[1] + " alink=#" + COLORS[6] + ">");
		out.println(Utils.font());
	}//minimalHeader
		
	/** Prints the header */
	public static void header(HttpServletRequest request, PrintWriter out, Session session) throws IOException, DataException {
	  // HTML header
		out.println("<html>");
		out.println("<head>");
		out.println("<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">");
		out.println("<META HTTP-EQUIV=\"Expires\" CONTENT=\"Tue, 26-Oct-1965 12:00:00\">");
		out.println("<META HTTP-EQUIV=\"Expires\" CONTENT=\"NOW\">");
		out.println("<META HTTP-EQUIV=\"last modified\" CONTENT=\"NOW\">");

		// print Javascript for different functions
		Utils.printConfirm(out);
		Utils.printPopup(out, 500, 400);

		// print the style sheet
		out.println("<title>EasyScout Web</title>");
		out.println("</head>");
		out.println("<body bgcolor=#" + COLORS[0] + " link=#" + COLORS[1] + " vlink=#" + COLORS[1] + " alink=#" + COLORS[6] + ">");
		out.println(font());
		
		menu(request, out, session);
	}//header
	
	/** Prints the footer */
	public static void footer(PrintWriter out, Session session) throws IOException {
		out.println("</td>");     // end of column 4
		if (session != null && session.isOwner()) {
			out.println("<td></td>"); // column 5 spacer
		}//if
		out.println("</tr></table>");
	}//footer

	/** Replaces every occurance of oldSt with newSt in the variable st.
			This method is exactly like the String.replace() method except it
			can work with strings rather than characters. */
	public static String replace(String st, String oldSt, String newSt) {
		int parsed = 0;
		int pos;
		while ((pos = st.indexOf(oldSt, parsed)) >= 0) {
			if (pos == 0) {
				st = newSt + st.substring(pos+oldSt.length());
			}else if (pos == st.length() - 1){
				st = st.substring(0, pos) + newSt;
			}else{
				st = st.substring(0, pos) + newSt + st.substring(pos+oldSt.length());
			}//if
			parsed = pos + newSt.length();
		}//while
		return st;
	}//replace

	/** Prints the javascript that confirms a new url */
	public static void printConfirm(PrintWriter out) {
		out.println("<SCRIPT language=\"javascript\">");
		out.println("  function confirmURL(text, url) {");
		out.println("    if (confirm(text)) {");
		out.println("      self.location=url;");
		out.println("    }");
		out.println("  }");
		out.println("</SCRIPT>");
	}//printConfirm

	/** Prints the Javascript for a popup window */
	public static void printPopup(PrintWriter out, int width, int height) {
		out.println("<SCRIPT language=\"JavaScript\">");
		out.println("  function openwin(cUrl, cName) {");
		out.println("    window.open(cUrl,cName,'toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=1,width="+String.valueOf(width)+",height="+String.valueOf(height)+",resizable=1');");
		out.println("  }");
		out.println("</SCRIPT>");
	}//printPopup

	/** Prints a date field within a form, with today as the default value */
	public static void printDateField(PrintWriter out, String fieldName) {
		printDateField(out, fieldName, new Date());
	}//printDateField

	/** Prints a date field within a form, with the given date as the default value */
	public static void printDateField(PrintWriter out, String fieldName, Date date) {
		// get a calendar object for this date
		java.util.Calendar cal = java.util.Calendar.getInstance();
		cal.setTime(date);

		// month
		out.println("<SELECT NAME=\"" + fieldName + "Month\" SIZE=\"1\">");
		int m = cal.get(java.util.Calendar.MONTH);
		for (int i = 0; i < 12; i++) {
			out.print("<OPTION VALUE=\"" + MONTHS[i].substring(0, 3) + "\"");
			if (i == m) {
				out.println(" SELECTED");
			}//if
			out.println(">" + MONTHS[i]);
		}//for i
		out.println("</SELECT>");

		// day
		out.println("<SELECT NAME=\"" + fieldName + "Day\" SIZE=\"1\">");
		int d = cal.get(java.util.Calendar.DATE);
		for (int i = 1; i <= 31; i++) {
			out.print("<OPTION");
			if (i == d) {
				out.print(" SELECTED");
			}//if
			out.println(">" + String.valueOf(i));
		}//for i
		out.println("</SELECT>");

		// year
		out.println("<SELECT NAME=\"" + fieldName + "Year\" SIZE=\"1\">");
		int y = cal.get(java.util.Calendar.YEAR);
		for (int i = -100; i < 25; i++) {
			out.print("<OPTION");
			if (i == 0) {
				out.print(" SELECTED");
			}//if
			out.println(">" + String.valueOf(i + y));
		}//for i
		out.println("</SELECT>");
	}//printDateField
	
	/** Parses a date field created with printDateField above */
	public static Date parseDateField(HttpServletRequest request, String fieldName) {
		try {
			return new Date(request.getParameter(fieldName + "Day") + " " + request.getParameter(fieldName + "Month") + " " + request.getParameter(fieldName + "Year"));
		}catch (IllegalArgumentException e) {
			e.printStackTrace();
			return null;
		}//try
	}//parseDateField

	/** Formats a date object.  This format should always be equal to format(Calendar) below */
	public static String format(Date date) {
		if (date == null) {
			return "&nbsp;";
		}else{
			return SDF.format(date);
		}//if
	}//format

	/** Formats a calendar object.  This format should always be equal to format(Date) above */
	public static String format(java.util.Calendar cal) {
		if (cal == null) {
			return "&nbsp;";
		}else{
			return format(cal.getTime());
		}//if
	}//format
	
	/** Prints a selection box for all the available merit badges */
	public static void printMeritBadges(PrintWriter out, String fieldname, String selected) throws IOException, DataException{
		Vector vec = XMLLookup.getMeritBadges();
	  out.println("<select name=\"" + fieldname + "\">");
		for (Enumeration enum = vec.elements(); enum.hasMoreElements();) {
			String name = (String)enum.nextElement();
			out.print("<option");
			if (selected != null && selected.equals(name)) {
				out.print(" selected");
			}//if
			out.print(">");
			out.print(name);
			out.println("</option>");
		}//for i
		out.println("</select>");
	}//printMeritBadges
	
	/** Formats a string for XML */
	public static String xml(String s) {
		if (s == null) {
			return "";
		}else{
			s = Utils.replace(s, "&nbsp;", " ");
			// found these conversions at http://java.sun.com/xml/docs/tutorial/sax/4_refs.html#chars
			s = Utils.replace(s, "&", "&amp;");
			s = Utils.replace(s, "<", "&lt;");
			s = Utils.replace(s, ">", "&gt;");
			s = Utils.replace(s, "\"", "&quot;");
		  s = Utils.replace(s, "'", "&apos;");
			return s;
		}//if
	}//xml
	
	/** Formats a date object.  This format should always be equal to format(Calendar) below */
	public static String xml(Date date) {
		if (date == null) {
			return "";
		}else{
			return SDF.format(date);
		}//if
	}//format
	
	/** Returns the image directory */
	public static String imagedir() throws DataException {
		return XMLLookup.directory("AppRoot") + XMLLookup.directory("Images");
	}//imagedir
	
	/** Returns the servlet path.  I don't use Utils.servletdir() because different
	    servlet engines return different things! Very, very frustrating. This ensures
			that everything is portable across servers */
	public static String servletdir() throws DataException {
		return XMLLookup.directory("AppRoot") + XMLLookup.directory("Servlet");
	}//servletdir
			
	
	/** Returns the application directory, such as "/EasyScout/" */
	public static String appdir() throws DataException {
		return XMLLookup.directory("AppRoot");
	}//adppdir
}//Utils class

