// file: $isip/class/search/SearchLevel/slev_07.cc
// version: $Id: slev_07.cc 10375 2006-01-19 17:45:29Z may $
//

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

// method: setBeam
//
// arguments:
//  float beam_threshold: (input) the desired beam threshold
//
// return: logical error status
//
// set the beam pruning threshold for this level
//
boolean SearchLevel::setBeam(float beam_threshold_a) {

  // range check the beam threshold
  //
  if (beam_threshold_a >= 0.0) {
    beam_threshold_d = beam_threshold_a;
  }
  else {
    return Error::handle(name(), L"setBeam", Error::ARG, __FILE__,
                         __LINE__);
  }
  
  // exit gracefully
  //
  return true;
}

// method: setContext
//
// arguments:
//  long left_context: (input) the left context lenght
//  long right_context: (input) the right context length
//
// return: logical error status
//
// set the context lengths for this level
//
boolean SearchLevel::setContext(long left_context_a, long right_context_a) {

  // range check the left and right context
  //
  if ((left_context_a >= 0) && (right_context_a >= 0)) {
    left_context_d = left_context_a;
    right_context_d = right_context_a;
  }
  else {
    return Error::handle(name(), L"setContext", Error::ARG, __FILE__,
                         __LINE__);
  }

  // exit gracefully
  //
  return true;
}

// method: setInstance
//
// arguments:
//  boolean use_instance_prune: (input) should this level use instance pruning
//  long instance_threshold: (input) the desired instance threshold
//
// return: logical error status
//
// set the instance pruning parameters for this level
//
boolean SearchLevel::setInstance(boolean use_instance_prune_a,
				 long instance_threshold_a) {

  // set the instance pruning flag
  //
  use_instance_prune_d = use_instance_prune_a;

  // range check the instance threshold
  //
  if (instance_threshold_a >= 0) {
    instance_threshold_d = instance_threshold_a;
  }
  else {
    return Error::handle(name(), L"setInstance", Error::ARG, __FILE__,
                         __LINE__);
  }
  
  // exit gracefully
  //
  return true;
}

// method: setInstance
//
// arguments:
//  long instance_threshold: (input) the desired instance threshold
//
// return: logical error status
//
// set the instance pruning threshold for this level
//
boolean SearchLevel::setInstance(long instance_threshold_a) {

  // range check the instance threshold
  //
  if (instance_threshold_a >= 0) {
    instance_threshold_d = instance_threshold_a;
  }
  else {
    return Error::handle(name(), L"setInstance", Error::ARG, __FILE__,
                         __LINE__);
  }
  
  // exit gracefully
  //
  return true;
}

// method: setNSymbol
//
// arguments:
//  boolean use_nsymbol: (input) should this level use nsymbol probabilities
//  long nsymbol_order: (input) the desired nsymbol order
//
// return: logical error status
//
// set the nsymbol parameters for this level
//
boolean SearchLevel::setNSymbol(boolean use_nsymbol_a,
				long nsymbol_order_a) {

  // set the nsymbol flag
  //
  use_nsymbol_d = use_nsymbol_a;

  // range check the nsymbol order
  //
  if (nsymbol_order_a > 0) {
    nsymbol_order_d = nsymbol_order_a;
  }
  else {
    return Error::handle(name(), L"setNSymbol", Error::ARG, __FILE__,
                         __LINE__);
  }
  
  // exit gracefully
  //
  return true;
}

// method: setNSymbol
//
// arguments:
//  long nsymbol_order: (input) the desired nsymbol order
//
// return: logical error status
//
// set the nsymbol order for this level
//
boolean SearchLevel::setNSymbol(long nsymbol_order_a) {

  // range check the nsymbol order
  //
  if (nsymbol_order_a > 0) {
    nsymbol_order_d = nsymbol_order_a;
  }
  else {
    return Error::handle(name(), L"setNSymbol", Error::ARG, __FILE__,
                         __LINE__);
  }
  
  // exit gracefully
  //
  return true;
}

// method: setNumSubGraphs
//
// arguments:
//  long num: (input) the number of subgraphs
//
//  return: a boolean indicating status
//
boolean SearchLevel::setNumSubGraphs(long num_a) {

  sub_graphs_d.setLength(num_a);

  // set the memory allocation mode of each graph to be false
  //
  for (long i = 0; i < num_a; i++) {
    sub_graphs_d(i).setAllocationMode(DstrBase::USER);
  }

  // exit gracefully
  //
  return true;
}

// method: getSymbolIndex
//
// arguments:
//  const SearchSymbol& input_symbol: (input) the symbol to lookup
//
// return: index of the input symbol, -1 if not found
//
// find the index of the given symbol
//
long SearchLevel::getSymbolIndex(const SearchSymbol& input_symbol_a) const {

  // initialize the output index
  //
  long out_ind = -1;

  // loop over the symbol table until the input symbol is found
  //
  long max_loops = symbol_table_d.length();
  boolean found = false;
  
  for (long i = 0; (i < max_loops) && !found; i++) {
    if (symbol_table_d(i).eq(input_symbol_a)) {
      out_ind = i;
      found = true;
    }
  }

  // return the index
  //
  return out_ind;
}
