/*
*$Id: input.c,v 2.2.4.2 2006/10/17 18:11:42 markus Exp $
************************************************************
* MODULE: r.le.patch/input.c                               *
*         Version 5.0                Nov. 1, 2001          *
*				                           *
* AUTHOR: W.L. Baker, University of Wyoming                *
*         BAKERWL@UWYO.EDU                                 *
*                                                          *
* PURPOSE: To analyze attributes of patches in a landscape *
*         input.c reads the user's requests from the       *
*         and sets appropriate flags                       *
*				                           *
* COPYRIGHT: (C) 2001 by W.L. Baker                        *
*                                                          *
* This program is free software under the GNU General      *
* Public License(>=v2).  Read the file COPYING that comes  *
* with GRASS for details                                   *
*				                           *
************************************************************/

#include <stdio.h>
#include <stdlib.h>

#include <grass/config.h>
#include "patch.h"



extern struct CHOICE *choice;

void user_input (int argc, char **argv)

{

   int i,count=0;

                         /* setup the GRASS parsing routine
                            structures to be used to read
                            in the user's parameter choices */

   struct Flag *cor;
   struct Flag *pat;
   struct Flag *bound;
   struct Flag *trace;
   struct Flag *units;
   struct Option *name;
   struct Option *sampling_method;
   struct Option *region;
   struct Option *att;
   struct Option *size;
   struct Option *edge;
   struct Option *core;
   struct Option *shape;
   struct Option *shape_m;
   struct Option *boundary;
   struct Option *perimeter;
   struct Option *out;


                         /* use the GRASS parsing routines
                            to read in the user's parameter
                            choices */

   cor = G_define_flag();
   cor->key              = 'c';
   cor->description      = "Output map 'interior' with patch cores (specify co1 & co2)";

   pat = G_define_flag();
   pat->key              = 'n';
   pat->description      = "Output map 'num' with patch numbers";

   bound = G_define_flag();
   bound->key       = 'p';
   bound->description    = "Include sampling area boundary as perimeter";

   trace = G_define_flag();
   trace->key            = 't';
   trace->description    = "Use 4 neighbor instead of 8 neighbor tracing";

   units = G_define_flag();
   units->key            = 'u';
   units->description    = "Output maps 'units_x' with sampling units for each scale x ";

   name = G_define_option();
   name->key             = "map";
   name->description     = "Raster map to be analyzed";
   name->type            = TYPE_STRING;
   name->gisprompt       = "old,cell,raster";
   name->required        = YES;

   sampling_method = G_define_option();
   sampling_method->answer      = "w";
   sampling_method->key         = "sam";
   sampling_method->description = "Sampling method (choose only 1 method): \n"
   "\tw = whole map     u = units     m = moving window    r = regions";
   sampling_method->type        = TYPE_STRING;
   sampling_method->multiple    = NO;
   sampling_method->required    = NO;

   region = G_define_option();
   region->key           = "reg";
   region->description   = "Name of regions map, only when sam = r; omit otherwise";
   region->type          = TYPE_STRING;
   region->gisprompt     = "old,cell,raster";
   region->required      = NO;

   att = G_define_option();
   att->key              = "att";
   att->description      = "a1 = mn. pixel att. \t\ta2 = s.d. pixel att.\n"
   "\ta3 = mn. patch att. \t\ta4 = s.d. patch att.\n"
   "\ta5 = cover by gp \t\ta6 = density by gp\n"
   "\ta7 = total density \t\ta8 = eff. mesh number";
   att->options		 = "a1,a2,a3,a4,a5,a6,a7,a8";
   att->type             = TYPE_STRING;
   att->multiple         = YES;
   att->required         = NO;
   
   size = G_define_option();
   size->key        = "siz";
   size->description     = "s1 = mn. patch size\t\ts2 = s.d. patch size\n"
   "\ts3 = mn. patch size by gp\ts4 = s.d. patch size by gp \n"
   "\ts5 = no. by size class\t\ts6 = no. by size class by gp\n"
   "\ts7 = eff. mesh size \t\ts8 = deg. landsc. division";
   size->options         = "s1,s2,s3,s4,s5,s6,s7,s8";
   size->type            = TYPE_STRING;
   size->multiple        = YES;
   size->required        = NO;

   edge = G_define_option();
   edge->key             = "co1";
   edge->description     = "Depth-of-edge-influence in pixels (integer) for use with co2";
   edge->type            = TYPE_INTEGER;
   edge->required        = NO;

   core = G_define_option();
   core->key        = "co2";
   core->description     = "Core size measures (required if co1 was specified):\n"
   "\tc1 = mn. core size\t\tc2 = s.d. core size\n"
   "\tc3 = mn. edge size\t\tc4 = s.d. edge size\n"
   "\tc5 = mn. core size by gp\tc6 = s.d. core size by gp\n"
   "\tc7 = mn. edge size by gp\tc8 = s.d. edge size by gp\n"
   "\tc9 = no. by size class\t\tc10 = no. by size class by gp";
   core->options         = "c1,c2,c3,c4,c5,c6,c7,c8,c9,c10";
   core->type            = TYPE_STRING;
   core->multiple        = YES;
   core->required        = NO;

   shape = G_define_option();
   shape->key            = "sh1";
   shape->description    = "Shape index (choose only 1 index):\n"
   "\tm1 = per./area    m2 = corr. per./area    m3 = rel. circum. circle";
   shape->type           = TYPE_STRING;
   shape->multiple       = NO;
   shape->required       = NO;

   shape_m = G_define_option();
   shape_m->key               = "sh2";
   shape_m->description       = "Shape measures (required if sh1 was specified):\n"
   "\th1 = mn. patch shape\t\th2 = s.d. patch shape\n"
   "\th3 = mn. patch shape by gp\th4 = s.d. patch shape by gp\n"
   "\th5 = no. by shape class \th6 = no. by shape class by gp";
   shape_m->options           = "h1,h2,h3,h4,h5,h6";
   shape_m->type              = TYPE_STRING;
   shape_m->multiple          = YES;
   shape_m->required          = NO;

   boundary = G_define_option();
   boundary->key                 = "bnd";
   boundary->description         = "n1 = mn. twist number           n2 = s.d. twist number\n"
   "\tn3 = mn. omega index            n4 = s.d. omega index";
   boundary->options             = "n1,n2,n3,n4";
   boundary->type                = TYPE_STRING;
   boundary->multiple            = YES;
   boundary->required            = NO;

   perimeter = G_define_option();
   perimeter->key             = "per";
   perimeter->description     = "p1 = sum of perims.\t\tp4 = sum of perims. by gp\n"
   "\tp2 = mn. per.\t\t\tp5 = mn. per. by gp\n"
   "\tp3 = s.d. per.\t\t\tp6 = s.d. per. by gp";
   perimeter->options         = "p1,p2,p3,p4,p5,p6";
   perimeter->type            = TYPE_STRING;
   perimeter->multiple        = YES;
   perimeter->required        = NO;

   out = G_define_option();
   out->key          = "out";
   out->description  = "Name of output file for individual patch measures, when sam=w,u,r;\n"
   "\tif out=head, then column headings will be printed";
   out->type         = TYPE_STRING;
   out->required     = NO;


   if (G_parser(argc,argv)) {
      exit(EXIT_FAILURE);
   }
                         /* record the user inputs for map,
                            sam and out parameters */

   G_strcpy(choice->fn, name->answer);

   choice->wrum = sampling_method->answer[0];

   if (out->answer && choice->wrum != 'm')
      G_strcpy(choice->out,out->answer);
   else if (out->answer && choice->wrum == 'm') {
         fprintf(stderr, "\n");
         fprintf(stderr, "   ***************************************************\n");
         fprintf(stderr, "    You can use the out parameter only when sam=w,u,r \n");
         fprintf(stderr, "   ***************************************************\n");
         exit(EXIT_FAILURE);
   } 
   else
      G_strcpy(choice->out,"");

                         /* check for unacceptable values for
                            input parameters for sam */

   if (strcmp(sampling_method->answer,"w") && 
       strcmp(sampling_method->answer,"u") &&
       strcmp(sampling_method->answer,"m") && 
       strcmp(sampling_method->answer,"r")) {
          fprintf(stderr, "\n");
          fprintf(stderr, "   ***************************************************\n");
          fprintf(stderr, "    You input an unacceptable value for parameter sam \n");
          fprintf(stderr, "   ***************************************************\n");
          exit(EXIT_FAILURE);
   }

  
                         /* check for unacceptable values for
                            input parameters for sh1 */

   if (shape->answer) {
      if (strcmp(shape->answer,"m1") && 
          strcmp(shape->answer,"m2") &&
          strcmp(shape->answer,"m3")) {
             fprintf(stderr, "\n");
             fprintf(stderr, "   ***************************************************\n");
             fprintf(stderr, "    You input an unacceptable value for parameter sh1 \n");
             fprintf(stderr, "   ***************************************************\n");
             exit(EXIT_FAILURE);
      }
   }

                         /* check for multiple values for 
                            parameters that accept only 1 */

   if (sampling_method->answer)
      if (sampling_method->answers[1]) {
         fprintf(stderr, "\n");
         fprintf(stderr, "   **********************************************\n");
         fprintf(stderr, "    You input multiple values for parameter sam, \n");
         fprintf(stderr, "    but only one is allowed                      \n");
         fprintf(stderr, "   **********************************************\n");
         exit(EXIT_FAILURE);
      }

   if (shape->answer)
      if (shape->answers[1]) {
         fprintf(stderr, "\n");
         fprintf(stderr, "   **********************************************\n");
         fprintf(stderr, "    You input multiple values for parameter sh1, \n");
         fprintf(stderr, "    but only one is allowed                      \n");
         fprintf(stderr, "   **********************************************\n");
         exit(EXIT_FAILURE);
      }

                         /* if the core flag -c is specified,
                            then set the choice->coremap flag
                            to 1 */

   choice->coremap = 0;
   if (!strcmp(sampling_method->answer,"w") && cor->answer)
      choice->coremap = 1;
   else if (strcmp(sampling_method->answer,"w") && cor->answer) {
      fprintf(stderr, "\n");
      fprintf(stderr, "   ***********************************************\n");
      fprintf(stderr, "    You requested output of map 'core' with patch \n");
      fprintf(stderr, "    cores, by using flag -c, but this option      \n");
      fprintf(stderr, "    is only available when sam=w                  \n");
      fprintf(stderr, "   ***********************************************\n");
      exit(EXIT_FAILURE);
   }

                         /* if the pat flag -n is specified,
                            then set the choice->coremap flag
                            to 1 */


   choice->patchmap = 0;
   if (!strcmp(sampling_method->answer,"w") && pat->answer)
      choice->patchmap = 1;
   else if (strcmp(sampling_method->answer,"w") && pat->answer) {
      fprintf(stderr, "\n");
      fprintf(stderr, "   **********************************************\n");
      fprintf(stderr, "    You requested output of map 'num' with patch \n");
      fprintf(stderr, "    numbers, by using flag -n, but this option   \n");
      fprintf(stderr, "    is only available when sam=w                 \n");
      fprintf(stderr, "   **********************************************\n");
      exit(EXIT_FAILURE);
   }



                         /* if the 4 neighbor tracing flag -t
                            is specified, then set the
                            choice->trace flag to 0 */

   choice->trace = 1;
   if (trace->answer)
      choice->trace = 0;

                         /* if the -p flag is specified, then
                            set the choice->perim2 flag to 0 */

   if (bound->answer)
      choice->perim2 = 0;
   else
      choice->perim2 = 1;

                         /* if the -u flag is specified, then
                            set the choice->units flag to 1 */

   choice->units = 0;
   if (!strcmp(sampling_method->answer,"u") && units->answer)
      choice->units = 1;
   else if (strcmp(sampling_method->answer,"u") && units->answer) {
      fprintf(stderr, "\n");
      fprintf(stderr, "   ***************************************************\n");
      fprintf(stderr, "    You requested output of map 'units' with sampling \n");
      fprintf(stderr, "    units, by using flag -u, but this option is only  \n");
      fprintf(stderr, "    available when sam=u                              \n");
      fprintf(stderr, "   ***************************************************\n");
      exit(EXIT_FAILURE);
   }


                         /* if the co1 parameter is specified,
                            then save the value of edge width
                            in choice->edge */

   choice->edge = 0;
   if (edge->answer) {
      choice->edge = atoi(edge->answer);
      if (choice->edge < 0 ||
          choice->edge >= G_window_rows()||
	  choice->edge >= G_window_cols()) {
           fprintf(stderr, "\n");
           fprintf(stderr, "   ***********************************************\n");
           fprintf(stderr, "    You chose values for co1 that are either less \n");
           fprintf(stderr, "    than 0 or too large                           \n");
           fprintf(stderr, "   ***********************************************\n");
           exit(EXIT_FAILURE);
      }
   }


                         /* if sampling_method is by REGION
                            get region file name.  Check to see
                            that the name was input */

   if (!strcmp(sampling_method->answer,"r")) {
      if (region->answer)
         G_strcpy(choice->reg,region->answer);
      else {
           fprintf(stderr, "\n");
           fprintf(stderr, "   ***********************************************\n");
           fprintf(stderr, "    You requested sampling by region, but did not \n");
           fprintf(stderr, "    input the name of the region using the reg=   \n");
           fprintf(stderr, "    parameter                                     \n");
           fprintf(stderr, "   ***********************************************\n");
           exit(EXIT_FAILURE);
      }
   }

   if (region->answer)
      if (strcmp(sampling_method->answer,"r")) {
           fprintf(stderr, "\n");
           fprintf(stderr, "   ***********************************************\n");
           fprintf(stderr, "    You requested sampling by region, by using    \n");
           fprintf(stderr, "    the reg= parameter, but did not input the     \n");
           fprintf(stderr, "    sam=r parameter                               \n");
           fprintf(stderr, "   ***********************************************\n");
           exit(EXIT_FAILURE);
   }

                         /* initialize flag arrays in choice
                            data structure. */

   for (i = 0; i < 3;  i++) choice->Mx[i]    = 0;
   for (i = 0; i < 9;  i++) choice->att[i]   = 0;
   for (i = 0; i < 9;  i++) choice->size[i]  = 0;
   for (i = 0; i < 11; i++) choice->core[i]  = 0;
   for (i = 0; i < 8;  i++) choice->shape[i] = 0;
   for (i = 0; i < 5;  i++) choice->boundary[i] = 0;
   for (i = 0; i < 8;  i++) choice->perim[i] = 0;


   if (att->answer) {
      choice->att[0]=1;       /* flag for attribute computations. */
      for (i = 0; att->answers[i] != NULL; i++) {
         count++;
              if (!strcmp(att->answers[i],"a1"))   choice->att[1] = 1;
         else if (!strcmp(att->answers[i],"a2"))   choice->att[2] = 1;
         else if (!strcmp(att->answers[i],"a3"))   choice->att[3] = 1;
         else if (!strcmp(att->answers[i],"a4"))   choice->att[4] = 1;
         else if (!strcmp(att->answers[i],"a5"))   choice->att[5] = 1;
         else if (!strcmp(att->answers[i],"a6"))   choice->att[6] = 1;
         else if (!strcmp(att->answers[i],"a7"))   choice->att[7] = 1;
         else if (!strcmp(att->answers[i],"a8"))   choice->att[8] = 1;
      }
   }

   if (size->answer) {
      choice->size[0]=1;           /* flag for size computations. */
      for (i = 0; size->answers[i] != NULL; i++) {
         count++;
              if (!strcmp(size->answers[i],"s1"))   choice->size[1] = 1;
         else if (!strcmp(size->answers[i],"s2"))   choice->size[2] = 1;
         else if (!strcmp(size->answers[i],"s3"))   choice->size[3] = 1;
         else if (!strcmp(size->answers[i],"s4"))   choice->size[4] = 1;
         else if (!strcmp(size->answers[i],"s5"))   choice->size[5] = 1;
         else if (!strcmp(size->answers[i],"s6")) {
                                                    choice->size[6] = 1;
                                                    choice->size2   = 1;
         }
         else if (!strcmp(size->answers[i],"s7"))   choice->size[7] = 1;
         else if (!strcmp(size->answers[i],"s8"))   choice->size[8] = 1;
      }
   }

   if (core->answer || edge->answer || cor->answer) {
      if (core->answer && edge->answer) {
         choice->core[0]=1;        /* flag for core computations. */
         for (i = 0; core->answers[i] != NULL; i++) {
            count++;
                 if (!strcmp(core->answers[i],"c1"))   choice->core[1] = 1;
            else if (!strcmp(core->answers[i],"c2"))   choice->core[2] = 1;
            else if (!strcmp(core->answers[i],"c3"))   choice->core[3] = 1;
            else if (!strcmp(core->answers[i],"c4"))   choice->core[4] = 1;
            else if (!strcmp(core->answers[i],"c5"))   choice->core[5] = 1;
            else if (!strcmp(core->answers[i],"c6"))   choice->core[6] = 1;
            else if (!strcmp(core->answers[i],"c7"))   choice->core[7] = 1;
            else if (!strcmp(core->answers[i],"c8"))   choice->core[8] = 1;
            else if (!strcmp(core->answers[i],"c9"))   choice->core[9] = 1;
            else if (!strcmp(core->answers[i],"c10")) {
                                                       choice->core[10] = 1;
                                                       choice->core2    = 1;
               }
           }
      }
      else {
         if (cor->answer) {
              fprintf(stderr, "\n");
              fprintf(stderr, "   ***********************************************\n");
              fprintf(stderr, "    You requested output of map 'core' with patch \n");
              fprintf(stderr, "    cores, by using flag -c, but did not input    \n");
              fprintf(stderr, "    both parameter co1 and co2                    \n");
              fprintf(stderr, "   ***********************************************\n");
              exit(EXIT_FAILURE);
         }
         else {
              fprintf(stderr, "\n");
              fprintf(stderr, "   ***********************************************\n");
              fprintf(stderr, "    You requested core size measures, but did not \n");
              fprintf(stderr, "    input both parameter co1 and co2              \n");
              fprintf(stderr, "   ***********************************************\n");
              exit(EXIT_FAILURE);
         }
      }
   }

   if (shape->answer || shape_m->answer) {
      if (shape->answer && shape_m->answer) {
              if (!strcmp(shape->answer,"m1"))   choice->Mx[1] = 1;
         else if (!strcmp(shape->answer,"m2"))   choice->Mx[2] = 1;
         else if (!strcmp(shape->answer,"m3"))   choice->Mx[3] = 1;
         choice->shape[0]=1;       /* flag for shape computations. */
         for (i = 0; shape_m->answers[i] != NULL; i++) {
            count++;
                 if (!strcmp(shape_m->answers[i],"h1")) choice->shape[1]=1;
            else if (!strcmp(shape_m->answers[i],"h2")) choice->shape[2]=1;
            else if (!strcmp(shape_m->answers[i],"h3")) choice->shape[3]=1;
            else if (!strcmp(shape_m->answers[i],"h4")) choice->shape[4]=1;
            else if (!strcmp(shape_m->answers[i],"h5")) choice->shape[5]=1;
            else if (!strcmp(shape_m->answers[i],"h6")) {
                                                        choice->shape[6]=1;
                                                        choice->shape2  =1;
            }
         }
      }
      else {
           fprintf(stderr, "\n");
           fprintf(stderr, "   **********************************************\n");
           fprintf(stderr, "    You requested shape measurement, but did not \n");
           fprintf(stderr, "    input both parameter sh1 and sh2             \n");
           fprintf(stderr, "   **********************************************\n");
           exit(EXIT_FAILURE);
      }
   }

   if (boundary->answer) {
      choice->boundary[0]=1;          /* flag for boundary complex. comput. */
      for (i = 0; boundary->answers[i] != NULL; i++) {
         count++;
              if (!strcmp(boundary->answers[i],"n1")) choice->boundary[1]=1;
         else if (!strcmp(boundary->answers[i],"n2")) choice->boundary[2]=1;
         else if (!strcmp(boundary->answers[i],"n3")) choice->boundary[3]=1;
         else if (!strcmp(boundary->answers[i],"n4")) choice->boundary[4]=1;
      }
   }

   if (perimeter->answer) {
      choice->perim[0]=1;          /* flag for perim. computations. */
      for (i = 0; perimeter->answers[i] != NULL; i++) {
         count++;
              if (!strcmp(perimeter->answers[i],"p1")) choice->perim[1]=1;
         else if (!strcmp(perimeter->answers[i],"p2")) choice->perim[2]=1;
         else if (!strcmp(perimeter->answers[i],"p3")) choice->perim[3]=1;
         else if (!strcmp(perimeter->answers[i],"p4")) choice->perim[4]=1;
         else if (!strcmp(perimeter->answers[i],"p5")) choice->perim[5]=1;
         else if (!strcmp(perimeter->answers[i],"p6")) choice->perim[6]=1;
      }
   }

   if (choice->wrum == 'm' && count > 25) {
      fprintf(stderr, "\n");
      fprintf(stderr, "   ****************************************************\n");
      fprintf(stderr, "    You can only choose up to 25 simultaneous measures \n");
      fprintf(stderr, "    when using sam=m.  Please redo your request.       \n");
      fprintf(stderr, "   ****************************************************\n");
      exit(EXIT_FAILURE);
   }

   if (!att->answer && !size->answer && !shape->answer && !shape_m->answer
      && !boundary->answer && !perimeter->answer && !core->answer) {
      fprintf(stderr, "\n");
      fprintf(stderr, "   **************************************************\n");
      fprintf(stderr, "    You did not select any measures to be calculated \n");
      fprintf(stderr, "   **************************************************\n");
      exit(EXIT_FAILURE);
   }

   return;
}
