/* indep.c                                                              */
#include <grass/gis.h>
#include <grass/raster.h>
#include <grass/glocale.h>

#include "ransurf.h"

void Indep(void)
{
    int Count, DRow, DCol;
    int Found, R, C;
    double RowDist, RowDistSq, ColDist;
    struct History history;

    G_debug(2, "indep()");

    Count = 0;
    Found = 0;

    while (CellCount > 0) {
	G_debug(3, "(CellCount):%d", CellCount);
	G_debug(3, "(Count):%d", Count);

        if (Found >= MaxCellsNum) {
            G_debug(1, "Hit maximum number of cells");
            break;
        }

	DRow = DoNext[Count].R;
	DCol = DoNext[Count++].C;

	if (0 != FlagGet(Cells, DRow, DCol)) {
	    /* FLAG_SET( Out, DRow, DCol); */
	    Out[DRow][DCol] = ++Found;
	    for (R = DRow; R < Rs; R++) {
		RowDist = NS * (R - DRow);
		if (RowDist >= MaxDistSq) {
		    R = Rs;
		}
		else {
		    RowDistSq = RowDist * RowDist;
		    for (C = DCol; C < Cs; C++) {
			ColDist = EW * (C - DCol);
			G_debug(3, "(RowDistSq):%.12lf", RowDistSq);
			G_debug(3, "(ColDist):%.12lf", ColDist);
			G_debug(3, "(MaxDistSq):%.12lf", MaxDistSq);
			
			if (MaxDistSq > RowDistSq + ColDist * ColDist) {
			    if (0 != FlagGet(Cells, R, C)) {
				G_debug(2, "unset()");
				FLAG_UNSET(Cells, R, C);
				CellCount--;
			    }
			}
			else {
			    C = Cs;
			}
		    }
		}
	    }

	    G_debug(2, "it1()");
	    for (R = DRow - 1; R >= 0; R--) {
		RowDist = NS * (DRow - R);
		if (RowDist >= MaxDistSq) {
		    R = 0;
		}
		else {
		    RowDistSq = RowDist * RowDist;
		    for (C = DCol; C < Cs; C++) {
			ColDist = EW * (C - DCol);
			if (MaxDistSq > RowDistSq + ColDist * ColDist) {
			    if (0 != FlagGet(Cells, R, C)) {
				G_debug(2, "unset()");
				FLAG_UNSET(Cells, R, C);
				CellCount--;
			    }
			}
			else {
			    C = Cs;
			}
		    }
		}
	    }

	    G_debug(2, "it2()");
	    for (R = DRow; R < Rs; R++) {
		RowDist = NS * (R - DRow);
		if (RowDist >= MaxDistSq) {
		    R = Rs;
		}
		else {
		    RowDistSq = RowDist * RowDist;
		    for (C = DCol - 1; C >= 0; C--) {
			ColDist = EW * (DCol - C);
			if (MaxDistSq > RowDistSq + ColDist * ColDist) {
			    if (0 != FlagGet(Cells, R, C)) {
				G_debug(2, "unset()");
				FLAG_UNSET(Cells, R, C);
				CellCount--;
			    }
			}
			else {
			    C = 0;
			}
		    }
		}
	    }

	    G_debug(2, "it3()");
	    for (R = DRow - 1; R >= 0; R--) {
		RowDist = NS * (DRow - R);
		if (RowDist >= MaxDistSq) {
		    R = 0;
		}
		else {
		    RowDistSq = RowDist * RowDist;
		    for (C = DCol - 1; C >= 0; C--) {
			ColDist = EW * (DCol - C);
			if (MaxDistSq > RowDistSq + ColDist * ColDist) {
			    if (0 != FlagGet(Cells, R, C)) {
				G_debug(2, "unset()");
				FLAG_UNSET(Cells, R, C);
				CellCount--;
			    }
			}
			else {
			    C = 0;
			}
		    }
		}
	    }
	}
    }

    G_debug(2, "outputting()");
    OutFD = Rast_open_c_new(Output->answer);

    G_message(_("Writing raster map <%s>..."),
	      Output->answer);
    for (R = 0; R < Rs; R++) {
	G_percent(R, Rs, 2);
	for (C = 0; C < Cs; C++) {
	    CellBuffer[C] = Out[R][C];
	    if(CellBuffer[C] == 0)
		Rast_set_null_value(&CellBuffer[C], 1, CELL_TYPE);
	}
	Rast_put_row(OutFD, CellBuffer, CELL_TYPE);
    }
    G_percent(1, 1, 1);
    
    Rast_close(OutFD);
    Rast_short_history(Output->answer, "raster", &history);
    Rast_command_history(&history);
    Rast_write_history(Output->answer, &history);
}
