#include <stdlib.h>
#include <grass/gis.h>
#include <grass/glocale.h>
#include "watershed.h"
#include "string.h"


int com_line_Gwater (INPUT *input, OUTPUT *output)
{
  struct Cell_head *window;
  char	map_layer[48], buf[100], *prog_name, *mapset;
  double d;
  int	i;
  
  window = &(output->window);
  if (0 == G_yes ("Continue?", 1)) exit (EXIT_SUCCESS);
  input->haf_name = (char *) G_calloc (40, sizeof (char));
  input->accum_name = (char *) G_calloc (40, sizeof (char));

  G_message(_("\nThis set of questions will organize the command line for the"));
  G_message(_("%s program to run properly for your application."), NON_NAME);
  G_message(_("The first question is whether you want %s to run"), NON_NAME);
  G_message(_("in its fast mode or its slow mode.  If you run %s"), NON_NAME);
  G_message(_("in the fast mode, the computer will finish about 10 times faster"));
  G_message(_("than in the slow mode, but will not allow other programs to run"));
  G_message(_("at the same time.  The fast mode also places all of the data into"));
  G_message(_("RAM, which limits the size of window that can be run.  The slow"));
  G_message(_("mode uses disk space in the same hard disk partition as where GRASS is"));
  G_message(_("stored.  Thus, if the program does not work in the slow mode, you will"));
  G_message(_("need to remove unnecessary files from that partition.  The slow mode"));
  G_message(_("will allow other processes to run concurrently with %s.\n"), NON_NAME);

  sprintf (buf, "Do you want to use the fast mode of %s?", NON_NAME);
  input->com_line_ram = input->com_line_seg  = NULL;
  input->fast = 0;
  input->slow = 0;
  if (G_yes (buf,1))	{
	input->fast = 1;
  	input->com_line_ram = (char *) G_calloc (400, sizeof (char));
	prog_name = G_store (RAM_NAME);
  	sprintf(input->com_line_ram, 
		"%s/etc/water/%s", G_getenv("GISBASE"), RAM_NAME);
  	fprintf(stderr, "\nIf there is not enough ram for the fast mode (%s) to run,\n", RAM_NAME);
  	sprintf (buf, "should the slow mode (%s) be run instead?", SEG_NAME);
  	if (G_yes (buf,1)) {
		input->slow = 1;
  		input->com_line_seg = (char *) G_calloc (400, sizeof (char));
  		sprintf(input->com_line_seg, 
			"%s/etc/water/%s", G_getenv("GISBASE"), SEG_NAME);
	}
  } else	{
  	input->slow = 1;
	prog_name = G_store (SEG_NAME);
  	input->com_line_seg = (char *) G_calloc (400, sizeof (char));
  	sprintf(input->com_line_seg, 
		"%s/etc/water/%s", G_getenv("GISBASE"), SEG_NAME);
  }

  G_message(_("\nIf you hit <return> by itself for the next question, this"));
  G_message(_("program will terminate."));

  mapset = G_ask_old ("What is the name of the elevation map layer?",
  		map_layer, "cell", "cell");
  if (!mapset) exit (EXIT_FAILURE);
  if (input->fast)
  	com_line_add (&(input->com_line_ram), " el=", map_layer, mapset);
  if (input->slow)
  	com_line_add (&(input->com_line_seg), " el=", map_layer, mapset);

  G_message(_("\nOne of the options for %s is a `depression map'.  A"), prog_name);
  G_message(_("depression map indicates all the locations in the current map window where"));
  G_message(_("water accumulates and does not leave by the edge of the map. Lakes without"));
  G_message(_("outlet streams and sinkholes are examples of `depressions'.  If you wish to"));
  G_message(_("have a depression map, prepare a map where non-zero values indicate the"));
  G_message(_("locations where depressions occur.\n"));
  G_message(_("Hit <return> by itself for the next question if there is no depression map."));

  mapset = G_ask_old ("What is the name of the depression map layer?",
  		map_layer, "cell", "cell");
  if (mapset) {
     if (input->fast)
	com_line_add (&(input->com_line_ram), " de=", map_layer, mapset);
     if (input->slow)
	com_line_add (&(input->com_line_seg), " de=", map_layer, mapset);
  }

  G_message(_("\nThe %s program will divide the elevation map into a number of"), prog_name);
  G_message(_("watershed basins.  The number of watershed basins is indirectly determined"));
  G_message(_("by the `basin threshold' value.  The basin threshold is the area necessary for"));
  G_message(_("%s to define a unique watershed basin.  This area only applies to"), prog_name);
  G_message(_("`exterior drainage basins'.  An exterior drainage basin does not have any"));
  G_message(_("drainage basins flowing into it.  Interior drainage basin size is determined"));
  G_message(_("by the surface flow going into stream segments between stream interceptions."));
  G_message(_("Thus interior drainage basins can be of any size.  The %s program"), prog_name);
  G_message(_("also allows the user to relate basin size to potential overland flow"));
  G_message(_("(i.e., areas with low infiltration capacities will need smaller areas to"));
  G_message(_("develop stream channels than neighboring areas with high infiltration rates)."));
  G_message(_("The user can create a map layer with potential overland flow values, and"));
  G_message(_("%s will accumulate those values instead of area.\n"), prog_name);
  G_message(_("What unit of measure will you use for the basin threshold:"));

  do {
	G_message(_(" 1) acres,          2) meters sq., 3) miles sq., 4) hectares,"));
	G_message(_(" 5) kilometers sq., 6) map cells,  7) overland flow units"));
  	fprintf (stderr, _("Choose 1-7 or 0 to exit this program: "));
  	G_gets (map_layer);
  	sscanf (map_layer, "%d", &i);
  } while (i > 7 || i < 0);

  if (!i) exit(EXIT_SUCCESS);
  output->type_area = (char) i;

  G_message(_("\nHow large an area (or how many overland flow units) must a drainage basin")); 
  fprintf (stderr, _("be for it to be an exterior drainage basin: "));
  G_gets (map_layer);
  sscanf (map_layer, "%lf", &d);

  switch (i)	{
	case 1: if (input->fast)
			basin_com_add (&(input->com_line_ram), d, ACRE_TO_METERSQ, window);
		if (input->slow)
			basin_com_add (&(input->com_line_seg), d, ACRE_TO_METERSQ, window);
		break;
	case 2: if (input->fast)
			basin_com_add (&(input->com_line_ram), d, 1.0, window);
		if (input->slow)
			basin_com_add (&(input->com_line_seg), d, 1.0, window);
		break;
	case 3: if (input->fast) 
			basin_com_add (&(input->com_line_ram), d, MILESQ_TO_METERSQ, window);
		if (input->slow) 
			basin_com_add (&(input->com_line_seg), d, MILESQ_TO_METERSQ, window);
		break;
	case 4: if (input->fast) 
			basin_com_add (&(input->com_line_ram), d, HECTACRE_TO_METERSQ, window);
		if (input->slow)
			basin_com_add (&(input->com_line_seg), d, HECTACRE_TO_METERSQ, window);
		break;
	case 5: if (input->fast) 
			basin_com_add (&(input->com_line_ram), d, KILOSQ_TO_METERSQ, window); 
	 	if (input->slow) 
			basin_com_add (&(input->com_line_seg), d, KILOSQ_TO_METERSQ, window); 
		break; 
	case 6: if (input->fast) 
			basin_com_add (&(input->com_line_ram), d, (window->ns_res * window->ew_res), window);
		if (input->slow)
			basin_com_add (&(input->com_line_seg), d, (window->ns_res * window->ew_res), window);
		break;
	case 7: /* needs an overland flow map */
  		G_message(_("\nIf you hit <return> by itself for the next question, this"));
  		G_message(_("program will terminate."));
  		mapset = G_ask_old ("What is the name of the overland flow map layer?",
  				map_layer, "cell", "cell");
  		if (!mapset) exit (EXIT_FAILURE);
  		if (input->fast) {
  			com_line_add (&(input->com_line_ram), " ov=", map_layer, mapset);
			basin_com_add (&(input->com_line_ram), d, (window->ns_res * window->ew_res), window);
		}
  		if (input->slow) {
  			com_line_add (&(input->com_line_seg), " ov=", map_layer, mapset);
			basin_com_add (&(input->com_line_seg), d, (window->ns_res * window->ew_res), window);
		}
		break;
  }

  G_message(_("\n%s must create a map layer of watershed basins"), prog_name);
  G_message(_("before %s can run properly."), G_program_name());

  strcpy (buf, "Please name the output watershed basin map:");
  do	{
  	mapset = G_ask_new (buf, input->haf_name, "cell", "");
  } while (NULL == mapset);

  if (input->fast)
	com_line_add (&(input->com_line_ram), " ba=", input->haf_name, NULL);
  if (input->slow)
	com_line_add (&(input->com_line_seg), " ba=", input->haf_name, NULL);

  /* 
  This section queries the user about the armsed file input. If
  you want to make this an option,  the code below "COMMENT2" needs to be
  modified. 
  */

#ifdef ARMSED
  G_message(_("\n%s must create a file of watershed basin relationships"), prog_name);
  G_message(_("before %s can run properly."), G_program_name());

  input->ar_file_name = NULL;
  while (input->ar_file_name == NULL)	{
  	fprintf (stderr, _("\nPlease name this file:"));
  	G_gets (char_input);
  	if ( 1 != G_legal_filename (char_input))	{
		G_message(_("[%s] file name not legal"), char_input);
	} else	input->ar_file_name = G_store (char_input);
  }

  if (input->fast)
	com_line_add (&(input->com_line_ram), " ar=", input->ar_file_name, NULL);
  if (input->slow)
	com_line_add (&(input->com_line_seg), " ar=", input->ar_file_name, NULL);

/*
end of ARMSED comment code
*/

/*
COMMENT2 This section of code tells the program where to place the statistics
about the watershed basin. GRASS users don't need this (w/ r.stats), but the
format is suppossed to be "user-friendly" to hydrologists. For the stats to be
created, the armsed file output needs to exist. For the stats to be an option
in this program: 1) it should be querried before the armsed file query, and 2)
make the armsed file query manditory if this option is invoked.
*/

  G_message(_("\n%s will generate a lot of output.  Indicate a file"), G_program_name());
  G_message(_("name for %s to send the output to."), G_program_name());

  output->file_name = NULL;
  while (output->file_name == NULL)	{
  	fprintf (stderr, _("\nPlease name this file:"));
  	G_gets (char_input);
  	if ( 1 != G_legal_filename (char_input))	{
		G_message(_("[%s] file name not legal\n"), char_input);
	} else	output->file_name = G_store (char_input);
  }
 
 /* 
 end of COMMENT2
 */
#endif

  G_message(_("\nThe accumulation map from %s must be present for"), prog_name);
  G_message(_("%s to work properly."), G_program_name());
  strcpy (buf, "Please name the accumulation map:");
  do	{
  	mapset = G_ask_new (buf, input->accum_name, "cell", "");
  } while (NULL == mapset);

  if (input->fast)
	com_line_add (&(input->com_line_ram), " ac=", input->accum_name, NULL);
  if (input->slow)
	com_line_add (&(input->com_line_seg), " ac=", input->accum_name, NULL);

  G_message(_("\n%s can produce several maps not necessary for"), prog_name);
  G_message(_("%s to function (stream channels, overland flow aspect, and"), G_program_name());
  G_message(_("a display version of the accumulation map).  %s also has the"), prog_name);
  G_message(_("ability to generate several variables in the Revised Universal Soil Loss"));
  G_message(_("Equation (Rusle): Slope Length (LS), and Slope Steepness (S).\n"));

  sprintf (buf, "Would you like any of these maps to be created?");
  if (G_yes(buf, 1))	{
	mapset = G_ask_new ("", map_layer, "cell", "stream channel");
	if (mapset != NULL) {
	    if(input->fast)
		com_line_add (&(input->com_line_ram), " se=", map_layer, NULL);
	    if(input->slow)
		com_line_add (&(input->com_line_seg), " se=", map_layer, NULL);
	}
	mapset = G_ask_new ("", map_layer, "cell", "half basin");
	if (mapset != NULL) {
	    if(input->fast)
		com_line_add (&(input->com_line_ram), " ha=", map_layer, NULL);
	    if(input->slow)
		com_line_add (&(input->com_line_seg), " ha=", map_layer, NULL);
	}
	mapset = G_ask_new ("", map_layer, "cell", "overland aspect");
	if (mapset != NULL) {
	    if(input->fast)
		com_line_add (&(input->com_line_ram), " dr=", map_layer, NULL);
	    if(input->slow)
		com_line_add (&(input->com_line_seg), " dr=", map_layer, NULL);
	}
	mapset = G_ask_new ("", map_layer, "cell", "display");
	if (mapset != NULL) {
	    if(input->fast)
		com_line_add (&(input->com_line_ram), " di=", map_layer, NULL);
	    if(input->slow)
		com_line_add (&(input->com_line_seg), " di=", map_layer, NULL);
	}
	i = 0;
	mapset = G_ask_new ("", map_layer, "cell", "Slope Length");
	if (mapset != NULL) {
	    i = 1;
	    if(input->fast)
		com_line_add (&(input->com_line_ram), " LS=", map_layer, NULL);
	    if(input->slow)
		com_line_add (&(input->com_line_seg), " LS=", map_layer, NULL);
	}
	mapset = G_ask_new ("", map_layer, "cell", "Slope Steepness");
	if (mapset != NULL) {
	    i = 1;
	    if(input->fast)
		com_line_add (&(input->com_line_ram), " S=", map_layer, NULL);
	    if(input->slow)
		com_line_add (&(input->com_line_seg), " S=", map_layer, NULL);
	}

	if (i)	{
	 	G_message(_("\nThe Slope Length factor (LS) and Slope Steepness (S) are influenced by"));
	 	G_message(_("disturbed land.  %s reflects this with an optional map layer or value"), prog_name);
	 	G_message(_("where the value indicates the percent of disturbed (barren) land in that cell."));
	 	G_message(_("Type <return> if you do not have a disturbed land map layer."));

	 	mapset = G_ask_old ("", map_layer, "cell", "disturbed land");
	 	if (mapset != NULL) {
		    if (input->fast)
			com_line_add (&(input->com_line_ram), " r=", map_layer, NULL);
		    if (input->slow)
			com_line_add (&(input->com_line_seg), " r=", map_layer, NULL);
	 	}else {
	 		G_message(_("\nType the value indicating the percent of disturbed land.  This value will"));
			G_message(_("be used for every cell in the current region."));
			i = -6;
			while (i < 0 || i > 100) {
				fprintf (stderr, _("\nInput value here [0-100]: "));
				fgets (buf, 80, stdin);
				sscanf (buf, "%d", &i);
			}
			if (input->fast) com_add (&(input->com_line_ram), " r=", i);
			if (input->slow) com_add (&(input->com_line_seg), " r=", i);
	 	}

	 	/*       12345678901234567890123456789012345678901234567890123456789012345678901234567890 */
	 	G_message(_("\nOverland surface flow only occurs for a set distance before swales form."));
	 	G_message(_("Because of digital terrain model limitations, %s cannot pick up"), prog_name);
	 	G_message(_("these swales.  %s allows for an input (warning: kludge factor)"), prog_name);
	 	G_message(_("that prevents the surface flow distance from getting too long.  Normally,"));
	 	G_message(_("maximum slope length is around 600 feet (about 183 meters)."));

	 	i = -1;
	 	while (i < 0) {
			fprintf (stdout,"\nInput maximum slope length here (in meters): ");
			fgets (buf, 80, stdin);
			sscanf (buf, "%d", &i);
	 	}
	 	if (input->fast) com_add (&(input->com_line_ram), " ms=", i);
	 	if (input->slow) com_add (&(input->com_line_seg), " ms=", i);

	 	/*       12345678901234567890123456789012345678901234567890123456789012345678901234567890 */
  		G_message(_("\nRoads, ditches, changes in ground cover, and other factors will stop"));
		G_message(_("slope length.  You may input a raster map indicating the locations of these"));
		G_message(_("blocking factors.\n"));
  		G_message(_("Hit <return> by itself for the next question if there is no blocking map."));

  		mapset = G_ask_old ("What is the name of the blocking map layer?",
  				map_layer, "cell", "cell");
  		if (mapset) {
     			if (input->fast)
				com_line_add (&(input->com_line_ram), " ob=", map_layer, mapset);
     			if (input->slow)
				com_line_add (&(input->com_line_seg), " ob=", map_layer, mapset);
  		}
	}
  }

  return 0;
}

int 
com_line_add (char **com_line, char *prompt, char *map_layer, char *mapset)
{
	G_strcat (*com_line, prompt);
	G_strcat (*com_line, "\"");
	G_strcat (*com_line, map_layer);
	if (mapset)	{
		G_strcat (*com_line, "@");
		G_strcat (*com_line, mapset);
	}
	G_strcat (*com_line, "\"");

	return 0;
}

int basin_com_add (char **com_line, double d, double modifier, struct Cell_head *window)
{
	int i;
	char buf[20];

	i = (int) (.5 + modifier * d / window->ns_res / window->ew_res);
	if (i < 1) i = 1;
	sprintf (buf, " t=%d", i);
	G_strcat (*com_line, buf);

	return 0;
}

int com_add (char **com_line, char *prompt, int ril_value)
{
	char buf[20];

	G_strcat (*com_line, prompt);
	sprintf (buf, "%d", ril_value);
	G_strcat (*com_line, buf);

	return 0;
}
