/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.servlets;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.servlets.format.*;

public class ConfOperations extends VeniceServlet
{
  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

  private static final String DELETE_CONFIRM_ATTR = "servlets.ConfOperations.delete.confirm";
  private static final String DELETE_CONFIRM_PARAM = "confirm";

  private static Category logger = Category.getInstance(ConfOperations.class.getName());

  /*--------------------------------------------------------------------------------
   * Internal functions
   *--------------------------------------------------------------------------------
   */

  private CreateConferenceDialog makeCreateConferenceDialog() throws ServletException
  {
    final String desired_name = "CreateConferenceDialog";
    DialogCache cache = DialogCache.getDialogCache(getServletContext());

    if (!(cache.isCached(desired_name)))
    { // create a template and save it off
      CreateConferenceDialog template = new CreateConferenceDialog();
      cache.saveTemplate(template);

    } // end if

    // return a new copy
    return (CreateConferenceDialog)(cache.getNewDialog(desired_name));

  } // end makeCreateConferenceDialog

  private EditConferenceDialog makeEditConferenceDialog(SecurityInfo sinf) throws ServletException
  {
    final String desired_name = "EditConferenceDialog";
    DialogCache cache = DialogCache.getDialogCache(getServletContext());

    if (!(cache.isCached(desired_name)))
    { // create a template and save it off
      EditConferenceDialog template = new EditConferenceDialog(sinf);
      cache.saveTemplate(template);

    } // end if

    // return a new copy
    return (EditConferenceDialog)(cache.getNewDialog(desired_name));

  } // end makeEditConferenceDialog

  private static boolean validateNewTopic(ServletRequest request, String on_error) throws ErrorBox
  {
    //boolean is_title_null, is_zp_null;

    String foo = request.getParameter("title");
    if (foo==null)
      throw new ErrorBox(null,"Title parameter was not specified.",on_error);
    //is_title_null = (foo.length()==0);

    foo = request.getParameter("pseud");
    if (foo==null)
      throw new ErrorBox(null,"Pseud parameter was not specified.",on_error);

    foo = request.getParameter("pb");
    if (foo==null)
      throw new ErrorBox(null,"Body text was not specified.",on_error);
    //is_zp_null = (foo.length()==0);

    /* EJB 4/5/2001 - remove this for consistency.  FUTURE: bring it back under a global option?
    return is_title_null || is_zp_null;
    -- end removed code */

    return false;
      
  } // end validateNewTopic

  private static boolean getFlag(ServletRequest request, String param, String on_error) throws ErrorBox
  {
    String foo = request.getParameter(param);
    if (foo==null)
      throw new ErrorBox(null,"Parameter not specified!",on_error);

    int value;
    try
    { // try to get a numeric value
      value = Integer.parseInt(foo);

    } // end try
    catch (NumberFormatException nfe)
    { // unable to decode value
      throw new ErrorBox(null,"Invalid parameter value!",on_error);

    } // end catch

    if (value==0)
      return false;
    else if (value==1)
      return true;
    else
      throw new ErrorBox(null,"Invalid parameter value!",on_error);

  } // end getFlag

  /*--------------------------------------------------------------------------------
   * Overrides from class HttpServlet
   *--------------------------------------------------------------------------------
   */

  public String getServletInfo()
  {
    String rc = "ConfOperations servlet - General conference operations (list, create, etc.)\n"
              + "Part of the Venice Web Communities System\n";
    return rc;

  } // end getServletInfo

  /*--------------------------------------------------------------------------------
   * Overrides from class VeniceServlet
   *--------------------------------------------------------------------------------
   */

  /*
   * ConfOperations commands:
   * A = Manage Conference Aliases (requires conference parameter)
   * C = Create conference
   * DEL = Delete conference (requires conference parameter)
   * E = Edit Conference Settings (requires conference parameter)
   * FX = Fixseen (requires conference parameter)
   * H = Add Conference to Hotlist (requires conference parameter)
   * M = Manage Conference Membership (requires conference parameter)
   * Q = Display Conference Manage menu (requires conference parameter)
   * RP = Report on Posters (requires conference parameter)
   * RR = Report on Readers (requires conference parameter)
   * S = Manage conference ordering/sequence
   * SDEL = Delete conference from sequence manager menu
   * SH = Hide/show conference from sequence manager menu
   * SS = Change conference sequence from sequence manager menu
   * T = Create topic (requires conference parameter)
   * Other = Display list of conferences in community
   */

