/*******************************************************************************
 * Copyright (c) 2001, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20080324   186456 makandre@ca.ibm.com - Andrew Mak
 *******************************************************************************/

package org.eclipse.wst.ws.internal.explorer.platform.perspective;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.wst.ws.internal.explorer.platform.constants.ActionInputs;
import org.eclipse.wst.ws.internal.explorer.platform.constants.FrameNames;
import org.eclipse.wst.ws.internal.explorer.platform.datamodel.TreeElement;
import org.eclipse.wst.ws.internal.explorer.platform.util.HTMLUtils;

public abstract class Node
{
  protected TreeElement element_;
  protected NodeManager nodeManager_;
  protected int nodeId_;
  protected int nodeDepth_;
  protected String imagePath_;
  protected boolean isOpen_;
  protected Vector childNodes_;
  protected ToolManager toolManager_;
  protected Node parent_;
  private String anchorName_;
  private int viewId_;

  public Node(TreeElement element,NodeManager nodeManager,int nodeDepth,String imagePath)
  {
    element_ = element;
    nodeManager_ = nodeManager;
    nodeId_ = nodeManager.addToNodeTable(this);
    nodeDepth_ = nodeDepth;
    Controller controller = nodeManager_.getController();
    if (imagePath == null)
      imagePath_ = controller.getPathWithContext(NodeManager.PATH_SPACE);
    else
      imagePath_ = imagePath;
    isOpen_ = true;
    childNodes_ = new Vector();
    toolManager_ = new ToolManager(this);
    initTools();
    anchorName_ = (new StringBuffer("action")).append(nodeId_).toString();
    parent_ = null;
    viewId_ = ActionInputs.VIEWID_DEFAULT;
  }

  /**
  * Returns the TreeElement associated with this node.
  * @return TreeElement The element associated with this node.
  */
  public TreeElement getTreeElement()
  {
    return element_;
  }

  /**
  * Returns the name of the node.
  * @return String
  */
  public String getNodeName()
  {
    return element_.getName();
  }

  /**
  * Returns the NodeManager managing this node.
  * @return NodeManager
  */
  public NodeManager getNodeManager()
  {
    return nodeManager_;
  }

  /**
  * Returns the id of this node.
  * @return int
  */
  public int getNodeId()
  {
    return nodeId_;
  }

  /**
  * Returns the depth in the tree of this node relative to the root node
  * @return int
  */
  public int getNodeDepth()
  {
    return nodeDepth_;
  }

  /**
  * Set the path of the image representing this class of Node.
  * @param String The path.
  */
  public void setImagePath(String path)
  {
    imagePath_ = path;
  }

  /**
  * Returns true if the children of this node are visible. Returns false
  * if they are not.
  * @return boolean
  */
  public boolean isOpen()
  {
    return isOpen_;
  }

  public boolean isVisible()
  {
    Node parentNode = parent_;
    while (parentNode != null)
    {
      if (!parentNode.isOpen())
        return false;
      parentNode = parentNode.getParent();
    }
    return true;
  }

  /**
  * Sets the visibility of this node's children to the specified value.
  * Updates the NodeManager's record of the maximum depth visible in the tree.
  * @param boolean
  */
  public final void setVisibilityOfChildren(boolean open)
  {
    isOpen_ = open;
    nodeManager_.updateMaxDepthVisible();
  }

  /**
  * Gets the maximum depth displayed in this node's branch of the tree
  * Used by NodeManager for html display purposes.
  * @return int
  */
  public int getMaxDepthVisible()
  {
    if (!isOpen_)
      return nodeDepth_;
    else
    {
      int currentDepth = nodeDepth_;
      Enumeration e = childNodes_.elements();
      while (e.hasMoreElements())
      {
        Node thisNode = (Node)e.nextElement();
        int depth = thisNode.getMaxDepthVisible();
        if (depth>currentDepth)
          currentDepth=depth;
      }
      return currentDepth;
    }
  }

  public final void setParent(Node node)
  {
    parent_ = node;
  }

  public final Node getParent()
  {
    return parent_;
  }

  public final void setViewId(int viewId)
  {
    viewId_ = viewId;
  }

  public final int getViewId()
  {
    return viewId_;
  }

  public final int getViewToolId()
  {
    ToolManager viewToolManager = getViewToolManager();
    if (viewToolManager != null)
      return viewToolManager.getSelectedToolId();
    return ActionInputs.VIEWTOOLID_DEFAULT;
  }

  /**
  * Adds the specified node as a child of this node.
  * @param Node The child being added.
  * @return boolean Always true.
  */
  public final boolean addChild(Node childNode)
  {
    childNode.setParent(this);
    childNodes_.addElement(childNode);
    nodeManager_.updateMaxDepthVisible();
    return true;
  }

  /**
  * Returns the child nodes of this node. If this node has no children, an
  * empty vector is returned.
  * @return Vector
  */
  public Vector getChildNodes()
  {
    return childNodes_;
  }

