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

import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import java.util.Set;
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 Category logger = Category.getInstance(LinkItem.class);

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

  private String href;                // what we actually link to
  private int type;                   // the type of item we specify
  private boolean enabled = true;     // is this item enabled?
  private String target = null;       // target window for the link
  private String title = null;        // title (tooltip) for the link
  private String on_click = null;     // onClick JavaScript for the link
  private String ifdef_sym = null;    // include only if defined
  private String ifndef_sym = null;   // include only if NOT defined
  private int indent = 0;             // how many spaces do we indent this link?
  private MenuComponent 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");

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

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

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

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

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

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

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

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

    if (h.hasAttribute("indent"))
    { // load the "indent" attribute, make sure it's not less than 0
      indent = loader.configGetAttributeInt(elt,"indent");
      if (indent<0)
      { // whoops - this is an error!
	logger.fatal("indent=\"" + 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)
      contents = new ImageItem(x);
    else
      contents = new TextItem(h.getElementText());

  } // end constructor

  LinkItem(LinkItem other, Map vars)
  {
    this.href = StringUtil.replaceAllVariables(other.href,vars);
    this.type = other.type;
    this.enabled = other.enabled;
    this.target = other.target;
    this.title = other.title;
    this.on_click = StringUtil.replaceAllVariables(other.on_click,vars);
    this.ifdef_sym = other.ifdef_sym;
    this.ifndef_sym = other.ifndef_sym;
    this.indent = other.indent;
    this.contents = other.contents;

  } // end constructor

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

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

  } // end getAddress

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

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

  } // end render

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

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

    if (wr==null)
      wr = out.getWriter();
    for (int i=0; i<indent; i++)
      wr.write("&nbsp;&nbsp;&nbsp;&nbsp;");  // do indent
    wr.write("<IMG SRC=\"" + html.getImagePath("purple-ball.gif")
	      + "\" ALT=\"*\" WIDTH=14 HEIGHT=14 BORDER=0>&nbsp;");
    if (enabled)
    { // render the URL as an <A> tag
      wr.write("<A HREF=\"" + html.formatURL(href,type) + "\"");
      if (target!=null)
	wr.write(" TARGET=\"" + target + "\"");
      if (title!=null)
	wr.write(" TITLE=\"" + title + "\"");
      if (on_click!=null)
	wr.write(" onClick=\"" + on_click + "\"");
      wr.write(">");
      
    } // end if
    else  // just disable the color
      wr.write(html.getFontTag(html.CONTENT_DISABLED,null));
    contents.render(out,wr,defines);
    if (enabled)
      wr.write("</A>");
    else
      wr.write("</FONT>");
    wr.write("<BR>\n");

  } // end render

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

  } // end renderOnLeft

  public void renderOnLeft(RequestOutput out, Writer wr, Set defines) throws IOException
  {
    if ((ifdef_sym!=null) && !(defines.contains(ifdef_sym)))
      return;
    if ((ifndef_sym!=null) && defines.contains(ifndef_sym))
      return;

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

    if (wr==null)
      wr = out.getWriter();
    for (int i=0; i<indent; i++)
      wr.write("&nbsp;");  // do indent
    if (enabled)
    { // write the opening <A> and <FONT> tags
      wr.write("<A HREF=\"" + html.formatURL(href,type) + "\" CLASS=\"lbar\"");
      if (target!=null)
	wr.write(" TARGET=\"" + target + "\"");
      if (title!=null)
	wr.write(" TITLE=\"" + title + "\"");
      if (on_click!=null)
	wr.write(" onClick=\"" + on_click + "\"");
      wr.write(">" + html.getFontTag(html.LEFT_LINK,null));
      
    } // end if
    else
      wr.write(html.getFontTag(html.CONTENT_DISABLED,null));
    contents.renderOnLeft(out,wr,defines);
    wr.write("</FONT>");
    if (enabled)
      wr.write("</A>");
    wr.write("<BR>\n");

  } // end renderOnLeft

  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
