/* ======================================================================
The Bodington System Software License, Version 1.0
  
Copyright (c) 2001 The University of Leeds.  All rights reserved.
  
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

1.  Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2.  Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

3.  The end-user documentation included with the redistribution, if any,
must include the following acknowledgement:  "This product includes
software developed by the University of Leeds
(http://www.bodington.org/)."  Alternately, this acknowledgement may
appear in the software itself, if and wherever such third-party
acknowledgements normally appear.

4.  The names "Bodington", "Nathan Bodington", "Bodington System",
"Bodington Open Source Project", and "The University of Leeds" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
d.gardner@leeds.ac.uk.

5.  The name "Bodington" may not appear in the name of products derived
from this software without prior written permission of the University of
Leeds.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  TITLE,  THE IMPLIED WARRANTIES 
OF QUALITY  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO 
EVENT SHALL THE UNIVERSITY OF LEEDS OR ITS CONTRIBUTORS BE LIABLE FOR 
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY OF SUCH DAMAGE.
=========================================================

This software was originally created by the University of Leeds and may contain voluntary 
contributions from others.  For more information on the Bodington Open Source Project, please 
see http://bodington.org/

====================================================================== */

package org.bodington.servlet.facilities;

import java.util.logging.*;


import org.bodington.servlet.*;
//import java.security.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.StringTokenizer;
import java.util.Enumeration;
import java.util.Vector;

import org.bodington.database.PrimaryKey;
import org.bodington.sqldatabase.SqlDatabase;
import org.bodington.server.*;
import org.bodington.server.realm.*;
import org.bodington.server.realm.User;
import org.bodington.server.resources.Resource;
import org.bodington.server.events.Event;
import org.bodington.server.events.UserManagementEvent;
import org.bodington.text.BigString;