  public final Node getChildNode(TreeElement element)
  {
    Enumeration e = childNodes_.elements();
    while (e.hasMoreElements())
    {
      Node presentNode = (Node)e.nextElement();
      if (presentNode.getTreeElement() == element)
        return presentNode;
    }
    return null;
  }

  public final void removeChildNodes(boolean isEntry)
  {
    int numberOfChildNodes = childNodes_.size();
    for (int i=numberOfChildNodes-1;i>=0;i--)
    {
      Node childNode = (Node)childNodes_.elementAt(i);
      childNode.removeChildNodes(false);
      nodeManager_.removeFromNodeTable(childNode.getNodeId());
    }
    if (numberOfChildNodes > 0)
    {
      childNodes_.removeAllElements();
      if (isEntry)
        nodeManager_.updateMaxDepthVisible();
    }
  }

  public final boolean removeChildNode(TreeElement element)
  {
    Node childNode = getChildNode(element);
    if (childNode != null)
    {
      int childNodeId = childNode.getNodeId();
      if (nodeManager_.getSelectedNodeId() == childNodeId)
        nodeManager_.setSelectedNodeId(nodeId_);
      childNodes_.removeElement(childNode);
      nodeManager_.removeFromNodeTable(childNodeId);
      nodeManager_.updateMaxDepthVisible();
      return true;
    }
    return false;
  }

  /**
  * Get the name of the HTML anchor associated with this node.
  * @return String The name of the anchor.
  */
  public String getAnchorName()
  {
    return anchorName_;
  }

  public ToolManager getToolManager()
  {
    return toolManager_;
  }

  public ToolManager getViewToolManager()
  {
    if (viewId_ != ActionInputs.VIEWID_DEFAULT)
    {
      ViewTool viewTool = (ViewTool)toolManager_.getSelectedTool();
      return viewTool.getToolManager(viewId_);
    }
    return null;
  }
  
  public ToolManager getCurrentToolManager()
  {
    ToolManager toolManager = getViewToolManager();
    if (toolManager == null)
      toolManager = toolManager_;
    return toolManager;
  }

  protected abstract void initTools();

  protected abstract String getToggleNodeActionHref();

  protected String getToggleNodeActionTarget()
  {
    return FrameNames.PERSPECTIVE_WORKAREA;
  }

  protected void addToggle(HttpServletResponse response,StringBuffer treeView,boolean isLastChild)
  {
    if (nodeDepth_ != 1)
    {
      treeView.append("    <td align=\"left\" width=16 height=16 nowrap>");
      String toggleImageTag;
      if (childNodes_.size() > 0)
      {
        // <a href="..." target="...">toggleImageTag</a>
        String href = nodeManager_.getController().getPathWithContext(getToggleNodeActionHref());
        if (isOpen_)
        {
          String toggleAlt = nodeManager_.getController().getMessage("ALT_CLOSE");
          if (isLastChild)
            toggleImageTag = HTMLUtils.getHTMLImageTag(response,nodeManager_.getController().getPathWithContext(NodeManager.PATH_MINUS_LAST),toggleAlt,"16","16",null);
          else
            toggleImageTag = HTMLUtils.getHTMLImageTag(response,nodeManager_.getController().getPathWithContext(NodeManager.PATH_MINUS_NOTLAST),toggleAlt,"16","16",null);
        }
        else
        {
          String toggleAlt = nodeManager_.getController().getMessage("ALT_OPEN");
          if (isLastChild)
            toggleImageTag = HTMLUtils.getHTMLImageTag(response,nodeManager_.getController().getPathWithContext(NodeManager.PATH_PLUS_LAST),toggleAlt,"16","16",null);
          else
            toggleImageTag = HTMLUtils.getHTMLImageTag(response,nodeManager_.getController().getPathWithContext(NodeManager.PATH_PLUS_NOTLAST),toggleAlt,"16","16",null);
        }
        String linkTag = HTMLUtils.getHTMLLinkTag(response,href,getToggleNodeActionTarget(),String.valueOf(nodeId_),toggleImageTag,null);
        treeView.append(linkTag);
      }
      else
      {
        // <img...>
        if (isLastChild)
          toggleImageTag = HTMLUtils.getHTMLImageTag(response,nodeManager_.getController().getPathWithContext(NodeManager.PATH_LINE_LAST),"","16","16",null);
        else
          toggleImageTag = HTMLUtils.getHTMLImageTag(response,nodeManager_.getController().getPathWithContext(NodeManager.PATH_LINE_NOTLAST),"","16","16",null);
        treeView.append(toggleImageTag);
      }
      treeView.append("</td>").append(HTMLUtils.LINE_SEPARATOR);
    }
  }

  protected abstract String getLinkActionHref();

  protected String getLinkActionTarget()
  {
    return FrameNames.PERSPECTIVE_WORKAREA;
  }

  public String getOpenImagePath()
  {
    return imagePath_;
  }

