
/***********************************************************
 *
 *                 replaceHa.c (for spread)
 *  This routine is to delete a cell in a heap. 
 *  It 1) searches the cell backward and sequentially from 
 *        the heap (if not found, returns a error message), 
 *     2) repalce that cell with the new min_cost and
 *        restore a heap order.
 *
 ************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <grass/gis.h>
#include "costHa.h"
#include "local_proto.h"

void
replaceHa(float new_min_cost, float angle, int row, int col,
	  struct costHa *heap, long *heap_len)
{
    long i, smaller_child = 0;

    G_debug(4, "in replaceHa()");

    if (*heap_len < 1)
	G_fatal_error("Programming ERROR: can't delete a cell from an empty list");

    /* search the cell with row and col from the heap */
    for (i = *heap_len; i >= 0; i--) {
	if (heap[i].row == row && heap[i].col == col)
	    break;
    }
    if (i == 0)
	G_fatal_error("Programming ERROR: can't find the old_cell from the list");

    /* replace this cell, fix the heap */
    /*take care upward */

    G_debug(4, "in replaceHa() before first while");
    while (i > 1 && new_min_cost < heap[i / 2].min_cost) {
	heap[i].min_cost = heap[i / 2].min_cost;
	heap[i].angle = heap[i / 2].angle;
	heap[i].row = heap[i / 2].row;
	heap[i].col = heap[i / 2].col;
	i = i / 2;
    }

    /*take care downward */
    if (2 * i <= *heap_len)
	smaller_child = 2 * i;

    if ((2 * i < *heap_len) &&
	(heap[2 * i].min_cost > heap[2 * i + 1].min_cost))
	smaller_child++;


    G_debug(4, "in replaceHa() before second while. smaller_child=%ld",
	smaller_child);

    while ( (smaller_child <= *heap_len) && (smaller_child > 0) &&
	   (new_min_cost > heap[smaller_child].min_cost)) {

	heap[i].min_cost = heap[smaller_child].min_cost;
	heap[i].angle = heap[smaller_child].angle;
	heap[i].row = heap[smaller_child].row;
	heap[i].col = heap[smaller_child].col;

	i = smaller_child;
	smaller_child = 2 * i;

	if ((2 * i < *heap_len) &&
	    (heap[2 * i].min_cost > heap[2 * i + 1].min_cost))
	    smaller_child++;
    }

    /*now i is the right position */
    heap[i].min_cost = new_min_cost;
    heap[i].angle = angle;
    heap[i].row = row;
    heap[i].col = col;

    G_debug(4, "replaceHa() done");

    return;
}
