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

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.ValidationException;
import com.silverwrist.venice.security.Role;
import com.silverwrist.venice.core.*;

public class ConferenceMembership implements JSPRender, SearchMode
{
  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

  // Attribute name for request attribute
  protected static final String ATTR_NAME = "com.silverwrist.venice.content.ConferenceMembership";

  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private VeniceEngine engine;            // reference to the engine
  private SIGContext sig;                 // the SIG we're in
  private ConferenceContext conf;         // the conference being listed
  private List display_list = null;       // list of members to display
  private boolean conf_members = false;   // is this a list of conference members?
  private int field = -1;                 // search field
  private int mode = -1;                  // search mode
  private String term = null;             // search term
  private int offset = 0;                 // search result offset
  private int find_count = -1;            // search results count
  private List role_choices;              // the list of security roles

  /*--------------------------------------------------------------------------------
   * Constructors
   *--------------------------------------------------------------------------------
   */

  public ConferenceMembership(VeniceEngine engine, SIGContext sig, ConferenceContext conf)
  {
    this.engine = engine;
    this.sig = sig;
    this.conf = conf;
    this.role_choices = Role.getConferenceMemberLevelChoices();

  } // end constructor

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

  private static int getParamInt(ServletRequest request, String name, int default_val)
  {
    String str = request.getParameter(name);
    if (str==null)
      return -1;

    try
    { // parse the integer value
      return Integer.parseInt(str);

    } // end try
    catch (NumberFormatException nfe)
    { // in case of conversion error, return default
      return default_val;

    } // end catch

  } // end getParamInt

  private static boolean isImageButtonClicked(ServletRequest request, String name)
  {
    String val = request.getParameter(name + ".x");
    return (val!=null);

  } // end isImageButtonClicked

  /*--------------------------------------------------------------------------------
   * External static functions
   *--------------------------------------------------------------------------------
   */

  public static ConferenceMembership retrieve(ServletRequest request)
  {
    return (ConferenceMembership)(request.getAttribute(ATTR_NAME));

  } // end retrieve

  /*--------------------------------------------------------------------------------
   * Implementations from interface VeniceContent
   *--------------------------------------------------------------------------------
   */

  public String getPageTitle(RenderData rdat)
  {
    return "Membership in Conference " + conf.getName();

  } // end getPageTitle

  /*--------------------------------------------------------------------------------
   * Implementations from interface JSPRender
   *--------------------------------------------------------------------------------
   */

  public void store(ServletRequest request)
  {
    request.setAttribute(ATTR_NAME,this);

  } // end store

  public String getTargetJSPName()
  {
    return "conf_member.jsp";

  } // end getTargetJSPName

  /*--------------------------------------------------------------------------------
   * External operations
   *--------------------------------------------------------------------------------
   */

  public void doConferenceMemberList() throws DataException, AccessError
  {
    this.display_list = conf.getMemberList();
    this.conf_members = true;
    this.term = "";

  } // end doConferenceMemberList