  public String getClosedImagePath()
  {
    return imagePath_;
  }

  protected void addHTMLLabel(HttpServletResponse response,StringBuffer treeView,boolean isLastChild)
  {
    // <a href="..." target="..." onClick="selectNode('...')"><img...></a>
    Hashtable additionalAttributes = new Hashtable();
    additionalAttributes.put("name",anchorName_);
    String imagePath = (nodeManager_.getSelectedNodeId() == nodeId_)?getOpenImagePath():getClosedImagePath();

    String imageTag = HTMLUtils.getHTMLImageTag(response,nodeManager_.getController().getPathWithContext(imagePath),getNodeName(),"16","16",additionalAttributes);
    String baseHref = getLinkActionHref();
    String href = ((baseHref == null)?baseHref:nodeManager_.getController().getPathWithContext(baseHref));
    String target = getLinkActionTarget();
    additionalAttributes.clear();

    treeView.append("    <td align=\"left\" width=16 height=16 nowrap>");
    if (href != null)
      treeView.append(HTMLUtils.getHTMLLinkTag(response,href,target,null,imageTag,additionalAttributes));
    else
      treeView.append(imageTag);
    treeView.append("</td>").append(HTMLUtils.LINE_SEPARATOR);
    treeView.append("    <td align=\"left\" width=3 height=10 nowrap>").append(HTMLUtils.getHTMLImageTag(response,nodeManager_.getController().getPathWithContext(NodeManager.PATH_SPACE),"","3","10",null)).append("</td>").append(HTMLUtils.LINE_SEPARATOR);

    // <a name="..." href="..." target="...">label</a>
    treeView.append("    <td align=\"left\" nowrap>").append(HTMLUtils.LINE_SEPARATOR);
    treeView.append("      ");
    if (href != null)
    {
      String textAnchorClass;
      if (nodeManager_.getSelectedNodeId() == nodeId_)
        textAnchorClass="selectedTextAnchor";
      else
        textAnchorClass="unselectedTextAnchor";
      additionalAttributes.put("class",textAnchorClass);
      treeView.append(HTMLUtils.getHTMLLinkTag(response,href,target,anchorName_,getNodeName(),additionalAttributes));
    }
    else
      treeView.append("<strong>").append(getNodeName()).append("</strong>");
    treeView.append(HTMLUtils.LINE_SEPARATOR).append("    </td>").append(HTMLUtils.LINE_SEPARATOR);
  }

  public void renderNode(HttpServletResponse response,StringBuffer treeView,String prefixColumns,boolean isLastChild)
  {
    String space_16x16 = HTMLUtils.getHTMLImageTag(response,nodeManager_.getController().getPathWithContext(NodeManager.PATH_SPACE),"","16","16",null);
    String line_16x16 = HTMLUtils.getHTMLImageTag(response,nodeManager_.getController().getPathWithContext(NodeManager.PATH_LINE),"","16","16",null);

    // Use border=1 to help with debugging.
    treeView.append("<table cellspacing=0 cellpadding=0 border=0>").append(HTMLUtils.LINE_SEPARATOR);
    treeView.append("  <tr>").append(HTMLUtils.LINE_SEPARATOR);
    treeView.append("    <td align=\"left\" width=16 height=16 nowrap>").append(space_16x16).append("</td>").append(HTMLUtils.LINE_SEPARATOR);
    StringBuffer newPrefixColumns = new StringBuffer(prefixColumns);
    if (nodeDepth_ >= 2)
    {
      if (prefixColumns.length() > 0)
        treeView.append(prefixColumns).append(HTMLUtils.LINE_SEPARATOR);
      // generate a new prefix columns.
      newPrefixColumns.append("    <td align=\"left\" width=16 height=16 nowrap>");
      if (isLastChild)
        newPrefixColumns.append(space_16x16);
      else
        newPrefixColumns.append(line_16x16);
      newPrefixColumns.append("</td>").append(HTMLUtils.LINE_SEPARATOR);
    }
    addToggle(response,treeView,isLastChild);
    addHTMLLabel(response,treeView,isLastChild);
    treeView.append("  </tr>").append(HTMLUtils.LINE_SEPARATOR);
    treeView.append("</table>").append(HTMLUtils.LINE_SEPARATOR);
    int numberOfChildNodes = childNodes_.size();
    if (numberOfChildNodes > 0)
    {
      if (isOpen_)
      {
        for (int i=0;i<numberOfChildNodes-1;i++)
        {
          Node childNode = (Node)childNodes_.elementAt(i);
          childNode.renderNode(response,treeView,newPrefixColumns.toString(),false);
        }
        Node lastChildNode = (Node)childNodes_.elementAt(numberOfChildNodes-1);
        lastChildNode.renderNode(response,treeView,newPrefixColumns.toString(),true);
      }
    }
  }

  // For sorting purposes.  
  public final String toString()
  {
    return getNodeName();
  }
}
