/*
 * 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) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.ui.menus;

import java.io.*;
import java.util.*;
import org.apache.log4j.*;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.except.ConfigException;
import com.silverwrist.venice.ui.*;
import com.silverwrist.venice.ui.config.RootConfig;
import com.silverwrist.venice.ui.helpers.HTMLRendering;
import com.silverwrist.venice.util.XMLLoader;

class LinkItem implements MenuComponent
{
  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

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

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

  private String m_href;              // what we actually link to
  private int m_type;                 // the type of item we specify
  private boolean m_enabled = true;   // is this item enabled?
  private String m_target = null;     // target window for the link
  private String m_title = null;      // title (tooltip) for the link
  private String m_on_click = null;   // onClick JavaScript for the link
  private String m_ifdef_sym = null;  // include only if defined
  private String m_ifndef_sym = null; // include only if NOT defined
  private int m_indent = 0;           // how many spaces do we indent this link?
  private MenuComponent m_contents;     // what does this link contain?  (image vs. text)

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

  LinkItem(Element elt, RootConfig rconf) throws ConfigException
  {
    XMLLoader loader = XMLLoader.get();

    loader.configVerifyNodeName(elt,"link");

    m_href = loader.configGetAttribute(elt,"href");

    DOMElementHelper h = new DOMElementHelper(elt);
    if (h.hasAttribute("type"))
    { // convert link type to an index
      m_type = rconf.convertLinkType(elt.getAttribute("type"));
      if (m_type<0) // the type is not valid
	throw new ConfigException("invalid type= attribute of <link/>");

    } // end if
    else // default to "absolute"
      m_type = LinkTypes.ABSOLUTE;

    // load the "target"
    if (h.hasAttribute("target"))
      m_target = elt.getAttribute("target");

    // load the "title"
    if (h.hasAttribute("title"))
      m_title = elt.getAttribute("title");

    // load the "onClick" script code
    if (h.hasAttribute("onClick"))
      m_on_click = elt.getAttribute("onClick");

    // load the "ifdef" and "ifndef" symbols
    if (h.hasAttribute("ifdef"))
      m_ifdef_sym = elt.getAttribute("ifdef");
    if (h.hasAttribute("ifndef"))
      m_ifndef_sym = elt.getAttribute("ifndef");

    // load the "disabled" attribute
    if (h.hasAttribute("disabled"))
      m_enabled = false;

    if (h.hasAttribute("indent"))
    { // load the "indent" attribute, make sure it's not less than 0
      m_indent = loader.configGetAttributeInt(elt,"indent");
      if (m_indent<0)
      { // whoops - this is an error!
	logger.fatal("indent=\"" + m_indent + "\" is not a valid value");
	throw new ConfigException("invalid indent= attribute of <link/>");

      } // end if

    } // end if

    // load the contents
    Element x = h.getSubElement("image");
    if (x!=null)
      m_contents = new ImageItem(x);
    else
      m_contents = new TextItem(h.getElementText());

  } // end constructor

  LinkItem(String href, int type, MenuComponent contents)
  {
    m_href = href;
    m_type = type;
    m_contents = contents;

  } // end constructor

  LinkItem(LinkItem other, Map vars)
  {
    m_href = StringUtil.replaceAllVariables(other.m_href,vars);
    m_type = other.m_type;
    m_enabled = other.m_enabled;
    m_target = other.m_target;
    m_title = other.m_title;
    m_on_click = StringUtil.replaceAllVariables(other.m_on_click,vars);
    m_ifdef_sym = other.m_ifdef_sym;
    m_ifndef_sym = other.m_ifndef_sym;
    m_indent = other.m_indent;
    m_contents = other.m_contents;

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Internal operations
   *--------------------------------------------------------------------------------
   */

  private final String getAddress(HTMLRendering html, Map vars)
  {
    String s = StringUtil.replaceAllVariables(m_href,vars);
    return html.formatURL(s,m_type);

  } // end getAddress

  private final String getExtraAttributes()
  {
    StringBuffer buf = new StringBuffer();
    if (m_target!=null)
      buf.append(" target=\"").append(m_target).append("\"");
    if (m_title!=null)
      buf.append(" title=\"").append(m_title).append("\"");
    if (m_on_click!=null)
      buf.append(" onClick=\"").append(m_on_click).append("\"");
    return buf.toString();

  } // end getExtraAttributes

  /*--------------------------------------------------------------------------------
   * Implementations from interface MenuComponent
   *--------------------------------------------------------------------------------
   */

  public void render(RequestOutput out, Writer wr, MenuTemplate template, Set defines) throws IOException
  {
    if ((m_ifdef_sym!=null) && !(defines.contains(m_ifdef_sym)))
      return;
    if ((m_ifndef_sym!=null) && defines.contains(m_ifndef_sym))
      return;

    HTMLRendering html = (HTMLRendering)(out.queryService(HTMLRendering.class));

    // Build up the parms map.
    HashMap parms = new HashMap();
    parms.put("xattr",getExtraAttributes());
    parms.put("stdbullet","<img src=\"" + html.getImagePath("purple-ball.gif")
	                  + "\" alt=\"*\" width=\"14\" height=\"14\" border=\"0\" />");

    // Format the item text to a StringWriter.
    StringWriter subwr = new StringWriter();
    m_contents.render(out,subwr,template,defines);
    subwr.flush();

    if (wr==null)
      wr = out.getWriter();

    // output the indenting
    String nstr = template.getBlock("link-indent");
    for (int i=0; i<m_indent; i++)
      wr.write(nstr);

    // output the actual item
    template.renderItem(wr,(m_enabled ? "normal" : "disabled"),subwr.toString(),html.formatURL(m_href,m_type),parms);

  } // end render

  public void render(RequestOutput out, Writer wr, MenuTemplate template) throws IOException
  {
    this.render(out,wr,template,java.util.Collections.EMPTY_SET);

  } // end render

  public String getTitle(RequestOutput out)
  {
    return null;  // we don't have a "title" in this sense

  } // end getTitle

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

  final String getAddress(RequestOutput out, Map vars)
  {
    return this.getAddress((HTMLRendering)(out.queryService(HTMLRendering.class)),vars);

  } // end getAddress

  final String getAddress(RequestInput inp, Map vars)
  {
    return this.getAddress((HTMLRendering)(inp.queryService(HTMLRendering.class)),vars);

  } // end getAddress

} // end class LinkItem