  protected VeniceContent doVeniceGet(HttpServletRequest request, VeniceEngine engine,
				      UserContext user, RenderData rdat)
      throws ServletException, IOException, VeniceServletResult
  {
    // get the community
    CommunityContext comm = getCommunityParameter(request,user,true,"top");
    changeMenuCommunity(request,comm);
    String on_error = "confops?sig=" + comm.getCommunityID();

    // get the command we want to use
    String cmd = getStandardCommandParam(request);

    if (cmd.equals("S"))
    { // "S" = Manage conferences sequence
      if (!(comm.canManageConferences()))
	return new ErrorBox("Access Error","You are not permitted to manage conferences in this community.",
			    on_error);

      try
      { // display the Conference Sequence screen
	setMyLocation(request,"confops?cmd=S&sig=" + comm.getCommunityID());
	return new ConferenceSequence(comm);

      } // end try
      catch (DataException de)
      { // oops - database error here
	return new ErrorBox("Database Error","Database error getting conference list: " + de.getMessage(),
			    on_error);

      } // end catch
      catch (AccessError ae)
      { // some sort of access error - display an error dialog
	return new ErrorBox("Access Error",ae.getMessage(),on_error);

      } // end catch

    } // end if ("S" command)

    if (cmd.equals("SH"))
    { // "SH" = Hide/show conference (requires conference parameter)
      if (!(comm.canManageConferences()))
	return new ErrorBox("Access Error","You are not permitted to manage conferences in this community.",
			    on_error);

      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&cmd=S";

      if (!(conf.canChangeConference()))
	return new ErrorBox("Access Error","You do not have permission to modify this conference.",on_error);

      boolean new_flag = getFlag(request,"flag",on_error);

      try
      { // go set the hide flag
	conf.setHideList(new_flag);

      } // end try
      catch (DataException de)
      { // database error - display appropriate dialog
	return new ErrorBox("Database Error","Database error setting hide flag: " + de.getMessage(),
			    on_error);

      } // end catch
      catch (AccessError ae)
      { // some sort of access error - display an error dialog
	return new ErrorBox("Access Error",ae.getMessage(),on_error);

      } // end catch

      throw new RedirectResult(on_error);  // trap back to the main display

    } // end if ("SH" command)

    if (cmd.equals("SS"))
    { // "SS" = Change conference sequence (requires conference parameter)
      if (!(comm.canManageConferences()))
	return new ErrorBox("Access Error","You are not permitted to manage conferences in this community.",
			    on_error);

      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&cmd=S";

      // we need a second conference parameter to exchange with
      ConferenceContext other_conf = getConferenceParameter(request.getParameter("oc"),comm,true,on_error);

      if (!(conf.canChangeConference()) || !(other_conf.canChangeConference()))
	return new ErrorBox("Access Error","You do not have permission to modify this conference.",on_error);

      try
      { // get the two sequences
	short this_seq = conf.getSequence();
	short other_seq = other_conf.getSequence();

	// now exchange them
	conf.setSequence(other_seq);
	boolean restore = true;
	try
	{ // set the second conference sequence
	  other_conf.setSequence(this_seq);
	  restore = false;

	} // end try
	finally
	{ // undo first set on error
	  if (restore)
	    conf.setSequence(this_seq);

	} // end finally

      } // end try
      catch (DataException de)
      { // database error - display appropriate dialog
	return new ErrorBox("Database Error","Database error changing sequence: " + de.getMessage(),
			    on_error);

      } // end catch
      catch (AccessError ae)
      { // some sort of access error - display an error dialog
	return new ErrorBox("Access Error",ae.getMessage(),on_error);

      } // end catch

      throw new RedirectResult(on_error);  // trap back to the main display

    } // end if ("SS" command)

    if (cmd.equals("SDEL"))
    { // "SDEL" = Delete conference (requires conference parameter)
      if (!(comm.canManageConferences()))
	return new ErrorBox("Access Error","You are not permitted to manage conferences in this community.",
			    on_error);

      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&cmd=S";

      if (!(conf.canDeleteConference()))
	return new ErrorBox("Access Error","You do not have permission to delete this conference.",on_error);

      if (ConfirmBox.isConfirmed(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM))
      { // we are confirmed - delete the conference!
	try
	{ // tell it to go away
	  conf.delete();

	} // end try
	catch (DataException de)
	{ // something wrong in the database
	  return new ErrorBox("Database Error","Database error deleting conference: " + de.getMessage(),
			      on_error);

	} // end catch
	catch (AccessError ae)
	{ // some lack of access is causing problems
	  return new ErrorBox("Access Error",ae.getMessage(),on_error);

	} // end catch

	// that's it - trap back to the main display
	throw new RedirectResult(on_error);

      } // end if
      else
      { // generate a confirmation box and wait for confirmation
	String message = "You are about to permanently delete the \"" + conf.getName() + "\" conference!  "
	               + "Are you sure you want to do this?";
	return new ConfirmBox(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM,"Delete Conference",message,
			      "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=SDEL",
			      on_error);

      } // end else

    } // end if ("SDEL" command)

    if (cmd.equals("C"))
    { // "C" = "Create conference"
      if (!(comm.canCreateConference()))
	return new ErrorBox("Access Error","You are not permitted to create conferences in this community.",
			    on_error);

      // make the "create" dialog
      CreateConferenceDialog dlg = makeCreateConferenceDialog();
      dlg.setupDialog(engine,comm);
      setMyLocation(request,on_error + "&cmd=C");
      return dlg;

    } // end if ("C" command)

    if (cmd.equals("T"))
    { // "T" = "Create topic" (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confdisp?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID();

      // Create the new topic form.
      NewTopicForm ntf = new NewTopicForm(comm,conf);
      ntf.setupNewRequest();
      setMyLocation(request,"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=T");
      return ntf;

    } // end if ("T" command)

    if (cmd.equals("Q"))
    { // "Q" = display Manage menu (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confdisp?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID();

      // display the "Manage Conference" display
      setMyLocation(request,"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q");
      return new ManageConference(comm,conf);

    } // end if ("Q" command)

    if (cmd.equals("FX"))
    { // "FX" = the dreaded fixseen :-) - catches up the entire conference
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confdisp?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID();

      try
      { // do the fixseen operation
	conf.fixSeen();

      } // end try
      catch (AccessError ae)
      { // some sort of access error - display an error dialog
	return new ErrorBox("Access Error",ae.getMessage(),on_error);

      } // end catch
      catch (DataException de)
      { // some sort of error in the database
	return new ErrorBox("Database Error","Database error catching up conference: " + de.getMessage(),
			    on_error);

      } // end catch

      return null;  // null response here

    } // end if ("FX" command)

    if (cmd.equals("E"))
    { // "E" = "Edit Conference Settings" (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q";

      if (!(conf.canChangeConference()))
	return new ErrorBox("Access Error","You are not permitted to change this conference's settings.",
			    on_error);

      // create and return the Edit Conference dialog
      EditConferenceDialog dlg = makeEditConferenceDialog(conf.getSecurityInfo());
      try
      { // set up and return the dialog
	dlg.setupDialog(comm,conf);
	setMyLocation(request,"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=E");
	return dlg;

      } // end try
      catch (AccessError ae)
      { // some sort of access error - display an error dialog
	return new ErrorBox("Access Error",ae.getMessage(),on_error);

      } // end catch
      catch (DataException de)
      { // database error retrieving the conference information
	return new ErrorBox("Database Error","Database error getting conference information: "
			    + de.getMessage(),on_error);

      } // end catch

    } // end if ("E" command)

    if (cmd.equals("A"))
    { // "A" = "Manage Aliases" (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q";

      if (!(conf.canChangeConference()))
	return new ErrorBox("Access Error","You are not permitted to change this conference's aliases.",
			    on_error);

      // process alias removal link
      String remove = request.getParameter("rem");
      if (!(StringUtil.isStringEmpty(remove)))
      { // do removal of an alias
	try
	{ // go ahead and remove the alias!
	  conf.removeAlias(remove);

	} // end try
	catch (AccessError ae)
	{ // some sort of access error - display an error dialog
	  return new ErrorBox("Access Error",ae.getMessage(),on_error);

	} // end catch
	catch (DataException de)
	{ // database error creating the conference
	  return new ErrorBox("Database Error","Database error removing alias: " + de.getMessage(),
			      on_error);

	} // end catch
	
      } // end if (removing an alias)

      // display the "Manage Conference Aliases" display
      try
      { // generate the display box
	setMyLocation(request,"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=A");
	return new ManageConferenceAliases(comm,conf);

      } // end try
      catch (DataException de)
      { // error generating the display box
	return new ErrorBox("Database Error","Database error displaying aliases: " + de.getMessage(),
			    on_error);

      } // end catch

    } // end if ("A" command)

    if (cmd.equals("QR"))
    { // "QR" = "Reports Menu" (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q";

      try
      { // display the "Conference Reports" display
	setMyLocation(request,"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=QR");
	return new ReportConferenceMenu(comm,conf);

      } // end try
      catch (DataException de)
      { // unable to get the data for the list
	return new ErrorBox("Database Error","Database error getting topic list: " + de.getMessage(),on_error);

      } // end catch
      catch (AccessError ae)
      { // some sort of access error - display an error dialog
	return new ErrorBox("Access Error",ae.getMessage(),on_error);

      } // end catch

    } // end if ("QR" command)

    if (cmd.equals("RP") || cmd.equals("RR"))
    { // "RP" = "Report Posters," "RR" = "Report Readers" (requires conference parameter, optional topic)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      TopicContext topic = getTopicParameter(request,conf,false,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=QR";

      try
      { // generate the listing on this page
	String my_loc = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID();
	if (topic!=null)
	  my_loc += ("&top=" + topic.getTopicNumber());
	setMyLocation(request,my_loc + "&cmd=" + cmd);
	return new ConferenceActivity(comm,conf,topic,cmd.equals("RP"));

      } // end try
      catch (DataException de)
      { // unable to get the data for the list
	return new ErrorBox("Database Error","Database error displaying conference users: " + de.getMessage(),
			    on_error);

      } // end catch
      catch (AccessError ae)
      { // some sort of access error - display an error dialog
	return new ErrorBox("Access Error",ae.getMessage(),on_error);

      } // end catch

    } // end if ("RP" and "RR" commands)

    if (cmd.equals("M"))
    { // "M" - Manage Conference Membership (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q";

      try
      { // display the conference member list!
	ConferenceMembership m = new ConferenceMembership(engine,comm,conf);
	m.doConferenceMemberList();
	setMyLocation(request,"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=M");
	return m;

      } // end try
      catch (DataException de)
      { // something wrong in the database
	return new ErrorBox("Database Error","Database error listing conference members: " + de.getMessage(),
			    on_error);

      } // end catch
      catch (AccessError ae)
      { // some lack of access is causing problems
	return new ErrorBox("Access Error",ae.getMessage(),on_error);

      } // end catch

    } // end if ("M" command)

    if (cmd.equals("H"))
    { // "H" = "Add Conference To Hotlist" (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confdisp?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID();

      try
      { // add to the hotlist
	conf.addToHotlist();

	// and trap back to the conference display
	throw new RedirectResult(on_error);

      } // end try
      catch (DataException de)
      { // something wrong in the database
	return new ErrorBox("Database Error","Database error adding to hotlist: " + de.getMessage(),
			    on_error);

      } // end catch

    } // end if ("H" command)

    if (cmd.equals("DEL"))
    { // "DEL" = "Delete Conference (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q";

      if (!(conf.canDeleteConference()))
	return new ErrorBox("Access Error","You do not have permission to delete this conference.",on_error);

      if (ConfirmBox.isConfirmed(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM))
      { // we are confirmed - delete the conference!
	try
	{ // tell it to go away
	  conf.delete();

	} // end try
	catch (DataException de)
	{ // something wrong in the database
	  return new ErrorBox("Database Error","Database error deleting conference: " + de.getMessage(),
			      on_error);

	} // end catch
	catch (AccessError ae)
	{ // some lack of access is causing problems
	  return new ErrorBox("Access Error",ae.getMessage(),on_error);

	} // end catch

	// that's it - trap back to the main conference list
	throw new RedirectResult("confops?sig=" + comm.getCommunityID());

      } // end if
      else
      { // generate a confirmation box and wait for confirmation
	String message = "You are about to permanently delete the \"" + conf.getName() + "\" conference!  "
	               + "Are you sure you want to do this?";
	return new ConfirmBox(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM,"Delete Conference",message,
			      "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=DEL",
			      on_error);

      } // end else

    } // end if ("DEL" command)

    // Any unrecognized command shows us the conference list.
    on_error = "sigprofile?sig=" + comm.getCommunityID();
    try
    { // make a conference listing
      setMyLocation(request,"confops?sig=" + comm.getCommunityID());
      return new ConferenceListing(comm);

    } // end try
    catch (DataException de)
    { // something wrong in the database
      return new ErrorBox("Database Error","Database error finding conferences: " + de.getMessage(),on_error);

    } // end catch
    catch (AccessError ae)
    { // some lack of access is causing problems
      return new ErrorBox("Access Error",ae.getMessage(),on_error);

    } // end catch

  } // end doVeniceGet

