#include <stdio.h>
#include <grass/gis.h>

/* write the GRASS ASCII heading */
int writeGRASSheader(FILE *fp)
{
	struct Cell_head region;
	char buf[128];
	    
	G_get_window (&region);
	G_format_northing (region.north, buf, region.proj);
	fprintf (fp,"north: %s\n", buf);
	G_format_northing (region.south, buf, region.proj);
	fprintf (fp,"south: %s\n", buf);
	G_format_easting (region.east, buf, region.proj);
	fprintf (fp,"east: %s\n", buf);
	G_format_easting (region.west, buf, region.proj);
	fprintf (fp,"west: %s\n", buf);

	fprintf (fp,"rows: %d\n", region.rows);
	fprintf (fp,"cols: %d\n", region.cols);

	return 0;
}

/* write GRASS ASCII GRID */
int write_GRASS(
int fd, 
FILE *fp, 
int nrows, 
int ncols, 
int out_type, 
int dp, 
char *null_str)
{
	int row,col;
	void *ptr, *raster;
	char cell_buf[300];

	raster=G_allocate_raster_buf(out_type);

	for (row = 0; row < nrows; row++)
	{
		G_percent(row, nrows, 2);

		if (G_get_raster_row(fd, raster, row, out_type) < 0)
		   return(row);

		for (col = 0, ptr = raster; col < ncols; col++, 
			   ptr = G_incr_void_ptr(ptr, G_raster_size(out_type))) 
		{
			if(!G_is_null_value(ptr, out_type))
			{
			   if(out_type == CELL_TYPE)
			   fprintf (fp,"%d", *((CELL *) ptr));
	
			   else if(out_type == FCELL_TYPE)
			   {
			      sprintf(cell_buf, "%.*f", dp, *((FCELL *) ptr));
			      G_trim_decimal (cell_buf);
			      fprintf (fp,"%s", cell_buf);
			   }
			   else if(out_type == DCELL_TYPE)
			   {
			      sprintf(cell_buf, "%.*f", dp, *((DCELL *) ptr));
			      G_trim_decimal (cell_buf);
			      fprintf (fp,"%s", cell_buf);
			   }
			}
			else fprintf (fp,"%s", null_str);
			fprintf (fp," ");
		}
		fprintf (fp,"\n");
	}

	return (0);
}

int writeMFheader(FILE *fp, int dp, int width, int out_type)
{
	if(out_type==CELL_TYPE)fprintf(fp,"INTERNAL  1  (FREE)  -1\n");
	else fprintf(fp,"INTERNAL  1.  (%de%d.%d)  -1\n",width,dp+6,dp-1);

	return 0;
}

/* write MODFLOW ASCII ARRAY */
int write_MODFLOW(
int fd,
FILE *fp,
int nrows,
int ncols,
int out_type,
int dp,
int width)
{
	int row,col,colcnt;
	void *ptr, *raster;

	raster=G_allocate_raster_buf(out_type);

	for (row = 0; row < nrows; row++)
	{
		G_percent(row, nrows, 2);

		if (G_get_raster_row(fd, raster, row, out_type) < 0)return(row);

		colcnt=0;
		for (col = 0, ptr = raster; col < ncols; col++, 
		   ptr = G_incr_void_ptr(ptr, G_raster_size(out_type))) 
		{
			if(out_type == CELL_TYPE)
			{
			   if(G_is_null_value(ptr, out_type))*((CELL *)ptr)=0;
			   fprintf(fp," %d",*((CELL *)ptr));
			}
			else if(out_type == FCELL_TYPE)
			{
			   if(G_is_null_value(ptr, out_type))*((FCELL *)ptr)=0;
			   fprintf(fp,"%*.*e",dp+6,dp-1,*((FCELL *)ptr));
			}
			else if(out_type == DCELL_TYPE)
			{
			   if(G_is_null_value(ptr, out_type))*((DCELL *)ptr)=0;
			   fprintf(fp,"%*.*e",dp+6,dp-1,*((DCELL *)ptr));
			}

			colcnt+=1;
			if(colcnt>=width)
			{
			   colcnt=0;
			   fprintf(fp,"\n");
			}
		}
		if(colcnt>0)fprintf(fp,"\n");
	}

	return (0);
}

/* write the Surfer grid heading */
int writeGSheader(FILE *fp, char *name, char *mapset)
{
	struct Cell_head region;
	char fromc[128],toc[128];
	struct FPRange range;
	DCELL Z_MIN, Z_MAX;
	    
	if(G_read_fp_range (name, mapset, &range) < 0)return 1;

	fprintf (fp,"DSAA \n");

	G_get_window (&region);
	fprintf (fp,"%d %d\n", region.cols, region.rows);

	/* Projection set to -1 to force floating point output */
	G_format_easting (region.west+region.ew_res/2., fromc, -1);
	G_format_easting (region.east-region.ew_res/2., toc, -1);
	fprintf (fp,"%s %s\n", fromc, toc);

	G_format_northing (region.south+region.ns_res/2., fromc, -1);
	G_format_northing (region.north-region.ns_res/2., toc, -1);
	fprintf (fp,"%s %s\n", fromc, toc);

	G_get_fp_range_min_max(&range, &Z_MIN, &Z_MAX);
	fprintf (fp,"%f %f\n", (double)Z_MIN, (double)Z_MAX);
	
	return 0;

}

/* write Surfer Golden Software grid file */
int write_GSGRID(
int fd,
FILE *fp,
int nrows,
int ncols,
int out_type,
int dp,
char *null_str,
int width)
{
	int row,col,colcnt;
	void *ptr, *raster;
	char cell_buf[300];

	raster=G_allocate_raster_buf(out_type);

	for (row = nrows -1 ; row >= 0 ; row--)
	{
		G_percent((row-nrows)*(-1), nrows, 2);

		if (G_get_raster_row(fd, raster, row, out_type) < 0)return(row);

		colcnt=0;
		for (col = 0, ptr = raster; col < ncols; col++, 
		   ptr = G_incr_void_ptr(ptr, G_raster_size(out_type))) 
		{
			colcnt+=1;
			if(!G_is_null_value(ptr, out_type))
			{
			   if(out_type == CELL_TYPE)
			      fprintf (fp,"%d", *((CELL *) ptr));
			   else if(out_type == FCELL_TYPE)
			   {
			      sprintf(cell_buf, "%.*f", dp, *((FCELL *) ptr));
			      G_trim_decimal (cell_buf);
			      fprintf (fp,"%s", cell_buf);
			   }
			   else if(out_type == DCELL_TYPE)
			   {
			      sprintf(cell_buf, "%.*f", dp, *((DCELL *) ptr));
			      G_trim_decimal (cell_buf);
			      fprintf (fp,"%s", cell_buf);
			   }
			}
			else
			   fprintf (fp,"%s", null_str);

			if(colcnt>=width)
			{
			   fprintf(fp,"\n");
			   colcnt=0;
			}
			else fprintf(fp," ");
		}
		if(colcnt!=0)fprintf(fp,"\n");
		fprintf (fp,"\n");
	}

	return(0);
}