public class UserDirectoryFacility extends org.bodington.servlet.facilities.AliasFacility
	{	
	



	public void insert( Request req, PrintWriter out, String command, String insertname )
		throws ServletException, IOException
		{
		Logger.getLogger("org.bodington").fine( " PasswordFacility insert()" );
		
		try
			{
			BuildingSession session;
			UserManagementSession um_session;

		    session = BuildingSessionManagerImpl.getSession( req.getResource() );
		    if ( !(session instanceof UserManagementSession) )
		    	{
		    	out.println( "<HR>Technical problem: unable to access appropriate tool session.<HR>" );
		    	return;
		    	}
		    um_session = (UserManagementSession)session;

			if ( command.equals( "confirmpass" ) )
				{
				confirmpass(  req, out );
				return;
				}

			if ( command.equals( "usersearchform" ) )
				{
				usersearchform(  req, out, insertname );
				return;
				}

			if ( command.equals( "listusers" ) )
				{
	            String output_format=req.getParameter( "output_format" );
    	        boolean xml_output = output_format != null && output_format.equalsIgnoreCase( "xml" );
    	        if ( xml_output )
    	        	out.println( "<span class=bs-textarea><TEXTAREA ROWS=20 COLS=80>" );
				listusers(  req, out, true );
    	        if ( xml_output )
    	        	out.println( "</TEXTAREA></span>" );
				return;
				}

			if ( command.equals( "userdata" ) )
				{
				userdata(  req, out, insertname );
				return;
				}

			if ( command.equals( "confirmuserdata" ) )
				{
				confirmuserdata( um_session, req, out );
				return;
				}
			
			if ( command.equals( "usereventlog" ) )
				{
				usereventlog(  req, out );
				return;
				}

			if ( command.equals( "ifcanedituser" ) )
				{
				req.setSwitchedOff(  !ifcanedituser( req ) );
				}

			
			if ( command.equals( "resetallstudents" ) )
				{
				String message = um_session.resetAllStudentPasswords();
				out.println( "<PRE>" );
				out.println( message );
				out.println( "</PRE>" );
				}
				
			if ( command.equals( "resetnullstudents" ) )
				{
				String message = um_session.resetNullStudentPasswords();
				out.println( "<PRE>" );
				out.println( message );
				out.println( "</PRE>" );
				}
			}
		catch ( BuildingServerException bsex )
			{
			out.println( bsex.toString() );
			return;
			}

		
		
		super.insert( req, out, command, insertname );
		}
	

        public void sendVirtualFile( Request req, HttpServletResponse res )
        throws ServletException, IOException
        {

            if ( req.getPageName().equals( "listusers.html" ) )
            {
                String output_format=req.getParameter( "output_format" );
                boolean xml_output = output_format != null && output_format.equalsIgnoreCase( "xml" );
                boolean html_output = !xml_output && !(output_format != null && output_format.equalsIgnoreCase( "text" ));
                PrintWriter out = new PrintWriter( res.getWriter() );
                res.setContentType( "text/plain" );

                if ( xml_output )
                {
                    res.setContentType( "text/xml" );
                }
                else if ( html_output )
                {
                    res.setContentType( "text/html" );
                    out.println( "<HTML><HEAD>" );
                    out.println( "<LINK HREF=\"bs_template_user.css\" TYPE=\"text/css\"  REL=\"STYLESHEET\">" );
                    out.println( "</HEAD><BODY>" );
                }
                else
                {
                    res.setContentType( "text/plain" );
                }


                listusers(  req, out, true );

                if ( html_output )
                {
                    out.println( "</body></html>" );
                }

                return;
            }
            else
            {
                super.sendVirtualFile( req, res );
            }
        }
		
	private void confirmpass( Request req, PrintWriter out )
		throws IOException
		{
		String o, p, c, r;
		User user;
		PassPhrase pass;
		
		if ( !BuildingContext.getContext().checkPermission( "edit" ) )
			{
			out.println( "<HR><H4>You don't have permission to use this facility.  Sorry.</H4><HR>\n" );
			return;
			}

		o=req.getParameter( "oldpass" );
		p=req.getParameter( "pass" );
		c=req.getParameter( "confirm" );

		try
			{
			user = (User)BuildingContext.getContext().getUser();
			pass = PassPhrase.findPassPhrase( "user_id = " + user.getUserId() );
			if ( pass==null )
				{
				out.println( "<HR><H4>There was a problem finding your user name and password data.</H4><HR>\n" );
				out.println( "<P>You can go <A HREF=bs_template_main.html>back</A> and try again.</P>" );
				return;
				}
			
			if ( !pass.isPassPhrase( o ) )
				{
				out.println( "<HR><H4>You didn't enter the correct current password and so you are not allowed to change it.</H4><HR>\n" );
				out.println( "<P>You can go <A HREF=bs_template_main.html>back</A> and try again.</P>" );
				return;
				}

			if ( p==null || c==null )
				{
				out.println( "<HR><H4>There was an unexpected problem processing input.  Sorry.</H4><HR>\n" );
				out.println( "<P>You can go <A HREF=bs_template_main.html>back</A> and try again.</P>" );
				return;
				}
			
			if ( p.length()==0 )
				{
				out.println( "<HR><H4>You didn't type anything in the new password box.</H4><HR>\n" );
				out.println( "<P>You can go <A HREF=bs_template_main.html>back</A> and try again.</P>" );
				return;
				}
			if ( p.length()<6 )
				{
				out.println( "<HR><H4>You didn't type a password that is long enough (must be 6 or more characters).</H4><HR>\n" );
				out.println( "<P>You can go <A HREF=bs_template_main.html>back</A> and try again.</P>" );
				return;
				}
			if ( c.length()==0 )
				{
				out.println( "<HR><H4>You didn't retype your new password in the second box.</H4><HR>\n" );
				out.println( "<P>You can go <A HREF=bs_template_main.html>back</A> and try again.</P>" );
				return;
				}
			if ( !c.equals(p) )
				{
				out.println( "<HR><H4>You typed different things in the two boxes.</H4><HR>\n" );
				out.println( "<P>You can go <A HREF=bs_template_main.html>back</A> and try again.</P>" );
				return;
				}
				
			pass.setUnencryptedPassPhrase( p );
			pass.save();
				
			UserManagementEvent event = 
				new UserManagementEvent( 
						UserManagementEvent.EVENT_PASSPHRASE_SET,
						req.getResource().getResourceId(),
						user.getUserId(),
						null,
						null,
						null,
						null,
						null );
			event.save();
				
			out.println( 
				"<H4>Your new password has been stored.  " +
				"When you access another page in the building " +
				"you will be prompted to log in again.  You should use your " +
				"new password.</H4>" );
			}
		catch ( Exception ex )
			{
			out.println( "<HR><H4>There was a problem finding your user name and password data.</H4><HR>\n" );
			out.println( "<P>You can go <A HREF=bs_template_main.html>back</A> and try again.</P>" );
			return;
			}
		}


	private void userdata( Request req, PrintWriter out, String item )
		throws IOException
		{
		boolean canedit;
		String o, p, c, r, u;
		PrimaryKey uid;
		User user, currentuser;
		UserDetail detail;
		PassPhrase pass;
		
		
		try
			{
			currentuser = (User)BuildingContext.getContext().getUser();
			if ( currentuser == null )
				{
				out.println( "Technical problem - couldn't determine who you are." );
				return;
				}


			if ( req.getTemplateParameterCount()==0 )
				{
				user = currentuser;
				}
			else
				{
				uid = null;
				user = null;
				u = (String)req.getTemplateParameter( 0 );
				try
					{
					if ( u!=null )
						uid = new PrimaryKey( Integer.parseInt( u ) );
					}
				catch ( NumberFormatException nfex )
					{
					uid = null;
					}
				if ( uid!=null )
					user = User.findUser( uid );
					
				if ( user == null )
					{
					out.println( "<I>Unspecified user.</I>" );
					return;
					}
				}

			// Can edit entry is current user has sysadmin access or if the
			// current user has manage access and the target user
			// belongs in the same adminsitrative zone or if the current user
			// is looking at their own entry and has been given edit level access
			// to the tool.
			canedit = req.getResource().checkPermission( Permission.SYSADMIN )           ||
			
					  ( req.getResource().checkPermission( Permission.MANAGE ) && 
						user.getZoneId().equals(currentuser.getZoneId())      )     ||
						
					  ( req.getResource().checkPermission( Permission.EDIT ) && 
						user.getUserId().equals(currentuser.getUserId())      )   ;
						
			
			if ( item.equalsIgnoreCase( "button" ) && canedit )
				{
				out.println( "<INPUT TYPE=SUBMIT VALUE=Save>" );
				out.println( "<INPUT TYPE=HIDDEN NAME=op VALUE=userdata>" );
				return;
				}

			if ( item.equalsIgnoreCase( "user_id" ) )
				{
				out.println( user.getUserId().toString() );
				return;
				}

			if ( item.equalsIgnoreCase( "name" ) )
				{
				if ( canedit )
					out.print( "<INPUT NAME=name VALUE=\"" );

				out.print( user.getName() );

				if ( canedit )
					out.print( "\">" );
				return;
				}

			if ( item.equalsIgnoreCase( "surname" ) )
				{
				if ( canedit )
					out.print( "<INPUT NAME=surname VALUE=\"" );

				out.println( user.getSurname() );

				if ( canedit )
					out.print( "\">" );
				return;
				}

			if ( item.equalsIgnoreCase( "initials" ) )
				{
				if ( canedit )
					out.print( "<INPUT NAME=initials VALUE=\"" );

				out.println( user.getInitials() );

				if ( canedit )
					out.print( "\">" );
				return;
				}

			if ( item.equalsIgnoreCase( "user_name" ) )
				{
				pass = PassPhrase.findPassPhrase( "user_id = " + user.getUserId() );
				if ( pass==null )
					{
					out.println( "<I>You don't have a user name</I>" );
					return;
					}
				out.println( pass.getUserName() );
				return;
				}

			detail = UserDetail.findUserDetail( "user_id = " + user.getUserId() );

			if ( item.equalsIgnoreCase( "email_address" ) )
				{
				if ( canedit )
					out.print( "<INPUT NAME=email_address VALUE=\"" );

				if (  detail !=null && detail.getEMailAddress() != null )
					out.print( detail.getEMailAddress() );

				if ( canedit )
					out.print( "\">" );
				return;
				}

			out.println( "<I>Unknown data item</I>" );
			}
		catch ( Exception ex )
			{
			out.println( "<HR><H4>There was a problem finding your personal data.</H4><HR>\n" );
			return;
			}
		}

	
	private void confirmuserdata( UserManagementSession um_session, Request req, PrintWriter out )
		throws IOException
		{
		String operation = req.getParameter( "op" );
		if ( operation==null )
				return;
				
		if ( operation.equalsIgnoreCase( "userdata" ) )
			saveuserdata( req, out );
			
		if ( operation.equalsIgnoreCase( "resetusername" ) )
			resetusername( um_session, req, out );

		if ( operation.equalsIgnoreCase( "resetpassword" ) )
			resetpassword( um_session, req, out );

		if ( operation.equalsIgnoreCase( "usermemo" ) )
			usermemo( req, out );
		}

	
	private void resetusername( UserManagementSession um_session, Request req, PrintWriter out )
		throws IOException
		{
		boolean canedit;
		int i, j;
		char c;
		String o, p, r, u, item, initials, user_name=null, message=null;
		PrimaryKey uid;
		User user=null, currentuser;
		UserDetail detail;
		PassPhrase pass=null, currentpass;
		
		
		try
			{
			currentuser = (User)BuildingContext.getContext().getUser();
			if ( currentuser == null )
				{
				out.println( "Technical problem - couldn't determine who you are." );
				return;
				}


			if ( req.getTemplateParameterCount()==0 )
				{
				user = currentuser;
				}
			else
				{
				uid = null;
				user = null;
				u = (String)req.getTemplateParameter( 0 );
				try
					{
					if ( u!=null )
						uid = new PrimaryKey( Integer.parseInt( u ) );
					}
				catch ( NumberFormatException nfex )
					{
					uid = null;
					}
				if ( uid!=null )
					user = User.findUser( uid );
					
				if ( user == null )
					{
					out.println( "<I>Unspecified user.</I>" );
					return;
					}
				}

			// Can edit entry is current user has sysadmin or manage access and
			// belongs to same zone
			// users can't reset their own user name
			canedit = req.getResource().checkPermission( Permission.SYSADMIN )           ||
			
					  ( req.getResource().checkPermission( Permission.MANAGE ) && 
						user.getZoneId().equals(currentuser.getZoneId())      )    ;
			if ( !canedit )
				{
				out.println( "<P><FONT COLOR=RED>You don't have the right to reset this user's password.</FONT></P>" );
				return;
				}

			currentpass = PassPhrase.findPassPhrase( "user_id = " + currentuser.getUserId() );
			pass = PassPhrase.findPassPhrase( "user_id = " + user.getUserId() );

			if ( currentpass == null )
				{
				out.println( "<P><FONT COLOR=RED>Couldn't find your pass phrase record.</FONT></P>" );
				return;
				}
			
			item = req.getParameter( "password" );
			if ( item==null || item.length()<1 )
				{
				out.println( "<P><FONT COLOR=RED>You must type your password into the box.</FONT></P>" );
				return;
				}
				
			Thread.sleep( 2000 );
			if ( !currentpass.isPassPhrase( item ) )
				{
				out.println( "<P><FONT COLOR=RED>The password you entered was not correct.</FONT></P>" );
				return;
				}
			
			if ( pass==null )
			    user_name = null;
			else
			    user_name = pass.getUserName();
			    
			message=null;
			message = um_session.resetUserName( user.getUserId() );
			out.print( "<P><FONT COLOR=RED><PRE>" );
			out.print( message );
			out.println( "</PRE></FONT></P>" );

			pass = PassPhrase.findPassPhrase( "user_id = " + user.getUserId() );
			UserManagementEvent event = 
					new UserManagementEvent( 
							UserManagementEvent.EVENT_DATA_CHANGE,
							req.getResource().getResourceId(),
							currentuser.getUserId(),
							currentuser.getUserId().equals( user.getUserId() )?null:user.getUserId(),
							null,
							"user name",
							user_name,
							pass.getUserName() );
			event.save();
			}
		catch ( Exception ex )
			{
			logException( null, "UserDirectoryFacility", "resetusername", 
			    "There was a problem saving personal data.",
			    ex );
			return;
			}
		}


	private void resetpassword( UserManagementSession um_session, Request req, PrintWriter out )
		throws IOException
		{
		boolean canedit;
		int i, j;
		char c;
		String o, p, r, u, item, initials, oldpass=null, message=null;
		PrimaryKey uid;
		User user=null, currentuser;
		UserDetail detail;
		PassPhrase pass=null, currentpass;
		
		
		try
			{
			currentuser = (User)BuildingContext.getContext().getUser();
			if ( currentuser == null )
				{
				out.println( "Technical problem - couldn't determine who you are." );
				return;
				}


			if ( req.getTemplateParameterCount()==0 )
				{
				user = currentuser;
				}
			else
				{
				uid = null;
				user = null;
				u = (String)req.getTemplateParameter( 0 );
				try
					{
					if ( u!=null )
						uid = new PrimaryKey( Integer.parseInt( u ) );
					}
				catch ( NumberFormatException nfex )
					{
					uid = null;
					}
				if ( uid!=null )
					user = User.findUser( uid );
					
				if ( user == null )
					{
					out.println( "<I>Unspecified user.</I>" );
					return;
					}
				}

			// Can edit entry is current user has sysadmin access or if the
			// current user has manage access and the target user
			// belongs in the same adminsitrative zone or if the current user
			// is looking at their own entry and has been given edit level access
			// to the tool.
			canedit = req.getResource().checkPermission( Permission.SYSADMIN )           ||
			
					  ( req.getResource().checkPermission( Permission.MANAGE ) && 
						user.getZoneId().equals(currentuser.getZoneId())      )     ||
						
					  ( req.getResource().checkPermission( Permission.EDIT ) && 
						user.getUserId().equals(currentuser.getUserId())      )   ;
			if ( !canedit )
				{
				out.println( "<P><FONT COLOR=RED>You don't have the right to reset this user's password.</FONT></P>" );
				return;
				}

			currentpass = PassPhrase.findPassPhrase( "user_id = " + currentuser.getUserId() );
			pass = PassPhrase.findPassPhrase( "user_id = " + user.getUserId() );

			if ( currentpass == null )
				{
				out.println( "<P><FONT COLOR=RED>Couldn't find your pass phrase record.</FONT></P>" );
				return;
				}
			
			if ( pass == null )
				{
				out.println( "<P><FONT COLOR=RED>Couldn't find the user's pass phrase record.</FONT></P>" );
				return;
				}

			item = req.getParameter( "password" );
			if ( item==null || item.length()<1 )
				{
				out.println( "<P><FONT COLOR=RED>You must type your password into the box.</FONT></P>" );
				return;
				}
				
			Thread.sleep( 2000 );
			if ( !currentpass.isPassPhrase( item ) )
				{
				out.println( "<P><FONT COLOR=RED>The password you entered was not correct.</FONT></P>" );
				return;
				}
			
			oldpass = pass.getPassPhrase();
			message=null;
			message = um_session.resetUserPassword( user.getUserId() );
			out.print( "<P><FONT COLOR=RED><PRE>" );
			out.print( message );
			out.println( "</PRE></FONT></P>" );

			UserManagementEvent event = 
				new UserManagementEvent( 
						UserManagementEvent.EVENT_PASSPHRASE_RESET,
						req.getResource().getResourceId(),
						currentuser.getUserId(),
						currentuser.getUserId().equals( user.getUserId() )?null:user.getUserId(),
						null,
						null,
						null,
						null );
			event.save();
			}
		catch ( Exception ex )
			{
			logException( null, "UserDirectoryFacility", "resetpassword", 
			    "There was a problem saving personal data.",
			    ex );
			if ( oldpass!=null && message==null )
				{
				try
					{
					um_session.setUserPassword( user.getUserId(), oldpass );
					}
				catch ( BuildingServerException bsex )
					{
					logException( null, "UserDirectoryFacility", "resetpassword", 
					    "There was another problem trying to set the password back to its old value.",
					    bsex );
					}
				}
			return;
			}
		}


	private void saveuserdata( Request req, PrintWriter out )
		throws IOException
		{
		boolean canedit;
		int i, j;
		char c;
		String o, p, r, u, item, old_item, initials;
		PrimaryKey uid;
		User user, currentuser;
		UserDetail detail;
		PassPhrase pass;
		UserManagementEvent event;
		
		try
			{
			currentuser = (User)BuildingContext.getContext().getUser();
			if ( currentuser == null )
				{
				out.println( "Technical problem - couldn't determine who you are." );
				return;
				}


			if ( req.getTemplateParameterCount()==0 )
				{
				user = currentuser;
				}
			else
				{
				uid = null;
				user = null;
				u = (String)req.getTemplateParameter( 0 );
				try
					{
					if ( u!=null )
						uid = new PrimaryKey( Integer.parseInt( u ) );
					}
				catch ( NumberFormatException nfex )
					{
					uid = null;
					}
				if ( uid!=null )
					user = User.findUser( uid );
					
				if ( user == null )
					{
					out.println( "<I>Unspecified user.</I>" );
					return;
					}
				}

			// Can edit entry is current user has sysadmin access or if the
			// current user has manage access and the target user
			// belongs in the same adminsitrative zone or if the current user
			// is looking at their own entry and has been given edit level access
			// to the tool.
			canedit = req.getResource().checkPermission( Permission.SYSADMIN )           ||
			
					  ( req.getResource().checkPermission( Permission.MANAGE ) && 
						user.getZoneId().equals(currentuser.getZoneId())      )     ||
						
					  ( req.getResource().checkPermission( Permission.EDIT ) && 
						user.getUserId().equals(currentuser.getUserId())      )   ;
			if ( !canedit )
				{
				out.println( "<P><FONT COLOR=RED>You don't have the right to edit this user's personal data.</FONT></P>" );
				return;
				}

			
			String[] fields = { "name", "surname", "initials" };

			
			for ( j=0; j< fields.length; j++ )
				{
				item = req.getParameter( fields[j] );
				if ( item == null )
					continue;

				item = item.trim();
				
				if ( j==2 )
					{
					initials = "";
	    			for ( i=0; i<item.length(); i++ )
						{
						c=item.charAt(i);
						if ( Character.isLetter( c ) )
							initials = initials + item.substring( i, i+1 ).toUpperCase();
						}
					if ( initials.length()==0 )
						{
						out.println( "<P><FONT COLOR=RED>The initials field wasn't saved because it didn't contain any letters.</FONT></P>" );
						continue;
						}
					item = initials;
					}
				
				if ( item.length()<1 )
					{
					out.print( "<P><FONT COLOR=RED>The " );
					out.print( fields[j] );
					out.println( " field wasn't saved because you can't leave this field empty.</FONT></P>" );
					continue;
					}
				if ( (j==0 || j==1) && item.length()>64 )
					{
					out.print( "<P><FONT COLOR=RED>The " );
					out.print( fields[j] );
					out.println( " field was saved but it was truncated because it exceeded 64 characters.</FONT></P>" );
					item = item.substring( 0, 64 );
					}
				if ( (j==2) && item.length()>8 )
					{
					out.print( "<P><FONT COLOR=RED>The " );
					out.print( fields[j] );
					out.println( " field was saved but it was truncated because it exceeded 8 characters.</FONT></P>" );
					item = item.substring( 0, 8 );
					}
					
	    		for ( i=0; i<item.length(); i++ )
					{
					c=item.charAt(i);
					if ( !Character.isLetterOrDigit( c ) &&   
						c != '_'  &&  
						c != '-'  &&  
						c != ' '  && 
						c != '\'' && 
						c != '.'       )
						{
						out.print( "<P><FONT COLOR=RED>The " );
						out.print( fields[j] );
						out.println( " field wasn't saved because names can only contain letters digits, '-', '_' or a space.</FONT></P>" );
						break;
						}
					}
				if ( i<item.length() )
					continue;
					
				switch ( j )
					{
					case 0:
						old_item = user.getName();
						if ( !item.equals( old_item ) )
							{
							user.setName( item );
							user.save();
							out.println( "<P><FONT COLOR=RED>Name was saved.</FONT></P>" );
							event = 
								new UserManagementEvent( 
										UserManagementEvent.EVENT_DATA_CHANGE,
										req.getResource().getResourceId(),
										currentuser.getUserId(),
										currentuser.getUserId().equals( user.getUserId() )?null:user.getUserId(),
										null,
										"name",
										old_item,
										item );
							event.save();
							}
						break;
					case 1:
						old_item = user.getSurname();
						if ( !item.equals( old_item ) )
							{
							user.setSurname( item );
							user.save();
							out.println( "<P><FONT COLOR=RED>Surname was saved.</FONT></P>" );
							event = 
								new UserManagementEvent( 
										UserManagementEvent.EVENT_DATA_CHANGE,
										req.getResource().getResourceId(),
										currentuser.getUserId(),
										currentuser.getUserId().equals( user.getUserId() )?null:user.getUserId(),
										null,
										"surname",
										old_item,
										item );
							event.save();
							}
						break;
					case 2:
						old_item = user.getInitials();
						if ( !item.equals( old_item ) )
							{
							user.setInitials( item );
							user.save();
							out.println( "<P><FONT COLOR=RED>Initials were saved.</FONT></P>" );
							event = 
								new UserManagementEvent( 
										UserManagementEvent.EVENT_DATA_CHANGE,
										req.getResource().getResourceId(),
										currentuser.getUserId(),
										currentuser.getUserId().equals( user.getUserId() )?null:user.getUserId(),
										null,
										"initials",
										old_item,
										item );
							event.save();
							}
						break;
					}
				}
				
			}
		catch ( Exception ex )
			{
			out.println( "<HR><H4>There was a problem saving personal data.</H4><HR>\n" );
			return;
			}
		}

	private void usermemo( Request req, PrintWriter out )
		throws IOException
		{
		boolean canedit;
		int i, j;
		char c;
		String u, memo;
		PrimaryKey uid;
		User user, currentuser;
		UserManagementEvent event;
		
		try
			{
			currentuser = (User)BuildingContext.getContext().getUser();
			if ( currentuser == null )
				{
				out.println( "Technical problem - couldn't determine who you are." );
				return;
				}


			if ( req.getTemplateParameterCount()==0 )
				{
				user = currentuser;
				}
			else
				{
				uid = null;
				user = null;
				u = (String)req.getTemplateParameter( 0 );
				try
					{
					if ( u!=null )
						uid = new PrimaryKey( Integer.parseInt( u ) );
					}
				catch ( NumberFormatException nfex )
					{
					uid = null;
					}
				if ( uid!=null )
					user = User.findUser( uid );
					
				if ( user == null )
					{
					out.println( "<I>Unspecified user.</I>" );
					return;
					}
				}

			// Can edit entry is current user has sysadmin access or if the
			// current user has manage access and the target user
			// belongs in the same adminsitrative zone or if the current user
			// is looking at their own entry and has been given edit level access
			// to the tool.
			canedit = req.getResource().checkPermission( Permission.SYSADMIN )           ||
			
					  ( req.getResource().checkPermission( Permission.MANAGE ) && 
						user.getZoneId().equals(currentuser.getZoneId())      );
			if ( !canedit )
				{
				out.println( "<P><FONT COLOR=RED>You don't have the right to record memos against this user record.</FONT></P>" );
				return;
				}

			memo = req.getParameter( "memo" );
			if ( memo !=null )
				memo = memo.trim();
			if ( memo==null || memo.length()==0 )
				{
				out.println( "<P><FONT COLOR=RED>The memo wasn't recorded because the text was empty.</FONT></P>" );
				return;
				}
			
			BigString big = new BigString();
			big.setString( memo );
			big.save();
			
			event = new UserManagementEvent( 
							UserManagementEvent.EVENT_MEMO,
							req.getResource().getResourceId(),
							currentuser.getUserId(),
							currentuser.getUserId().equals( user.getUserId() )?null:user.getUserId(),
							big.getBigStringId(),
							null,
							null,
							null );
			event.save();

			out.println( "<P><FONT COLOR=RED>Memo was recorded.</FONT></P>" );
			}
		catch ( Exception ex )
			{
			out.println( "<HR><H4>There was a problem recording the memo.</H4><HR>\n" );
			return;
			}
		}

		
	public void usereventlog(  Request req, PrintWriter out )
		throws IOException
		{
		boolean canedit;
		int j;
		Event event;
		StringBuffer where;
		String u;
		PrimaryKey uid;
		User user, currentuser;


        if ( out==null )
            return;

		if ( !BuildingContext.getContext().checkPermission( "manage" ) )
			{
			out.println( "<HR>You need manage access to view the log.<HR>" );
			return;
			}

		try
			{
			currentuser = (User)BuildingContext.getContext().getUser();
			if ( currentuser == null )
				{
				out.println( "Technical problem - couldn't determine who you are." );
				return;
				}


			if ( req.getTemplateParameterCount()==0 )
				{
				user = currentuser;
				}
			else
				{
				uid = null;
				user = null;
				u = (String)req.getTemplateParameter( 0 );
				try
					{
					if ( u!=null )
						uid = new PrimaryKey( Integer.parseInt( u ) );
					}
				catch ( NumberFormatException nfex )
					{
					uid = null;
					}
				if ( uid!=null )
					user = User.findUser( uid );
					
				if ( user == null )
					{
					out.println( "<I>Unspecified user.</I>" );
					return;
					}
				}

			// Can edit entry is current user has sysadmin access or if the
			// current user has manage access and the target user
			// belongs in the same adminsitrative zone or if the current user
			// is looking at their own entry and has been given edit level access
			// to the tool.
			canedit = req.getResource().checkPermission( Permission.SYSADMIN )           ||
			
					  ( req.getResource().checkPermission( Permission.MANAGE ) && 
						user.getZoneId().equals(currentuser.getZoneId())      );
			if ( !canedit )
				{
				out.println( "<P><FONT COLOR=RED>You don't have the right to record memos against this user record.</FONT></P>" );
				return;
				}

			where = new StringBuffer();
			where.append( "type = 24 AND passive_user_id = " );
			where.append( user.getUserId().toString() );
			
			Enumeration enum = Event.findEvents( where.toString(), "event_time" );
			
			PrintWriter writer = new PrintWriter( out );
			for ( j=0; enum.hasMoreElements();  )
				{
				event=(Event)enum.nextElement();
				
				if ( j==0 )
					out.println( "</A></H3><TABLE CLASS=bs-table-opaque>" );

				out.println( "<TR><TD><I>" );
				outputDate( out, event.getEventTime(), 0 );
				out.println( "</I></TD><TD>" );
				event.printMessage( writer, true );
				writer.flush();
				out.println( "</TD></TR>" );
				j++;
				}
			if ( j>0 )
				out.println( "</TABLE>" );
			else
				out.println( "<P>There are no events in the event log here.</P>" );
			}
		catch ( Exception ex )
			{
			out.println( "</TD></TR></TABLE><HR>There was a technical problem trying to get a list of events.<HR>" );
			out.println( ex.toString() );
			return;
			}
		
		}

		

	private void usersearchform( Request req, PrintWriter out, String item )
		throws IOException
		{
	
		try
			{
		    out.println( "<FORM METHOD=POST ACTION=bs_virtual_listusers.html>" );
                
            userSearchFields( req, out, item.equalsIgnoreCase("advanced"), true );
                
            out.println( "</FORM>" );
			}
		catch ( Exception ex )
			{
			out.println( "<HR><H4>There was a problem finding your users.</H4><HR>\n" );
			return;
			}
		}


	private boolean ifcanedituser( Request req )
		throws IOException
		{
		boolean canedit;
		String o, p, c, r, u;
		PrimaryKey uid;
		User user, currentuser;
		
		try
			{
			currentuser = (User)BuildingContext.getContext().getUser();
			if ( currentuser == null )
				return false;


			if ( req.getTemplateParameterCount()==0 )
				{
				user = currentuser;
				}
			else
				{
				uid = null;
				user = null;
				u = (String)req.getTemplateParameter( 0 );
				try
					{
					if ( u!=null )
						uid = new PrimaryKey( Integer.parseInt( u ) );
					}
				catch ( NumberFormatException nfex )
					{
					uid = null;
					}
				if ( uid!=null )
					user = User.findUser( uid );
					
				if ( user == null )
					return false;
				}

			// Can edit entry is current user has sysadmin access or if the
			// current user has manage access and the target user
			// belongs in the same adminsitrative zone or if the current user
			// is looking at their own entry and has been given edit level access
			// to the tool.
			canedit = req.getResource().checkPermission( Permission.SYSADMIN )           ||
			
					  ( req.getResource().checkPermission( Permission.MANAGE ) && 
						user.getZoneId().equals(currentuser.getZoneId())      )     ||
						
					  ( req.getResource().checkPermission( Permission.EDIT ) && 
						user.getUserId().equals(currentuser.getUserId())      )   ;
			}
		catch ( Exception ex )
			{
			return false;
			}
			
		return canedit;
		}

	}