  protected VeniceContent doVenicePost(HttpServletRequest request, VeniceEngine engine,
				       UserContext user, RenderData rdat)
      throws ServletException, IOException, VeniceServletResult
  {
    // get the community
    CommunityContext comm = getCommunityParameter(request,user,true,"top");
    changeMenuCommunity(request,comm);
    String on_error = "confops?sig=" + comm.getCommunityID();

    // get the command we want to use
    String cmd = getStandardCommandParam(request);

    if (cmd.equals("C"))
    { // "C" = "Create Conference"
      if (!(comm.canCreateConference()))
	return new ErrorBox("Access Error","You are not permitted to create conferences in this community.",
			    on_error);

      // load up the create conference dialog!
      CreateConferenceDialog dlg = makeCreateConferenceDialog();
      dlg.setupDialog(engine,comm);

      if (dlg.isButtonClicked(request,"cancel"))
	throw new RedirectResult(on_error); // they chickened out - go back to the conference list

      if (dlg.isButtonClicked(request,"create"))
      { // OK, they actually want to create the new conference...
	dlg.loadValues(request);  // load the form data

	try
	{ // attempt to create the conference!
	  ConferenceContext conf = dlg.doDialog(comm);

	  // success! redirect to the conference's topic list
	  throw new RedirectResult("confdisp?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID());

	} // end try
	catch (ValidationException ve)
	{ // validation error - throw it back to the user
	  dlg.resetOnError(ve.getMessage() + " Please try again.");

	} // end catch
	catch (AccessError ae)
	{ // some sort of access error - display an error dialog
	  return new ErrorBox("Access Error",ae.getMessage(),on_error);

	} // end catch
	catch (DataException de)
	{ // database error creating the conference
	  return new ErrorBox("Database Error","Database error creating conference: " + de.getMessage(),
			      on_error);

	} // end catch

	setMyLocation(request,on_error + "&cmd=C");
	return dlg;  // redisplay the dialog

      } // end if ("create" button clicked)

       // error - don't know what button was clicked
      logger.error("no known button click on ConfOperations.doPost, cmd=C");
      return new ErrorBox("Internal Error","Unknown command button pressed",on_error);

    } // end if ("C" command)

    if (cmd.equals("T"))
    { // "T" command = Create New Topic (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confdisp?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID();

      // determine what to do based on the button pressed
      if (isImageButtonClicked(request,"cancel"))
	throw new RedirectResult(on_error); // the user chickened out - go back to the conference display

      if (isImageButtonClicked(request,"preview"))
      { // generate a preview and redisplay the form
	NewTopicForm ntf = new NewTopicForm(comm,conf);

	try
	{ // generate a preview display
	  ntf.generatePreview(engine,conf,request);

	} // end try
	catch (ValidationException ve)
	{ // something messed up in the preview generation
	  return new ErrorBox(null,ve.getMessage(),on_error);

	} // end catch

	/* EJB 4/5/2001 - code removed for consistency - FUTURE: bring it back controlled by
	   a global option?
	if (ntf.isNullRequest())
	  return null;  // no title or text specified - "204 No Content"
	-- end removed code */ 

	setMyLocation(request,"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=T");
	return ntf;

      } // end if ("preview" clicked)

      if (isImageButtonClicked(request,"post"))
      { // first validate that we've got all the parameters
	if (validateNewTopic(request,on_error))
	  return null; // this is a null request - send a null response

	try
	{ // add the new topic!
	  TopicContext topic = conf.addTopic(request.getParameter("title"),request.getParameter("pseud"),
					     request.getParameter("pb"));

	  final String yes = "Y";
	  if (yes.equals(request.getParameter("attach")))
	  { // we need to upload an attachment for this post
	    setMyLocation(request,on_error);
	    return new AttachmentForm(comm,conf,topic.getMessage(0),on_error);
	    
	  } // end if

	} // end try
	catch (DataException de)
	{ // display a database error
	  return new ErrorBox("Database Error","Database error adding topic: " + de.getMessage(),on_error);

	} // end catch
	catch (AccessError ae)
	{ // some sort of access problem
	  return new ErrorBox("Access Error",ae.getMessage(),on_error);

	} // end catch

	// jump back to the form under normal circumstances
	throw new RedirectResult(on_error);

      } // end if ("post" clicked)

      // we don't know what button was pressed
      logger.error("no known button click on ConfOperations.doPost, cmd=T");
      return new ErrorBox("Internal Error","Unknown command button pressed",on_error);

    } // end if ("T" command)
    
    if (cmd.equals("P"))
    { // "P" = Set default pseud (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confdisp?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID();

      try
      { // go set the pseud!
	String pseud = request.getParameter("pseud");
	if (pseud!=null)
	  conf.setDefaultPseud(pseud);

      } // end try
      catch (DataException de)
      { // oops - there was a problem!
	return new ErrorBox("Database Error","Database error setting pseud: " + de.getMessage(),on_error);

      } // end catch

      return null;  // don't change the view

    } // end if ("P" command)

    if (cmd.equals("E"))
    { // "E" = "Edit Conference Settings" (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q";

      if (!(conf.canChangeConference()))
	return new ErrorBox("Access Error","You are not permitted to change this conference's settings.",
			    on_error);

      // create the dialog class
      EditConferenceDialog dlg = makeEditConferenceDialog(conf.getSecurityInfo());

      if (dlg.isButtonClicked(request,"cancel"))
	throw new RedirectResult(on_error); // they chickened out - go back to the conference list

      if (dlg.isButtonClicked(request,"update"))
      { // they're changing the conference - do what you have to
	dlg.loadValues(request); // load the form data

	try
	{ // run that baby!
	  dlg.doDialog(conf);

	  // success - return back to where we started from
	  throw new RedirectResult(on_error);

	} // end try
	catch (ValidationException ve)
	{ // validation error - throw it back to the user
	  dlg.resetOnError(comm,conf,ve.getMessage() + " Please try again.");

	} // end catch
	catch (AccessError ae)
	{ // some sort of access error - display an error dialog
	  return new ErrorBox("Access Error",ae.getMessage(),on_error);

	} // end catch
	catch (DataException de)
	{ // database error creating the conference
	  return new ErrorBox("Database Error","Database error updating conference: " + de.getMessage(),
			      on_error);

	} // end catch

	setMyLocation(request,"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=E");
	return dlg;  // redisplay the dialog

      } // end if

    } // end if ("E" command)

    if (cmd.equals("A"))
    { // "A" = "Add Alias" (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q";

      if (!(conf.canChangeConference()))
	return new ErrorBox("Access Error","You are not permitted to change this conference's settings.",
			    on_error);

      String new_alias = request.getParameter("alias");
      if (StringUtil.isStringEmpty(new_alias))
	return null;  // this is a no-op

      on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=A";
      String error_message = null;

      if (IDUtils.isValidVeniceID(new_alias))
      { // the alias we have netered is perfectly valid...
	try
	{ // go ahead and add the alias!
	  conf.addAlias(new_alias);

	} // end try
	catch (AccessError ae)
	{ // some sort of access error - display an error dialog
	  return new ErrorBox("Access Error",ae.getMessage(),on_error);

	} // end catch
	catch (DataException de)
	{ // database error creating the conference
	  return new ErrorBox("Database Error","Database error adding alias: " + de.getMessage(),
			      on_error);

	} // end catch
	
      } // end if
      else  // alias is not valid
	error_message = "The alias you have entered is not a valid identifier.  Please try again.";

      // redisplay the "Manage Conference Aliases" display
      try
      { // generate the display box
	setMyLocation(request,on_error);
	return new ManageConferenceAliases(comm,conf);

      } // end try
      catch (DataException de)
      { // error generating the display box
	return new ErrorBox("Database Error","Database error displaying aliases: " + de.getMessage(),
			    "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q");

      } // end catch
      
    } // end if ("A" command)

    if (cmd.equals("M"))
    { // "M" - Manage Conference Membership (requires conference parameter)
      ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
      on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=M";

      if (isImageButtonClicked(request,"update"))
      { // the "update" command that changes all the security levels
	HashMap org_vals = new HashMap();
	HashMap new_vals = new HashMap();
	try
	{ // retrieve all parameters and filter them for the levels
	  Enumeration p_names = request.getParameterNames();
	  while (p_names.hasMoreElements())
	  { // examine each parameter name in turn
	    String p_name = (String)(p_names.nextElement());
	    if (p_name.startsWith("zxcur_"))
	    { // this is a current value (from a hidden field)
	      int uid = Integer.parseInt(p_name.substring(6));
	      int level = Integer.parseInt(request.getParameter(p_name));
	      org_vals.put(new Integer(uid),new Integer(level));

	    } // end if
	    else if (p_name.startsWith("zxnew_"))
	    { // this is a new value (from a dropdown list box)
	      int uid = Integer.parseInt(p_name.substring(6));
	      int level = Integer.parseInt(request.getParameter(p_name));
	      new_vals.put(new Integer(uid),new Integer(level));

	    } // end else if

	  } // end while

	  if (org_vals.size()!=new_vals.size())
	    return new ErrorBox(null,"Invalid parameters.",on_error);

	} // end try
	catch (NumberFormatException nfe)
	{ // error converting the parameters
	  return new ErrorBox(null,"Invalid parameter conversion.",on_error);

	} // end catch

	try
	{ // loop through the hashmaps and set the value
	  Iterator it = org_vals.keySet().iterator();
	  while (it.hasNext())
	  { // extract the UID, old level, and new level
	    Integer uid = (Integer)(it.next());
	    Integer org_level = (Integer)(org_vals.get(uid));
	    Integer new_level = (Integer)(new_vals.get(uid));
	    if (new_level==null)   // whoops
	      return new ErrorBox(null,"Invalid new level parameter.",on_error);
	    int new_level_x = new_level.intValue();
	    if (new_level_x==0)
	      new_level_x = -1;

	    // call down to set the membership level
	    if (org_level.intValue()!=new_level_x)
	      conf.setMembership(uid.intValue(),new_level_x);

	  } // end while

	} // end try
	catch (AccessError ae)
	{ // some sort of access error - display an error dialog
	  return new ErrorBox("Access Error",ae.getMessage(),on_error);

	} // end catch
	catch (DataException de)
	{ // database error creating the conference
	  return new ErrorBox("Database Error","Database error setting memberships: " + de.getMessage(),
			      on_error);

	} // end catch
	
	// trap back to the conference membership display
	throw new RedirectResult(on_error);

      } // end if ("update" clicked)

      if (   isImageButtonClicked(request,"search") || isImageButtonClicked(request,"previous")
	  || isImageButtonClicked(request,"next"))
      { // create the new dialog box
	ConferenceMembership m = new ConferenceMembership(engine,comm,conf);

	try
	{ // perform the search!
	  m.doSearch(request);

	} // end try
	catch (ValidationException ve)
	{ // validation error - throw it back to the user
	  return new ErrorBox(null,ve.getMessage() + " Please try again.",on_error);

	} // end catch
	catch (AccessError ae)
	{ // some sort of access error - display an error dialog
	  return new ErrorBox("Access Error",ae.getMessage(),on_error);

	} // end catch
	catch (DataException de)
	{ // database error creating the conference
	  return new ErrorBox("Database Error","Database error updating conference: " + de.getMessage(),
			      on_error);

	} // end catch

	setMyLocation(request,on_error);
	return m;

      } // end if (search function clicked)

      // we don't know what button was pressed
      logger.error("no known button click on ConfOperations.doPost, cmd=M");
      return new ErrorBox("Internal Error","Unknown command button pressed",on_error);

    } // end if ("M" command)

    // unrecognized command!
    logger.error("invalid command to ConfOperations.doPost: " + cmd);
    return new ErrorBox("Internal Error","Invalid command to ConfOperations.doPost",on_error);

  } // end doVenicePost

} // end class ConfOperations
