// file: hist_ref_2.cc
//

// isip include files
//
#include "history.h"
#include "history_constants.h"

// method: decr_ref_count_cc
//
// arguments: none
//
// return: a logical_1 indicating status
//
// this method decrements the reference count for this history node.
// if the ref count becomes 0, the history node is removed from the
// list and returned to the memory manager, so the previous history
// node also needs to be decremented
//
logical_1 History::decr_ref_count_cc() {

  // decrease the history reference count
  //
  ref_count_d--;

  // check if this needs to be recursed downwards
  //
  if (ref_count_d > (int_4)0) {
    return ISIP_TRUE;
  }    
  
  // recurse it down to all the previous histories provided there are
  // some
  //
  if (prev_d == (Link_list*)NULL) {
    return ISIP_TRUE;
  }
  
  // dummy variable
  //
  Link_node* next = (Link_node*)NULL;
  History* hist = (History*)NULL;
  int_4 idx = (int_4)0;
  
  // loop over all previous path histories
  //
  for (Link_node* node = prev_d->get_head_cc();
       node != (Link_node*)NULL; node = next, idx++) {
    
    // get the next node
    //
    next = node->get_next_cc();
    
    // get the history node here
    //
    hist = (History*)(node->get_item_cc());
    
    // decrement the ref count here
    //
    hist->decr_ref_count_cc();
    
    // if the ref count here is less than 1 remove this node
    //
    if (hist->ref_count_d == (int_4)0) {
      
      // remove the history node
      //
      prev_d->remove_cc(node);

      // remove associated path score
      //
      remove_score_cc(idx);
      
      // reduce count
      //
      hist_num_d--;
    }
  }
    
  // if there are no more histories remaining release list memory
  //
  if (hist_num_d == (int_4)0) {
    delete prev_d;
    prev_d = (Link_list*)NULL;
  }
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
