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

import java.util.*;
import org.apache.log4j.*;
import org.apache.regexp.*;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.ui.*;
import com.silverwrist.venice.ui.helpers.*;
import com.silverwrist.venice.util.XMLLoader;

public class EmoticonManager
{
  /*--------------------------------------------------------------------------------
   * Internal class that contains the icon data.
   *--------------------------------------------------------------------------------
   */

  private static class IconDefinition
  {
    /*====================================================================
     * Attributes
     *====================================================================
     */

    private int m_width;
    private int m_height;
    private boolean m_fixup;
    private String m_path;
    private String m_text;

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

    IconDefinition(Element icon_elt) throws ConfigException
    {
      XMLLoader loader = XMLLoader.get();
      DOMElementHelper h = new DOMElementHelper(icon_elt);

      // Get the icon image data.
      Element img_elt = loader.configGetSubSection(h,"image");
      m_width = loader.configGetAttributeInt(img_elt,"width");
      m_height = loader.configGetAttributeInt(img_elt,"height");
      DOMElementHelper h2 = new DOMElementHelper(img_elt);
      m_fixup = h2.getAttributeBoolean("fixup",false).booleanValue();
      m_path = h2.getElementText();

      // Get the text data.
      m_text = h.getSubElementText("text");
      if (m_text==null)
	m_text = "";

    } // end constructor

    /*====================================================================
     * External operations
     *====================================================================
     */

    String format(RequestOutput out)
    {
      StringBuffer buf = new StringBuffer("<img src=\"");
      if (m_fixup)
      { // fix it up
	HTMLRendering html = (HTMLRendering)(out.queryService(HTMLRendering.class));
	m_path = html.getImagePath(m_path);
	m_fixup = false;

      } // end if

      buf.append(m_path).append("\" width=\"").append(m_width).append("\" height=\"").append(m_height);
      buf.append("\" border=\"0\" alt=\"").append(m_text).append("\" title=\"").append(m_text);
      buf.append("\" />");
      return buf.toString();
      
    } // end format

  } // end class IconDefinition

  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

  private static Logger logger = Logger.getLogger(EmoticonManager.class);

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

  private Map m_iconmap;

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

  EmoticonManager(Element config) throws ConfigException
  {
    XMLLoader loader = XMLLoader.get();
    HashMap tmp = new HashMap();
    NodeList nl = config.getChildNodes();
    for (int i=0; i<nl.getLength(); i++)
    { // get the element
      Node n = nl.item(i);
      if ((n.getNodeType()==Node.ELEMENT_NODE) && n.getNodeName().equals("icon"))
      { // load the emoticon
	Element elt = (Element)n;
	String icon_name = loader.configGetAttribute(elt,"name").intern();
	IconDefinition defn = new IconDefinition(elt);
	tmp.put(icon_name,defn);

      } // end if

    } // end for

    if (tmp.isEmpty())
      m_iconmap = Collections.EMPTY_MAP;
    else
      m_iconmap = Collections.unmodifiableMap(tmp);

  } // end constructor

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

  public String rewriteText(RequestOutput out, String txt)
  {
    RE r = null;
    try
    { // create the regexp
      r = new RE("<ei:\\s*(\\w+)(?:\\s*/)?\\s*>");

    } // end try
    catch (RESyntaxException e)
    { // something wicked this way comes
      logger.fatal("WTF?!?!?!?",e);

    } // end catch

    if (!(r.match(txt)))
    { // null it out
      logger.debug("EmoticonManager.rewriteText matched nothing at all");
      return txt;

    } // end if

    StringBuffer buf = new StringBuffer();
    String work = txt;
    do
    { // figure out how many characters to skip
      int skip = r.getParenStart(0);
      if (skip>0)
	buf.append(work.substring(0,skip));
      skip += r.getParenLength(0);

      // get the icon name
      String icon_name = r.getParen(1);
      IconDefinition defn = (IconDefinition)(m_iconmap.get(icon_name));
      if (defn==null)
	buf.append(StringUtil.encodeHTML(r.getParen(0)));
      else
	buf.append(defn.format(out));
      
      work = work.substring(skip);  // skip over stuff

    } while (r.match(work));  // end do

    return buf.append(work).toString();  // all done!

  } // end rewriteText

} // end class EmoticonManager
