// file: tr_tr_back_4.cc
//

// isip include files
//
#include "train_trace.h"
#include "train_trace_constants.h"

// method: set_back_ptr_cc
//
// arguments:
//  Train_Trace* trace: (input) the path back pointer to be set
//
// return: a logical_1 indicating status
//
// this method inserts the input trace in the path back pointer array
// at an appropriate location sorted by score
//
logical_1 Train_Trace::add_back_ptr_cc(Train_Trace* trace_a) {

  // if the back-pointer trace is null return ungracefully
  //
  if (trace_a == (Train_Trace*)NULL) {
    return ISIP_FALSE;
  }
  
  // if the backpointer array is not allocated yet flag an error
  //
  if (backptr_size_d == (int_4)0) {
    error_handler_cc((char_1*)"set_back_ptr_cc", (char_1*)"First set an appropriate size for the back-pointer array.");
  }

  // if required allocate memory
  //
  if (back_ptr_d == (Train_Trace**)NULL) {
    back_ptr_d = new Train_Trace*[backptr_size_d];
    for (int_4 i = 0; i < backptr_size_d; i++) {
      back_ptr_d[i] = (Train_Trace*)NULL;
    }
  }

  // perform insertion sort on the back-pointer array with the input
  // trace
  //
  logical_1 flag = ISIP_FALSE;

  // loop over the array
  //
  for (int_4 i = 0; i < backptr_size_d; i++) {

    // if there is space left in the array insert here
    //
    if (back_ptr_d[i] == (Train_Trace*)NULL) {

      // insert in current position, set flag and break
      //
      back_ptr_d[i] = trace_a;
      flag = ISIP_TRUE;
      break;
    }
    
    // if the score in the current array position is smaller, insert here
    //
    if (back_ptr_d[i]->score_d < trace_a->score_d) {

      // move subsequent traces down the array
      //
      for (int_4 j = backptr_size_d - (int_4)1; j > i; j--) {
	back_ptr_d[j] = back_ptr_d[j-1];
      }

      // insert in current position, set flag and break
      //
      back_ptr_d[i] = trace_a;
      flag = ISIP_TRUE;
      break;
    }
  }

  // exit gracefully
  //
  return flag;
}
