// file: $isip/class/search/StackSearch/ssrch_08.cc
// version: $Id: ssrch_08.cc 9742 2004-08-20 20:43:15Z may $
//

// isip include files
//
#include "StackSearch.h"

// method: clear
//
// arguments:
//  Integral::CMODE cmode: (input) clear mode
//
// return: a boolean value indicating status
//
// clear the contents of the search
//
boolean StackSearch::clear(Integral::CMODE cmode_a) {
  
  // if in retain mode then call initializeDecode and return
  //
  if (cmode_a == Integral::RETAIN) {

    // clean trace lists, search node lists and generate initial traces
    //
    return initializeLinearDecoder();
  }

  // clear all of the data members
  //
  else {
    
    features_d.clear(cmode_a);
    svm_features_d.clear(cmode_a);
    
    num_frames_d = ALL_FRAMES;
    current_frame_d = START_FRAME;
    n_best_d = DEF_N_BEST;
    stack_level_d = DEF_STACK_LEVEL;
    evaluation_mode_d = DEF_EVALUATION_MODE;
    decoding_mode_d = DEF_DECODING_MODE;
    score_normalization_d = DEF_SCORE_NORMALIZATION;
    user_requested_no_score_normalization_d = false;

    h_digraph_d->clear(cmode_a);
    max_frame_scores_d.clear(cmode_a);
    max_stack_scores_d.clear(cmode_a);
    stat_model_scores_d.clear(cmode_a);

    // clear the trace lists
    //
    clearTraceStorage();

    // clear the history pool
    //
    if (history_pool_d.length() > 0) {
      history_pool_d.clear();
    }

    // clear the context pool
    //
    if (context_pool_d.length() > 0) {
      context_pool_d.clear();
    }

    // clear the frame number
    //
    current_frame_d = START_FRAME;

    // exit gracefully
    //
    return true;
  }
}

// method: clearTraceStorage
//
// arguments: none
//
// return: logical error status
//
// clear the trace storage
//
boolean StackSearch::clearTraceStorage() {

  if (debug_level_d >= Integral::ALL) {
    Console::put(L"\n\nClearing trace storage");
  }
  
  // define local variables
  //
  Trace* tmp_trace;

  long num_levels = trace_lists_d.length();
  
  // use the term_hyps_d list as temporary storage
  //
  for (long i = 0; i < num_levels; i++) {
    while (!trace_lists_d(i).isEmpty()) {
      trace_lists_d(i).removeFirst(tmp_trace);
      term_hyps_d.insertLast(tmp_trace);
    }
  }

  // loop over all traces in the valid hypotheses list and move them
  // to the term list
  //
  while (!valid_hyps_d.isEmpty()) {
    tmp_trace = valid_hyps_d.pop();
    term_hyps_d.insertLast(tmp_trace);
  }
  
  // loop over all traces in the terminated hypotheses list
  //
  while (!term_hyps_d.isEmpty()) {
    
    // remove this trace from the list. if it is not referenced, then
    // delete it
    // 
    term_hyps_d.removeFirst(tmp_trace);

    if (tmp_trace->getRefCount() < 1) {
      Trace::deleteTrace(tmp_trace, true, true);	
    }
    else {
      term_hyps_d.insertLast(tmp_trace);
    }
  }
  
  // exit gracefully
  //
  return true;
}

// method: clearValidHypsTrace
//
// arguments: none
//
// return: logical error status
//
// clear the traces stored in the valid hypothesis and term list
//
boolean StackSearch::clearValidHypsTrace() {
    
  if (debug_level_d >= Integral::ALL) {
    Console::put(L"\n\nClearing valid hyps\n\n");
  }

  // define local variables
  //
  Trace* tmp_trace;

  // use the term_hyps_d list as temporary storage
  //
  while (!valid_hyps_d.isEmpty()) {
      tmp_trace = valid_hyps_d.pop();
      term_hyps_d.insertLast(tmp_trace);
  }

  // use the valid_hyps_d list as temporary storage
  //
  while (term_hyps_d.removeFirst(tmp_trace)) {
    if (tmp_trace != (Trace*)NULL) {
      Trace::deleteTrace(tmp_trace, true);
    }
  }
  
  // exit gracefully
  //
  return true;
}

// method: clearTermHypsTrace
//
// arguments: none
//
// return: logical error status
//
// clear the traces stored in the terminated hypothesis list
//
boolean StackSearch::clearTermHypsTrace() {
    
  // define local variables
  //
  Trace* tmp_trace = NULL;
  
  // remove traces from term_hyps_d
  //
  while (term_hyps_d.removeFirst(tmp_trace)) {
    if (tmp_trace != (Trace*)NULL) {
      Trace::deleteTrace(tmp_trace, true);
    }
  }
  
  // exit gracefully
  //
  return true;
}

// method: clearSearchNodesTraceLists
//
// arguments: none
//
// return: logical error status
//
// clear the list of traces from all the search nodes
//
boolean StackSearch::clearSearchNodesTraceLists() {
    
  // define local variables
  //
  long num_levels = getNumLevels();
  DiGraph<SearchNode>* sub_graph;
  SearchNode* snode;

  // loop through all levels
  //
  for (long level_num = 0; level_num < num_levels; level_num++) {
    
    long num_sub_graphs = getSearchLevel(level_num).getNumSubGraphs();
    
    // loop through all subgraphs
    //
    for (long sub_ind = 0; sub_ind < num_sub_graphs; sub_ind++) {

      sub_graph = &(getSearchLevel(level_num).getSubGraph(sub_ind));
      
      // loop through all vertices
      //
      for (boolean more_vertices = sub_graph->gotoFirst(); more_vertices;
	   more_vertices = sub_graph->gotoNext()) {
	
	snode = const_cast< SearchNode* >(sub_graph->getCurr()->getItem());
	snode->clearTraceList();
      }
    }
  }
  
  // exit gracefully
  //
  return true;
}

