#include "Gwater.h"

CELL
def_basin(int row, int col, CELL basin_num, double stream_length,
	  CELL old_elev)
{
    int r, rr, c, cc, ct, new_r[9], new_c[9];
    CELL value, new_elev;
    char downdir, direction, asp_value;
    int oldupdir, riteflag, leftflag, thisdir;
    ASP_FLAG af;

    for (;;) {
	cseg_put(&bas, &basin_num, row, col);
	ct = 0;
	for (r = row - 1, rr = 0; rr < 3; r++, rr++) {
	    for (c = col - 1, cc = 0; cc < 3; c++, cc++) {
		if (r >= 0 && c >= 0 && r < nrows && c < ncols) {
		    if (r == row && c == col)
			continue;
		    seg_get(&aspflag, (char *)&af, r, c);
		    asp_value = af.asp;
		    if (asp_value < 0)
			asp_value = -asp_value;
		    if (asp_value == drain[rr][cc]) {
			if (FLAG_GET(af.flag, SWALEFLAG)) {
			    new_r[++ct] = r;
			    new_c[ct] = c;
			}
		    }
		}
	    }
	}
	if (ct == 0) {
	    no_stream(row, col, basin_num, stream_length, old_elev);
	    return (basin_num);
	}
	if (ct >= 2) {
	    basin_num = split_stream(row, col, new_r, new_c, ct,
				     basin_num, stream_length, old_elev);
	    return (basin_num);
	}
	oldupdir = drain[row - new_r[1] + 1][col - new_c[1] + 1];
	seg_get(&aspflag, (char *)&af, row, col);
	downdir = af.asp;
	if (downdir < 0)
	    downdir = -downdir;
	riteflag = leftflag = 0;
	for (r = row - 1, rr = 0; rr < 3; r++, rr++) {
	    for (c = col - 1, cc = 0; cc < 3; c++, cc++) {
		if (r >= 0 && c >= 0 && r < nrows && c < ncols) {
		    if (r == row && c == col)
			continue;
		    seg_get(&aspflag, (char *)&af, r, c);
		    direction = af.asp;
		    if (direction == drain[rr][cc]) {
			thisdir = updrain[rr][cc];
			switch (haf_basin_side
				(oldupdir, (int) downdir, thisdir)) {
			case LEFT:
			    overland_cells(r, c, basin_num, basin_num - 1,
					   &new_elev);
			    leftflag++;
			    break;
			case RITE:
			    overland_cells(r, c, basin_num, basin_num,
					   &new_elev);
			    riteflag++;
			    break;
			}
		    }
		}
	    }
	}
	if (leftflag > riteflag) {
	    value = basin_num - 1;
	    cseg_put(&haf, &value, row, col);
	}
	else {
	    cseg_put(&haf, &basin_num, row, col);
	}
	if (arm_flag) {
	    if (sides == 8) {
		if (new_r[1] != row && new_c[1] != col)
		    stream_length += diag;
		else if (new_r[1] != row)
		    stream_length += window.ns_res;
		else
		    stream_length += window.ew_res;
	    }
	    else {			/* sides == 4 */

		seg_get(&aspflag, (char *)&af, row, col);
		asp_value = af.asp;
		if (asp_value < 0)
		    asp_value = -asp_value;
		if (asp_value == 2 || asp_value == 6) {
		    if (new_r[1] != row)
			stream_length += window.ns_res;
		    else
			stream_length += diag;
		}
		else {		/* asp_value == 4, 8 */

		    if (new_c[1] != col)
			stream_length += window.ew_res;
		    else
			stream_length += diag;
		}
	    }
	}
	row = new_r[1];
	col = new_c[1];
    }
}
