// file: lat_merge_0.cc
//

// isip include files
//
#include "lattice.h"
#include "lattice_constants.h"

// method: merge_subpath_results_cc
//
// arguments:
//  Link_list* results: (output) list of all subpath results
//  Link_list* merge_results: (output) list of results to merge
//
// return: an int_4 indicating number of paths merged.
//
// This path merges a list of new subpath results with an existing list by determining
// whether new match instances already exist in the list of total matches. If not, the
// new match is added. If so, the new match is discarded.
//
int_4 Lattice::merge_subpath_results_cc(Link_list*& results_a, Link_list*& merge_results_a) {


  // keep count of the number we merged
  //
  int_4 merge_count = 0;

  // if the linked list is empty, add the first result (basically to seed)
  //
  if (results_a->get_head_cc() == (Link_node*)NULL) {
    
    Link_node* head = (Link_node*)merge_results_a->get_head_cc();
    Subpath_match* match = (Subpath_match*)head->get_item_cc();
    results_a->insert_cc(match);
    merge_count++;
  }

  // loop over matches to merge
  //
  for (Link_node* lnd = merge_results_a->get_head_cc(); 
       lnd != (Link_node*)NULL; lnd = lnd->get_next_cc()) {

    Subpath_match* cmp_match = (Subpath_match*)lnd->get_item_cc();

    // find out where (or if) to insert into results list
    //
    for (Link_node* lnd2 = results_a->get_head_cc();
	 lnd2 != (Link_node*)NULL; lnd2 = lnd2->get_next_cc()) {

      Subpath_match* merge_match = (Subpath_match*)lnd2->get_item_cc();

      if (cmp_match->equal_to_cc(merge_match)) {

	// already exists. compare scores.
	//
	if (cmp_match->get_score_cc() > merge_match->get_score_cc()) {
	  lnd2->set_item_cc((Subpath_match*)cmp_match);
	  merge_count++;
	}

	break;
      }
      if (!cmp_match->greater_than_cc(merge_match) && 
	  !cmp_match->equal_to_cc(merge_match)) {
	
	// found place to insert
	//
	Link_node* new_node = new Link_node();
	new_node->set_item_cc((Subpath_match*)cmp_match);
	new_node->set_prev_cc((Link_node*)lnd2->get_prev_cc());
	new_node->set_next_cc((Link_node*)lnd2);
	lnd2->set_prev_cc((Link_node*)new_node);

	// should the new node be the head node
	//
	if (new_node->get_prev_cc() == (Link_node*)NULL) {
	  results_a->set_head_cc((Link_node*)new_node);
	}
	merge_count++;
	break;
      }
      else if (lnd2->get_next_cc() == (Link_node*)NULL &&
	       !cmp_match->equal_to_cc(merge_match)) {

	// need to add it to the end
	//
	results_a->insert_cc((Subpath_match*)cmp_match);
	merge_count++;
	break;
      }

    }

  }
  
  // exit gracefully
  //
  return merge_count;
}
