// file: plist_add_0.cc
//

// isip include files
//
#include "path_list.h"
#include "path_list_constants.h"
#include <decoder_constants.h>
#include <word.h>
#include <nbest_node.h>

// method: add_path_cc
//
// arguments:
//  Nbest_node* nbest_node: (input) the partial path
//
// return: a logical_1 indicating status
//
// this method inserts the input partial path into the path list for this
// frame
//
logical_1 Path_list::add_path_cc(Nbest_node* nbest_node_a) {
  
  // define local variables
  //
  float_8 score = (float_8)0;
  float_8 new_score = nbest_node_a->get_score_cc();
  Nbest_node* nnode = (Nbest_node*)NULL;
  Link_node* lnd = (Link_node*)NULL;
  Link_node* node = (Link_node*)NULL;
  Link_node* lnode = (Link_node*)NULL;
  
  // memory manager
  //
  Memory_manager* manager = Link_list::get_manager_cc();
    
  // if the history node to add is null return ungracefully
  //
  if (nbest_node_a == (Nbest_node*)NULL) {
    return ISIP_FALSE;
  }

  // if no other histories exist allocate memory for the list
  //
  if (paths_d == (int_4)0) {
    paths_d = new Link_list();
  }

  // insert the new history at the right place
  //
  node = paths_d->get_head_cc();
  
  // loop over previous histories and compare
  //
  for (int_4 i = 0; i <= num_paths_d; i++) {

    // if this is the correct place insert here
    //
    if (node == (Link_node*)NULL) {
      
      // create node for history
      //
      lnode = manager->new_node_cc();
      lnode->set_item_cc((void_p)nbest_node_a);
      
      // insert path into list
      //
      if (lnd == (Link_node*)NULL) {
	lnode->insert_cc(node);
	paths_d->set_head_cc(lnode);
      }
      else {
	lnd->insert_cc(lnode);
      }
      paths_d->set_curr_cc(lnode);
      
      // update reference counts
      //
      num_paths_d++;
      break;
    }
  
    // get the history in the node
    //
    nnode = (Nbest_node*)(node->get_item_cc());
    score = nnode->get_score_cc();

    // insert new link node
    //
    if (new_score > score) {
      
      // create node for history
      //
      lnode = manager->new_node_cc();
      lnode->set_item_cc((void_p)nbest_node_a);
      
      // insert history
      //
      lnd = node->get_prev_cc();
      if (lnd == (Link_node*)NULL) {
	lnode->insert_cc(node);
	paths_d->set_head_cc(lnode);
      }
      else {
	lnd->insert_cc(lnode);
      }
      
      // update number of partial paths
      //
      num_paths_d++;
      break;
    }

    // get the next node
    //
    lnd = node;
    node = node->get_next_cc();
    
  } // end for all nodes
  
  // exit gracefully
  //
  return ISIP_TRUE;
}


