/*
************************************************************
* MODULE: r.le.setup/mv_wind.c                             *
*         Version 5.0beta            Oct. 1, 2001          *
*				                           *
* AUTHOR: W.L. Baker, University of Wyoming                *
*         BAKERWL@UWYO.EDU                                 *
*                                                          *
* PURPOSE: To set up sampling areas, which can can then    *
*         be used to obtain data using the r.le.dist,      *
*         r.le.patch, and r.le.pixel programs.  The        *
*         mv_wind.c code queries the user for information  *
*         needed to setup the moving window                *
*				                           *
* 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 <grass/raster.h>
#include <grass/display.h>
#include "setup.h"
#include <grass/config.h>



				/* SETUP THE PARAMETERS FOR THE 
				   MOVING WINDOW */

void mov_wind (int t, int b, int l, int r, char *n1, char *n2, char *n3, double *mx)

{

  int    xp=0, yp=0, x1, y1, btn=0, s, l0, t0, xpl, ypt,
         u_w=0, u_l=0, u_w0, u_l0, w_w=0, w_l=0, initl=0,
         initt=0, d, fmask, j, circle=0;
  register int i;
  double tmp[2], tmp1, radius=0.0;
  FILE   *fp;

/*
	mx[0]	=	cols of region/width of screen
	mx[1]	=	rows of region/height of screen
	t	=	top row of sampling frame
	b	=	bottom row of sampling frame
	l	=	left col of sampling frame
	r	=	right col of sampling frame
*/

				/* open the moving window parameter file */

  fp = fopen0("r.le.para/move_wind", "w");  
  G_sleep_on_error(0);

  initl = l;
  initt = t;

  l = (int)((double)(l * mx[0]) + 0.5);
  r = (int)((double)(r * mx[0]) + 0.5);
  t = (int)((double)(t * mx[1]) + 0.5);
  b = (int)((double)(b * mx[1]) + 0.5);

				/* display sampling frame */

  R_open_driver();  
  R_standard_color(D_translate_color("grey"));
  draw_box((int)(l/mx[0] + 0.5), (int)(t/mx[1] + 0.5), (int)(r/mx[0] + 0.5),
     (int)(b/mx[1] + 0.5), 1);
  R_close_driver();

				/* determine whether the user will use
				   the keyboard or mouse to setup the 
				   moving window */

keyboard:
  fprintf(stderr, "\n\n    HOW WILL YOU SPECIFY THE MOVING WINDOW?\n");
  fprintf(stderr, "\n       Use keyboard to enter moving window dimensions   1");
  fprintf(stderr, "\n       Use mouse to draw moving window                  2\n");
  fprintf(stderr, "\n                                            Which Number?  ");

  numtrap(1, &tmp1);
  d = (int)(tmp1);
  if (d < 1 || d > 2) {
     fprintf(stderr, "     You did not enter a 1 or 2, try again\n");

     goto keyboard;
  }

  if (d == 1 || d == 2) {
                                /* return a value > 0 to fmask if there is
				   a MASK present */

     fprintf(stderr, "\n    If a MASK is not present (see r.mask) a beep may sound\n");
     fprintf(stderr, "    and a WARNING may be printed that can be ignored.\n");
     fprintf(stderr, "    If a MASK is present there will be no warning.\n");

     fmask = G_open_cell_old("MASK",G_mapset());
     fprintf(stderr, "\n");


				/* setup the moving window using keyboard */

     if (d == 1) {
				/* if sampling using circles */

        fprintf(stderr, "\n    Do you want to sample using rectangles");

        if (!G_yes("\n       (including squares) (y) or circles (n)?   ",1)) {
           fprintf(stderr, "\n    What radius do you want for the circles?  Radius");
           fprintf(stderr, "\n       is in pixels; add 0.5 pixels, for the center");
           fprintf(stderr, "\n       pixel, to the number of pixels outside the");
           fprintf(stderr, "\n       center pixel.  Type a real number with one");
           fprintf(stderr, "\n       decimal place ending in .5 (e.g., 4.5):        ");

           numtrap(1, &radius);
           u_w = (int)(2 * radius);
           u_l = (int)(2 * radius);
           u_w0 = u_w/mx[0];
           u_l0 = u_l/mx[1];
        }

				/* if sampling using rectangles/squares */

        else {
back:
           fprintf(stderr, "\n    Enter number of COLUMNS & ROWS for the dimensions of");
           fprintf(stderr, "\n       the moving window (e.g., 10 10):  ");

           numtrap(2, tmp);
           u_w = fabs(tmp[0]);
           u_l = fabs(tmp[1]);
           u_w0 = fabs(tmp[0])/mx[0];
           u_l0 = fabs(tmp[1])/mx[1];

				/* trap possible errors in dimensions */

           if (!u_w0 || !u_l0) {
              fprintf(stderr, "\n    You entered a dimension as 0; enter dimensions again\n");

              goto back;
           }
           else if (u_w == 1 && u_l == 1) {
              fprintf(stderr, "\n    You entered dimensions as 1 1; This will not produce");
              fprintf(stderr, "\n       meaningful results; enter larger dimensions\n");

              goto back;
           }
           else if (u_w >= r || u_l >= b) {
              fprintf(stderr, "\n    Window size you chose allows < 2 windows across each row;");
              fprintf(stderr, "\n       please make window dimensions smaller\n");

              goto back;
           }
        }

				/* display the user-defined moving
				   window on the map */

        R_open_driver();
        R_standard_color(D_translate_color("red"));
        if (radius) {
	   draw_circle(initl, initt, initl+u_w0, initt+u_l0, 3);
        }
        else {
           draw_box(initl, initt, initl+u_w0, initt+u_l0, 1);
        }
        R_close_driver();

				/* if all is OK, then set window dimensions */

        fprintf(stderr, "\n    Is the displayed moving window as you wanted it (y) or");

        if (G_yes("\n       do you want to redo it? (n)     ", 1)) {
           xp = (int)(u_w0);
           yp = (int)(u_l0);
        }
        else {
           paint_map(n1, n2, n3);
	   R_open_driver();
           R_standard_color(D_translate_color("grey"));
           draw_box((int)(l/mx[0] + 0.5), (int)(t/mx[1] + 0.5), (int)(r/mx[0] + 0.5),
              (int)(b/mx[1] + 0.5), 1);
           R_close_driver();
	   radius = 0.0;
	   goto keyboard;
        }
     }

				/* setup the moving window using the mouse */

     else if (d == 2) {
        G_system("clear");

				/* if sampling using circles */

        fprintf(stderr, "\n\n    Do you want to use a rectangular (including squares) (y)");

        if (!G_yes("\n       or circular (n) moving window?   ",1)) {
           circle = 1;
           fprintf(stderr, "\n    Draw a rectangular area to contain a circular moving window.");
           fprintf(stderr, "\n    First select upper left corner, then lower right:\n");
           fprintf(stderr, "       Left button:     Check unit size\n");
           fprintf(stderr, "       Middle button:   Upper left corner of area here\n");
           fprintf(stderr, "       Right button:    Lower right corner of area here\n");

        }
        else {
           circle = 0;
           fprintf(stderr, "\n    Draw a rectangular (or square) moving window");
           fprintf(stderr, "\n    First select upper left corner, then lower right:\n");
           fprintf(stderr, "       Left button:     Check moving window size\n");
           fprintf(stderr, "       Middle button:   Upper left corner of window here\n");
           fprintf(stderr, "       Right: button:   Lower right corner of window here\n");

        }
        R_open_driver();
        while(btn != 3){
back1:
           R_get_location_with_box(l, t, &xp, &yp, &btn);
           u_w = (int)((double)(xp-l)*mx[0] + 0.5);
           u_l = (int)((double)(yp-t)*mx[1] + 0.5);

           if(btn == 1) {  	/** show the size and ratio **/
              fprintf(stderr, "    Window would be %d columns wide by %d rows long\n",
                          u_w, u_l);
              fprintf(stderr, "    Width/length would be %5.2f and area %d pixels\n",
                          (float)u_w/u_l, u_w*u_l);

              for(i = 0; i < 120; i++)
                 fprintf(stderr,"\b");

           }

           else if(btn == 2){
              R_move_abs(xp, yp);
	      l0 = l;
	      t0 = t;
              l = xp;
              t = yp;
           }

           else if( btn == 3) {
              xpl = (int)((double)((int)((double)(xp-l)*mx[0] + 0.5))/mx[0]);
              ypt = (int)((double)((int)((double)(yp-t)*mx[1] + 0.5))/mx[1]);
	      if (xpl < 0 || ypt < 0) {
	         fprintf(stderr, "\n    You did not put lower right corner below and to the");
                 fprintf(stderr, "\n       of upper left corner. Please select lower right");
                 fprintf(stderr, "\n       corner again");

                 goto back1;
              }
              else if (xpl == 0 || ypt == 0) {
	         fprintf(stderr, "\n\n    Window would have 0 rows and/or 0 columns;");
                 fprintf(stderr, "       try again\n");

	         goto back1;
              }
              else if (xpl > 0 && ypt > 0) {
                 R_standard_color(D_translate_color("red"));
                 if (circle) {
                    if (xpl > ypt) xpl = ypt;
                    else if (ypt > xpl) ypt = xpl;
                    u_w = (int)((double)xpl*mx[0] + 0.5);
                    u_l = (int)((double)ypt*mx[1] + 0.5);
                    draw_circle(initl, initt, initl+xpl, initt+ypt, 3);
                 }
                 else
                    draw_box(initl, initt, initl+xpl, initt+ypt, 1);

	         G_system("clear");
                 if (circle) {
		    radius = (float)u_w/2.0;
	            fprintf(stderr, "\n\n    Circular moving window has radius = %5.2f pixels\n",
	               radius);

                 }
                 else {
	            fprintf(stderr, "\n    Rectangular moving window has %d columns and %d rows",
                       u_w, u_l);
                    fprintf(stderr, "\n    with width/length ratio of %5.2f and area of %d pixels\n",
                       (float)u_w/u_l, u_w*u_l);

                 }
              }
           }
        }
        R_close_driver();
        l = l0;
        t = t0;
     }

     G_close_cell(fmask);
  }

				/* if neither, then exit */

  else
     exit(0);
				/* write the moving window parameters
				   into the r.le.para/move_wind file */

  fprintf(fp, "%8d%8d  u_w u_l: CELL\n", u_w, u_l);


  w_w = r-l;
  w_l = b-t;

				/* write the radius of circles, if a
				   circular moving window is to be used */

  fprintf(fp, "%8.1f          radius of circular moving window\n",radius);


 				/* write the search area in the
				   r.le.para/move_wind file */

  fprintf(fp, "%8d%8d  w_w w_l\n",w_w,w_l);
  fprintf(fp, "%8d%8d  x0, y0\n", (int)((double)(initl)*mx[0] + 0.5),
     (int)((double)(initt)*mx[1] + 0.5));


  fclose(fp);
  return;
}

