// file: $isip/class/search/LexialTree/lex_01.cc
// version: $Id: lex_01.cc 8818 2002-11-19 22:32:57Z parihar $
//

//isip include files
//
#include "LexicalTree.h"
#include <SearchSymbol.h>

// method: debug
//
// arguments:
//  const unichar* msg: (input) message to print
//
// return: logical error status
//
// this is the debug method
//
boolean LexicalTree::debug(const unichar* message_a) {

  // build a debug string
  //
  String val;
  String output;
  
  output.debugStr(name(), message_a, L":");
  Console::put(output);
  
  Console::increaseIndention();

  // display the algorithm name
  //
  val.assign((long)algorithm_d);
  output.debugStr(name(), message_a, L"algorithm_d", val);
  Console::put(output);
  
  // display the implementation name
  //
  val.assign((long)implementation_d);
  output.debugStr(name(), message_a, L"implementation_d", val);
  Console::put(output);

  // dump a pointer to the start vertex
  //
  val.assign(root_vert_d);
  output.debugStr(name(), message_a, L"root_vert_d", val);
  Console::put(output);

  debugTree(message_a);
  //LexicalTree temp_tree(*this);
  //temp_tree.debugTree(L":");
  
  // call the parent debug method to debug the list of vertices itself
  //
  if (debug_level_d > Integral::BRIEF) {
    DiGraph<LexicalNode>::debug(L"DiGraph");
  }
  
  // that's it for sub-items, decrease indentation
  //
  Console::decreaseIndention();
  
  // exit gracefully
  //
  return true;
}

// method: debugTree
//
// arguments:
//  const unichar* msg: (input) message to print
//
// return: logical error status
//
// this is the debug method
//
boolean LexicalTree::debugTree(const unichar* message_a) {

  // build a debug string
  //
  String val;
  String output;
  
  output.debugStr(name(), message_a, L":");
  Console::put(output);
  
  Console::increaseIndention();

  // call the tree debug method to debug the tree vertices itself
  //
  debugVertex(start_vertex_d, true);

  // that's it for sub-items, decrease indentation
  //
  Console::decreaseIndention();
  
  // exit gracefully
  //
  return true;
}

// method: debugVertex
//
// arguments:
// const GVLexicalNode*& lex_vert_a: the vertex in the lexical
// boolean recursive_a: whether debug all the following vertexes
//
// return: status
//
// this method find the successors and print debug information
//
boolean LexicalTree::debugVertex (GVLexicalNode*& lex_vert_a,
				  boolean recursive_a,
				  GALexicalNode* arc_a) {

  String weight(L" "); 

  // set the weight
  //
  if (arc_a != NULL ){
    if (arc_a->getEpsilon())
      weight.concat(L"-->");
    else
      weight.concat(arc_a->getWeight());
  }
  
  // build a debug string
  //
  SearchSymbol val;
  String output;
  
  Console::increaseIndention();

  // if it is a NULL vertex
  //
  if (root_vert_d == (GVLexicalNode*)NULL){
    output.debugStr(name(), L"tree", L"EMPTY TREE");
    Console::put(output);

    // decrease indention
    //
    Console::decreaseIndention();
    return false;
  }

  // if it is a NULL vertex
  //
  if (lex_vert_a == (GVLexicalNode*)NULL){
    output.debugStr(name(), L"vertex", L"NULL");
    Console::put(output);

    // decrease indention
    //
    Console::decreaseIndention();
    return false;
  }

  LexicalNode* curr_node = (LexicalNode*) NULL;

  // if it is a term vertex
  //
  if (lex_vert_a->isTerm()){
    output.debugStr(name(), L"terminal", L"TERMINAL");
    Console::put(output);
    
    // decrease indention
    //
    Console::decreaseIndention();
    return false;
  }

  
  // if it is a start vertex
  //
  if (lex_vert_a->isStart()){

    // if root vert is also a start
    //
    if ( root_vert_d->isStart()){
      val.assign(L"START");
    }
    else {
      curr_node = (LexicalNode*)root_vert_d->getItem();
      curr_node->getSymbol(val);
    }
    output.debugStr(name(), L"start", val);
    Console::put(output);
  }
  else{ // if it is not a star vertex

    curr_node = (LexicalNode*)lex_vert_a->getItem();
    if (debug_level_d  > Integral::BRIEF) {
      curr_node->debug(L"curr_node");
    }

    // if it is a NULL node
    //
    if (curr_node == (LexicalNode*)NULL){
      val.assign(L"NULL");
    }
    else {
      curr_node->getSymbol(val);
    }

    // add weight
    //
    weight.concat(L" ");
    weight.concat(val);
    val.assign(weight);
    output.debugStr(name(), L"symbol", val);
    
    //output.concat(weight);
    Console::put(output);
  }
  
  // not recursive
  //
  if ( !recursive_a ){

    // decrease indention
    //
    Console::decreaseIndention();
    return true;
  }
  
  // algorithm for this method:
  // self-explain
  //

  GVLexicalNode* succ_vert = (GVLexicalNode*)NULL;
  GALexicalNode* succ_arc  = (GALexicalNode*)NULL;
  boolean more_arcs = false;

  for ( more_arcs = lex_vert_a->gotoFirst(); more_arcs;
        more_arcs = lex_vert_a->gotoNext() ) {
    
    // get the successor
    //
    succ_arc = lex_vert_a->getCurr();
    succ_vert = lex_vert_a->getCurr()->getVertex();

    // if it is a NULL vertex
    //
    if (succ_vert == (GVLexicalNode*)NULL){
      debugVertex(succ_vert, false, succ_arc);
      continue;
    }

    // if it is a term vertex
    //
    if (succ_vert->isTerm()){
      debugVertex(succ_vert, false, succ_arc);
      continue;
    }
    
    LexicalNode* succ_node = (LexicalNode*)succ_vert->getItem();

    // if it is a NULL node
    //
    if (succ_node == (LexicalNode*)NULL){
      debugVertex(succ_vert, true, succ_arc);
      continue;
    }

    // this is the start of the lexial tree
    //
    if ( lex_vert_a->isStart()){
      debugVertex(succ_vert, true, succ_arc);
    }
    // if we reach the end of the pronuciation
    //
    else if ( succ_node->getSearchLevel()->getLevelIndex()
	 != curr_node->getSearchLevel()->getLevelIndex() ){
      // print the word
      //
      debugVertex(succ_vert, false, succ_arc);
    }
    else {
      // do it recursively
      //
      debugVertex(succ_vert, true, succ_arc);
    }
    
  }

  // decrease indention
  //
  Console::decreaseIndention();
  return true;
  
  // exit gracefully
  //
  return true;
  
}

