/*
 * 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@ricochet.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2004 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.ui.sidebox;

import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.ui.*;
import com.silverwrist.venice.ui.helpers.HTMLRendering;
import com.silverwrist.venice.ui.helpers.ImageHandler;

public class UserListBox implements SideBoxFactory
{
  /*--------------------------------------------------------------------------------
   * Internal class that implements the actual sidebox
   *--------------------------------------------------------------------------------
   */

  private class UserListBoxImpl implements ContentDirect
  {
    /*====================================================================
     * Attributes
     *====================================================================
     */

    private boolean m_logged_in;
    private int m_total_count;
    private int m_max_count;
    private int m_anon_count = 0;
    private TreeSet m_users = new TreeSet(String.CASE_INSENSITIVE_ORDER);

    /*====================================================================
     * Constructor
     *====================================================================
     */

    UserListBoxImpl(boolean logged_in, VeniceUISessionList slist)
    {
      m_logged_in = logged_in;
      Iterator it = null;
      synchronized (slist)
      { // get user information
	m_total_count = slist.getSessionCount();
	m_max_count = slist.getMaxSessionCount();
	it = slist.listSessions();

      } // end synchronized block

      while (it.hasNext())
      { // build the user list and the anon user count
	UserContext uc = ((VeniceUISession)(it.next())).getUser();
	if (uc.isLoggedIn())
	  m_users.add(uc.getUserName());
	else
	  m_anon_count++;

      } // end while

    } // end constructor

    /*====================================================================
     * Implementations from interface Content
     *====================================================================
     */

    public boolean needFrame()
    {
      return false;

    } // end needFrame

    public int getMenuSelector()
    {
      return MENU_SELECTOR_NOCHANGE;

    } // end getMenuSelector

    public String getPageTitle(RequestOutput ro)
    {
      if (m_title_image!=null)
      { // return an image rendering
	ImageHandler ih = (m_logged_in ? m_title_image : m_anon_title_image);
	return ih.getRendering(ro);

      } // end if
      else
      { // return a title string
	String rc = (m_logged_in ? m_title : m_anon_title);
	return StringUtil.encodeHTML(rc);

      } // end else

    } // end getPageTitle

    public String getPageQID()
    {
      return null;

    } // end getPageQID

    /*====================================================================
     * Implementations from interface ContentDirect
     *====================================================================
     */

    public void render(RequestOutput out) throws IOException
    {
      HTMLRendering html = (HTMLRendering)(out.queryService(HTMLRendering.class));
      String norm_font = html.getFontTag(html.SIDEBOX_CONTENT_FOREGROUND,"sidebox");
      String hilite = html.getFontTag(html.SIDEBOX_CONTENT_LINK,"sidebox");

      out.write("<table align=\"left\" border=\"0\" cellpadding=\"0\" cellspacing=\"2\"><tr valign=\"middle\">"
		+ "<td align=\"left\" class=\"sidebox\" colspan=\"2\">" + norm_font + "<b>");
      HashMap m = new HashMap();
      m.put("cur",String.valueOf(m_total_count));
      m.put("max",String.valueOf(m_max_count));
      out.write(StringUtil.replaceAllVariables(m_summary,m) + "</b></FONT></td></tr>");
      if (m_anon_count>0)
      { // write the anonymous user count
	out.write("<tr valign=\"middle\"><td align=\"center\" width=\"" + m_bullet.getWidth() + "\">");
	m_bullet.render(out);
	out.write("</td><td align=\"left\" class=\"sidebox\">" + norm_font + m_anon_label + " (" + m_anon_count
		  + ")</FONT></td></tr>");

      } // end if

      for (Iterator it=m_users.iterator(); it.hasNext(); )
      { // get user name and write it out to the list
	String uname = (String)(it.next());
	out.write("<tr valign=\"middle\"><td align=\"center\" width=\"" + m_bullet.getWidth() + "\">");
	m_bullet.render(out);
	out.write("</td><td align=\"left\" class=\"sidebox\"><a class=\"sidebox\" target=\"_blank\" href=\"");
	out.write(html.formatURL("user/" + uname,html.SERVLET));
	out.write("\">" + hilite + uname + "</FONT></a></td></tr>");

      } // end for

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

    } // end render

  } // end class UserListBoxImpl

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

  private ImageHandler m_title_image;       // title image for sidebox for logged-in users
  private ImageHandler m_anon_title_image;  // title image for sidebox for not-logged-in users
  private String m_title;                   // title of sidebox for logged-in users
  private String m_anon_title;              // title of sidebox for not-logged-in users
  private ImageHandler m_bullet;            // bullet image
  private String m_summary;                 // summary message
  private String m_anon_label;              // anonymous label

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  public UserListBox()
  { // do nothing
  } // end constructor

  /*--------------------------------------------------------------------------------
   * Implementations from interface SideBoxFactory
   *--------------------------------------------------------------------------------
   */

  public void setConfiguration(Element cfg) throws ConfigException
  {
    DOMElementHelper cfg_h = new DOMElementHelper(cfg);
    m_title_image = new ImageHandler(cfg_h.getSubElement("title-image"));
    if (m_title_image.isDefined())
    { // we're using image titles...
      m_title = m_anon_title = null;
      m_anon_title_image = new ImageHandler(cfg_h.getSubElement("anon-title-image"));
      if (!(m_anon_title_image.isDefined()))
	m_anon_title_image = m_title_image;

    } // end if
    else
    { // standard textual title
      m_title_image = m_anon_title_image = null;
      m_title = cfg_h.getSubElementText("title");
      if (m_title==null)
	throw new ConfigException("no <title/> specified for conference list sidebox",cfg);
      m_title += ":";
      m_anon_title = cfg_h.getSubElementText("anon-title");
      if (m_anon_title==null)
	m_anon_title = m_title;
      else
	m_anon_title += ":";

    } // end else

    m_bullet = new ImageHandler(cfg_h.getSubElement("bullet"),"purple-ball.gif","*",14,14);

    m_summary = cfg_h.getSubElementText("summary");
    if (m_summary==null)
      m_summary = "${cur} total (max ${max})";

    m_anon_label = cfg_h.getSubElementText("anon-label");
    if (m_anon_label==null)
      m_anon_label = "Anonymous";

  } // end setConfiguration

  public Content create(RequestInput ri) throws AccessError, DataException
  {
    VeniceUISessionList slist = (VeniceUISessionList)(ri.getAppAttribute(VeniceUISessionList.APP_ATTR_NAME));
    if (slist==null)
      throw new DataException("session list object not found");
    return new UserListBoxImpl(ri.getUser().isLoggedIn(),slist);

  } // end create

} // end class UserListBox
