/*
 * 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 com.silverwrist.util.IOUtil;
import com.silverwrist.util.cache.CacheMap;

public class StaticRender implements ContentRender
{
  /*--------------------------------------------------------------------------------
   * Static data values
   *--------------------------------------------------------------------------------
   */

  private static CacheMap cache = new CacheMap(15,25);

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

  private String name;
  private boolean processed = false;
  private String title = null;
  private String content = null;

  /*--------------------------------------------------------------------------------
   * Static data values
   *--------------------------------------------------------------------------------
   */

  protected StaticRender(String name)
  {
    this.name = name;

  } // end constructor

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

  private static String searchBetweenTags(StringBuffer data, String search, String tagname)
  {
    tagname = tagname.toUpperCase();
    String start = "<" + tagname;
    String end = "</" + tagname + ">";

    int startpos = search.indexOf(start);
    if (startpos<0)
      return null;
    startpos += start.length();

    int bkt_pos = search.indexOf('>',startpos);
    if (bkt_pos<0)
      return null;

    int end_pos = search.indexOf(end,++bkt_pos);
    if (end_pos<0)
      return data.substring(bkt_pos);
    else
      return data.substring(bkt_pos,end_pos);

  } // end searchBetweenTags

  private synchronized void process(RenderData rdat)
  {
    if (processed)
      return;  // check and set flag

    // Map the content path to a real filename.
    String real_path = rdat.mapToPath(rdat.getStaticIncludePath(name));
    if (real_path==null)
    { // not found!
      title = name;
      content = "File not mappable: " + name;
      return;

    } // end if

    // Read in the whole thing.
    StringBuffer raw_file;
    try
    { // read in from the file
      raw_file = IOUtil.loadText(new File(real_path));

    } // end try
    catch (IOException ioe)
    { // I/O exception - just discard
      title = name;
      content = "I/O error reading " + name + ": " + ioe.getMessage();
      return;

    } // end catch

    // make the upper-case search page and use that to locate the page title and body
    String search_page = raw_file.toString().toUpperCase();
    title = searchBetweenTags(raw_file,search_page,"TITLE");
    content = searchBetweenTags(raw_file,search_page,"BODY");
    if (content==null)
    { // no content?
      content = "No content seen on " + name;
      processed = false;

    } // end if

    processed = true;  // set the flag to indicate we've got everything

  } // end process

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

  public String getPageTitle(RenderData rdat)
  {
    process(rdat);
    if (title==null)
      return name;
    else
      return title;

  } // end getPageTitle

  public String getPageQID()
  {
    return "static/" + name;

  } // end getPageQID

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

  public void renderHere(Writer out, RenderData rdat) throws IOException
  {
    process(rdat);
    if (content!=null)
      out.write(content);

  } // end renderHere

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

  public static StaticRender getStaticRender(String name)
  {
    StaticRender rc = (StaticRender)(cache.get(name));
    if (rc==null)
    { // create a new object and cache it
      rc = new StaticRender(name);
      cache.put(name,rc);

    } // end if

    return rc;

  } // end getStaticRender

} // end class StaticRender
