package org.mbari.vdm.knowledgebase;


//~--- non-JDK imports --------------------------------------------------------

import java.util.Collection;
import java.util.Iterator;

import javax.swing.tree.DefaultMutableTreeNode;

import org.mbari.vars.knowledgebase.model.Concept;
import org.mbari.vars.knowledgebase.model.ConceptName;


/**
* <p><!-- Class description --></p>
*
* @version    $Id: TreeConcept.java,v 1.2 2005/12/14 03:24:33 achase Exp $
* @author     <a href="http://www.mbari.org">Monterey Bay Aquarium Research Institute</a>    
*/
public class TreeConcept implements Comparable {

  //~--- fields -------------------------------------------------------------

  private final Concept concept;

  private boolean details;

  private String name;
  private boolean primaryImage;
  private String[] secondaryNames;

  //~--- constructors -------------------------------------------------------

  /**
   * Constructs ...
   *
   *
   * @param concept
   */
  TreeConcept(Concept concept) {
      this.name = concept.getPrimaryConceptNameAsString();
      this.concept = concept;

      ConceptName[] secondaryConceptNames =
          concept.getSecondaryConceptNames();

      secondaryNames = new String[secondaryConceptNames.length];

      for (int i = 0; i < secondaryConceptNames.length; ++i) {
          secondaryNames[i] = secondaryConceptNames[i].getName();
      }

      // TODO 20040402 brian: This call tries to load the conceptDelegate.
      // Which slows things up. Will need to optimize this at some point.
      details = concept.hasDetails();
      primaryImage = concept.hasPrimaryImage();
  }

  //~--- methods ------------------------------------------------------------

  /*
   *  (non-Javadoc)
   * @see java.lang.Comparable#compareTo(java.lang.Object)
   */

  /**
   * <p><!-- Method description --></p>
   *
   *
   * @param o
   *
   * @return
   */
  public int compareTo(Object o) {
      return getName().compareTo(((TreeConcept) o).getName());
  }

  //~--- get methods --------------------------------------------------------

  /**
   * <p><!-- Method description --></p>
   *
   *
   * @return
   */
  public Concept getConcept() {
      return concept;
  }

  /**
   * <p><!-- Method description --></p>
   *
   *
   * @return
   */
  public String getName() {
      return name;
  }

  /**
   * <p><!-- Method description --></p>
   *
   *
   * @return
   */
  String[] getSecondaryNames() {
      // RxNOTE wcpr No defensive copy since package protected method
      return secondaryNames;
  }

  /**
   * <p><!-- Method description --></p>
   *
   *
   * @return
   */
  boolean hasDetails() {
      return details;
  }

  /**
   * <p><!-- Method description --></p>
   *
   *
   * @return
   */
  boolean hasPrimaryImage() {
      return primaryImage;
  }

  //~--- methods ------------------------------------------------------------

  /**
   * Add this concepts children to the node passed to the method. For example,
   * <pre>
   * TreeConcept treeConcept = new TreeConcept(rootConcept);
   * DefaultMutableTreeNode rootNode =
   *     new DefaultMutableTreeNode(treeConcept);
   * treeConcept.lazyExpand(rootNode);
   *
   * </pre>
   *
   * @param parent
   * @return
   *
   */
  public synchronized boolean lazyExpand(DefaultMutableTreeNode parent) {

      // Return false if attempt made to expand a node with no children.
      if (parent.isLeaf()) {
          return false;
      }

      // check if this node needs to be updated
      DefaultMutableTreeNode flag =
          (DefaultMutableTreeNode) parent.getFirstChild();

      if (flag == null) {
          return false;    // no flag set, this node doesn't need any action performed
      }

      Object obj = flag.getUserObject();

      if (!(obj instanceof Boolean)) {
          return false;    // the first object is not a flag, no need to expand
      }

      // remove the flag
      parent.removeAllChildren();

      Collection concepts =  getConcept().getChildConceptColl();

      for (Iterator iter = concepts.iterator(); iter.hasNext(); ) {
          Concept childConcept = (Concept) iter.next();
          DefaultMutableTreeNode node =
              new SortedTreeNode(new TreeConcept(childConcept));

          parent.add(node);

          if (childConcept.hasChildConcepts()) {
              node.add(new SortedTreeNode(Boolean.TRUE));
          }
      }

      return true;
  }

  /**
   * <p><!-- Method description --></p>
   *
   *
   * @return
   */
  public String toString() {
      StringBuffer buf = new StringBuffer("TreeConcept( ");

      buf.append(name);

      if (0 < secondaryNames.length) {
          buf.append(": ");

          for (int i = 0; i < secondaryNames.length - 1; ++i) {
              buf.append(secondaryNames[i]);
              buf.append(", ");
          }

          buf.append(secondaryNames[secondaryNames.length - 1]);
      }

      buf.append(" )");

      return buf.toString();
  }
}