  public void doSearch(ServletRequest request) throws ValidationException, DataException, AccessError
  {
    // Validate the search field parameter.
    field = getParamInt(request,"field",FIELD_USER_NAME);
    if (   (field!=FIELD_USER_NAME) && (field!=FIELD_USER_DESCRIPTION) && (field!=FIELD_USER_GIVEN_NAME)
	   && (field!=FIELD_USER_FAMILY_NAME))
      throw new ValidationException("The field search parameter is not valid.");

    // Validate the search mode parameter.
    mode = getParamInt(request,"mode",SEARCH_PREFIX);
    if ((mode!=SEARCH_PREFIX) && (mode!=SEARCH_SUBSTRING) && (mode!=SEARCH_REGEXP))
      throw new ValidationException("The search mode parameter is not valid.");

    // Retrieve the search term parameter.
    term = request.getParameter("term");
    if (term==null)
      term = "";

    // Retrieve the offset and find count parameters.
    offset = getParamInt(request,"ofs",0);
    find_count = getParamInt(request,"fcount",-1);

    // Adjust the search return offset based on the command button click.
    int count = getNumResultsDisplayed();
    if (isImageButtonClicked(request,"search"))
      offset = 0;
    else if (isImageButtonClicked(request,"previous"))
    { // adjust the offset in the reverse direction
      offset -= count;
      if (offset<0)
	offset = 0;

    } // end else if
    else if (isImageButtonClicked(request,"next"))
      offset += count;  // go forwards instead
    else
      throw new ValidationException("Unable to determine what action triggered the form.");

    // Perform the search!
    List intermediate = sig.searchForMembers(field,mode,term,offset,count);
    if (find_count<0)
      find_count = sig.getSearchMemberCount(field,mode,term);

    // Create the real display list by getting the conference security levels.
    Iterator it = intermediate.iterator();
    Vector rc = new Vector(count+1);
    while (it.hasNext())
    { // loop around and find the member level of every one
      UserFound uf = (UserFound)(it.next());
      int new_level = conf.getMemberLevel(uf.getUID());
      if (new_level==-1)
	new_level = 0;
      rc.add(uf.createNewLevel(new_level));

    } // end while

    display_list = rc;  // save display list for display

  } // end doSearch

  public int getSIGID()
  {
    return sig.getSIGID();

  } // end getSIGID

  public int getConfID()
  {
    return conf.getConfID();

  } // end getConfID

  public String getSIGName()
  {
    return sig.getName();

  } // end getSIGName

  public String getConfName()
  {
    return conf.getName();

  } // end getConfName

  public String getLocator()
  {
    return "sig=" + sig.getSIGID() + "&conf=" + conf.getConfID();

  } // end getLocator

  public boolean displayList()
  {
    if ((display_list==null) || (display_list.size()==0))
      return false;
    if (conf_members && (display_list.size()>engine.getMaxNumConferenceMembersDisplay()))
      return false;
    return true;

  } // end displayList

  public boolean conferenceMemberList()
  {
    return conf_members;

  } // end conferenceMemberList

  public int getSearchField()
  {
    return field;

  } // end getSearchField

  public int getSearchMode()
  {
    return mode;

  } // end getSearchMode

  public boolean searchFieldIs(int value)
  {
    return (field==value);

  } // end searchFieldIs

  public boolean searchModeIs(int value)
  {
    return (mode==value);

  } // end searchModeIs

  public String getSearchTerm()
  {
    return term;

  } // end getSearchTerm

  public int getFindCount()
  {
    return find_count;

  } // end getFindCount

  public int getOffset()
  {
    return offset;

  } // end getOffset

  public int getSize()
  {
    return display_list.size();

  } // end getSize

  public int getNumResultsDisplayed()
  {
    return engine.getStdNumSearchResults();

  } // end getNumResultsDisplayed

  public UserFound getItem(int ndx)
  {
    return (UserFound)(display_list.get(ndx));

  } // end getItem

  public void outputDropDown(Writer out, int uid, int cur_level) throws IOException
  {
    out.write("<INPUT TYPE=HIDDEN NAME=\"zxcur_" + uid + "\" VALUE=\"" + cur_level + "\">\n");
    out.write("<SELECT NAME=\"zxnew_" + uid + "\" SIZE=1>\n");
    Iterator it = role_choices.iterator();
    while (it.hasNext())
    { // output the <OPTION> lines for the dropdown
      Role r = (Role)(it.next());
      out.write("<OPTION VALUE=\"" + r.getLevel() + "\"");
      if (r.getLevel()==cur_level)
	out.write(" SELECTED");
      out.write(">" + StringUtil.encodeHTML(r.getName()) + "</OPTION>\n");

    } // end while

    out.write("</SELECT>\n");

  } // end outputDropDown

} // end class ConferenceMembership