#include <stdio.h>
#include <math.h>
#include <grass/Vect.h>
#include "sw_defs.h"
#include "defs.h"
#include "write.h"

/*-extend_line()  finds coordinates along the boundary of a window
 *                  that also lie on a specified line (ax+by=c). The
 *                  line can cross at least two boundaries---the line
 *                  that intersects the midpoint of s1 and s2 determines 
 *                  which coordinates are placed in (c_x, c_y).
 *
 * The limits of the window are described by:
 *    e:  east
 *    w:  west
 *    s:  south
 *    n:  north
 * Note that the following constraints must be true:
 *    ( w < e )     ( s < n )
 *
 *    x and y are points on the line ax + by = c that are assumed
 *    to lie within the window.
 *
 *    the c_x and c_y values are changed.
 *
 *    returns: 0 on error, 1 otherwise
 */

int extend_line (double s, double n, double w, double e,
  double a, double b, double c, double x, double y,
  double *c_x, double *c_y, int knownPointAtLeft)
{
  double nx, ny; /* intesection coordinates */

  if (x > w && x < e && y > s && y < n)
  {
    /* vertical line? */
    if(a == 0)
    {
        *c_y = c / b;
        *c_x = knownPointAtLeft ? s : n;
    }

    /* horizontal line? */
    if(b == 0)
    {
        *c_x = c / a;
        *c_y = knownPointAtLeft ? e : w;
    }

    /* south */
    nx = (c - b * s) / a;
    if(Vect_point_in_box(nx,s,0.0,&Box) &&
       ((nx >  x && knownPointAtLeft) || (nx <= x && !knownPointAtLeft)))
    {
        *c_x = nx;
        *c_y = s;
        return 1;
    }

    /* north */
    nx = (c - b * n) / a;
    if( Vect_point_in_box(nx,n,0.0,&Box) &&
       ((nx >  x && knownPointAtLeft) || (nx <= x && !knownPointAtLeft)))
    {
        *c_x = nx;
        *c_y = n;
        return 1;
    }

    if(knownPointAtLeft) {
        /* east */
        ny = (c - a * e) / b;
        if(Vect_point_in_box(e,ny,0.0,&Box))
        {
            *c_x = e;
            *c_y = ny;
            return 1;
        }
    } else {
        /* west */
        ny = (c - a * w) / b;
        if(Vect_point_in_box(w,ny,0.0,&Box))
        {
            *c_x = w;
            *c_y = ny;
            return 1;
        }
    }
  }
  return 0;
}
