/*
 * 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.Writer;
import java.io.IOException;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;

public class TopDisplay implements ContentRender, ColorSelectors
{
  /*--------------------------------------------------------------------------------
   * Static data values
   *--------------------------------------------------------------------------------
   */

  private static final String ATTR_NAME = "com.silverwrist.venice.TopDisplay";

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

  private ServletContext ctxt;
  private VeniceEngine engine;
  private UserContext uc;
  private List top_posts;
  private List descrs;
  private VeniceContent[] sideboxes;

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

  public TopDisplay(ServletContext ctxt, VeniceEngine engine, UserContext uc)
      throws ServletException, DataException, AccessError
  {
    // Stash some basic information.
    this.ctxt = ctxt;
    this.engine = engine;
    this.uc = uc;
    this.top_posts = engine.getPublishedMessages(false);
    this.descrs = uc.getSideBoxList();

    // Create the sideboxes.
    sideboxes = new VeniceContent[descrs.size()];
    RenderConfig rconf = RenderConfig.getRenderConfig(ctxt);
    for (int i=0; i<descrs.size(); i++)
    { // create each sidebox in turn...
      SideBoxDescriptor d = (SideBoxDescriptor)(descrs.get(i));
      sideboxes[i] = rconf.createSideBox(d.getID(),engine,uc);

    } // end for

  } // end constructor

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

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

  } // end retrieve

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

  public String getPageTitle(RenderData rdat)
  {
    return "My Front Page";

  } // end getPageTitle

  public String getPageQID()
  {
    return "top";

  } // end getPageQID

  /*--------------------------------------------------------------------------------
   * Implementations from interface ContentRender
   *--------------------------------------------------------------------------------
   */

  public void renderHere(Writer out, RenderData rdat) throws IOException
  {
    // Write out the start of the content structure.
    out.write("<TABLE BORDER=0 ALIGN=CENTER WIDTH=\"100%\" CELLPADDING=4 CELLSPACING=0><TR VALIGN=TOP>\n");
    out.write("<TD ALIGN=LEFT>\n");

    // The top content is a JSP page, so include it here.
    rdat.setRequestAttribute(ATTR_NAME,this);
    RequestDispatcher dispatcher = ctxt.getRequestDispatcher(rdat.getFormatJSPPath("top_content.jsp"));
    out.flush();
    rdat.flushOutput();  // make sure the stuff to be output first is output
    try
    { // include me!
      rdat.includeDispatch(dispatcher);

    } // end try
    catch (ServletException se)
    { // since we can't throw ServletException, we throw IOException
      throw new IOException("Failure including top_content.jsp");

    } // end catch

    rdat.flushOutput();  // now make sure the included page is properly flushed

    out.write("</TD>\n<TD ALIGN=CENTER WIDTH=210>\n");  // break to the sidebox column

    for (int i=0; i<sideboxes.length; i++)
    { // draw in the outer framework of the sidebox
      out.write("<TABLE ALIGN=CENTER WIDTH=200 BORDER=0 CELLPADDING=2 CELLSPACING=0>"
		+ "<TR VALIGN=MIDDLE BGCOLOR=\"" + rdat.getStdColor(SIDEBOX_TITLE_BACKGROUND)
		+ "\"><TD ALIGN=LEFT CLASS=\"sideboxtop\">\n"
		+ rdat.getStdFontTag(SIDEBOX_TITLE_FOREGROUND,3) + "<B>" + sideboxes[i].getPageTitle(rdat)
		+ "</B></FONT>\n</TD></TR><TR VALIGN=TOP BGCOLOR=\""
		+ rdat.getStdColor(SIDEBOX_CONTENT_BACKGROUND) + "\"><TD ALIGN=LEFT CLASS=\"sidebox\">\n");

      // Fill in the sidebox by calling down to the base.
      if (sideboxes[i] instanceof ContentRender)
      { // we have a direct-rendering component here - do it
	ContentRender cr = (ContentRender)(sideboxes[i]);
	cr.renderHere(out,rdat);

      } // end if
      else if (sideboxes[i] instanceof JSPRender)
      { // we have a JSP rendering component here - bounce to the appropriate JSP file
	JSPRender jr = (JSPRender)(sideboxes[i]);
	rdat.storeJSPRender(jr);
	dispatcher = ctxt.getRequestDispatcher(rdat.getFormatJSPPath(jr.getTargetJSPName()));
	out.flush();
	rdat.flushOutput();  // make sure the stuff to be output first is output
	try
	{ // include me!
	  rdat.includeDispatch(dispatcher);

	} // end try
	catch (ServletException se)
	{ // since we can't throw ServletException, we throw IOException
	  out.write(rdat.getStdFontTag(SIDEBOX_CONTENT_FOREGROUND,2) + "<EM>failure rendering class "
		    + sideboxes[i].getClass().getName() + ": " + StringUtil.encodeHTML(se.getMessage())
		    + "</EM></FONT>\n");
	  out.flush();

	} // end catch

	rdat.flushOutput();  // now make sure the included page is properly flushed

      } // end else if
      else  // this is bogus - just display a little error here
	out.write(rdat.getStdFontTag(SIDEBOX_CONTENT_FOREGROUND,2) + "<EM>cannot display sidebox of class: "
		  + sideboxes[i].getClass().getName() + "</EM></FONT>\n");
	
      // close up the framework of this sidebox
      out.write("</TD></TR></TABLE><P>\n");

    } // end for

    if (uc.isLoggedIn())
    { // write the Configure button below the sideboxes
      out.write("<A HREF=\"" + rdat.getEncodedServletPath("settings?cmd=B") + "\"><IMG SRC=\""
		+ rdat.getFullImagePath("bn_configure.gif")
		+ "\" ALT=\"Configure\" WIDTH=80 HEIGHT=24 BORDER=0></A>\n");

    } // end if

    // Finish up.
    out.write("</TD>\n</TR></TABLE>");

  } // end renderHere

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

  public static String getPosterName(TopicMessageContext msg)
  {
    try
    { // have to guard agains a DataException here
      return msg.getCreatorName();

    } // end try
    catch (DataException de)
    { // just return "unknown" on failure
      return "(unknown)";

    } // end catch

  } // end getPosterName

  public static String getMessageBodyText(TopicMessageContext msg)
  {
    try
    { // have to guard against a DataException here
      return msg.getBodyText();

    } // end try
    catch (DataException de)
    { // just return an error message
      return "<EM>(Unable to retrieve message data: " + StringUtil.encodeHTML(de.getMessage()) + ")</EM>";

    } // end catch

  } // end getMessageBodyText

  public int getNumTopPosts()
  {
    return top_posts.size();

  } // end getNumTopPosts

  public TopicMessageContext getTopPost(int index)
  {
    return (TopicMessageContext)(top_posts.get(index));

  } // end getTopPost

  public boolean displayWelcome()
  {
    return !(uc.isLoggedIn());

  } // end displayWelcome

} // end class TopDisplay
