/*
 * $Id$
 *
 * Copyright © 2004 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Keith Packard not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Keith Packard makes no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "twin-fedit.h"

double
min (double a, double b)
{
    return a < b ? a : b;
}

double
max (double a, double b)
{
    return a > b ? a : b;
}

double
abs (double a)
{
    return a < 0 ? -a : a;
}

pts_t *
new_pts (void)
{
    pts_t   *pts = malloc (sizeof (pts_t));

    pts->n = 0;
    pts->s = 0;
    pts->pt = 0;

    return pts;
}

void
dispose_pts (pts_t *pts)
{
    if (pts->pt)
	free (pts->pt);
    free (pts);
}

void
add_pt (pts_t *pts, pt_t *pt)
{
    if (pts->n == pts->s)
    {
	int	ns = pts->s ? pts->s * 2 : 16;

	if (pts->pt)
	    pts->pt = realloc (pts->pt, ns * sizeof (pt_t));
	else
	    pts->pt = malloc (ns * sizeof (pt_t));
	pts->s = ns;
    }
    pts->pt[pts->n++] = *pt;
}

double
distance_to_point (pt_t * a, pt_t * b)
{
    double dx = (b->x - a->x);
    double dy = (b->y - a->y);

    return sqrt (dx*dx + dy*dy);
}

double
distance_to_line (pt_t * p, pt_t * p1, pt_t * p2)
{
    /*
     * Convert to normal form (AX + BY + C = 0)
     *
     * (X - x1) * (y2 - y1) = (Y - y1) * (x2 - x1)
     *
     * X * (y2 - y1) - Y * (x2 - x1) - x1 * (y2 - y1) + y1 * (x2 - x1) = 0
     *
     * A = (y2 - y1)
     * B = (x1 - x2)
     * C = (y1x2 - x1y2)
     *
     * distance² = (AX + BC + C)² / (A² + B²)
     */
    double   A = p2->y - p1->y;
    double   B = p1->x - p2->x;
    double   C = (p1->y * p2->x - p1->x * p2->y);
    double   den, num;

    num = A * p->x + B * p->y + C;
    den = A * A + B * B;
    if (den == 0)
	return distance_to_point (p, p1);
    else
	return sqrt ((num * num) / den);
}

double
distance_to_segment (pt_t * p, pt_t * p1, pt_t * p2)
{
    double dx, dy;
    double pdx, pdy;
    pt_t px;

    /* intersection pt_t * (px):
     
            px = p1 + u(p2 - p1)
            (p - px) . (p2 - p1) = 0
     
            Thus:
     
            u = ((p - p1) . (p2 - p1)) / (||(p2 - p1)|| ^ 2);
         */

    dx = p2->x - p1->x;
    dy = p2->y - p1->y;

    if (dx == 0 && dy == 0)
        return distance_to_point (p, p1);

    pdx = p->x - p1->x;
    pdy = p->y - p1->y;

    double u = (pdx * dx + pdy * dy) / (dx*dx + dy*dy);

    if (u <= 0)
        return distance_to_point (p, p1);
    else if (u >= 1)
        return distance_to_point (p, p2);

    px.x = p1->x + u * (p2->x - p1->x);
    px.y = p1->y + u * (p2->y - p1->y);

    return distance_to_point (p, &px);
}

double
distance_to_segments (pt_t * p, pts_t *s)
{
    double  m = distance_to_segment (p, &s->pt[0], &s->pt[1]);
    int	    i;
    for (i = 1; i < s->n - 1; i++)
    {
	double d = distance_to_segment (p, &s->pt[i], &s->pt[i+1]);
	m = min (d, m);
    }
    return m;
}

pt_t
lerp (pt_t *a, pt_t *b)
{
    pt_t    p;

    p.x = a->x + (b->x - a->x) / 2;
    p.y = a->y + (b->y - a->y) / 2;
    return p;
}
	
void
dcj (spline_t *s, spline_t *s1, spline_t *s2)
{
    pt_t 	ab = lerp (&s->a, &s->b);
    pt_t 	bc = lerp (&s->b, &s->c);
    pt_t 	cd = lerp (&s->c, &s->d);
    pt_t 	abbc = lerp (&ab, &bc);
    pt_t 	bccd = lerp (&bc, &cd);
    pt_t 	final = lerp (&abbc, &bccd);

    s1->a = s->a;
    s1->b = ab;
    s1->c = abbc;
    s1->d = final;

    s2->a = final;
    s2->b = bccd;
    s2->c = cd;
    s2->d = s->d;
}


double spline_error (spline_t *s)
{
    double	berr, cerr;

    berr = distance_to_line (&s->b, &s->a, &s->d);
    cerr = distance_to_line (&s->c, &s->a, &s->d);
    return max (berr, cerr);
}

void decomp (pts_t *pts, spline_t *s, double tolerance)
{
    if (spline_error (s) <= tolerance)
    {
	add_pt (pts, &s->a);
    }
    else
    {
	spline_t  s1, s2;
	dcj (s, &s1, &s2);
	decomp (pts, &s1, tolerance);
	decomp (pts, &s2, tolerance);
    }
}

pts_t *decompose(spline_t *s, double tolerance)
{
    pts_t   *result = new_pts ();

    decomp (result, s, tolerance);
    add_pt (result, &s->d);
    return result;
}


double
spline_fit_error (pt_t *p, int n, spline_t *s, double tolerance)
{
    pts_t   *sp = decompose (s, tolerance);
    double  err = 0;
    int	    i;
    
    for (i = 0; i < n; i++)
    {
	double	e = distance_to_segments (&p[i], sp);
	err += e * e;
    }
    dispose_pts (sp);
    return err;
}

pt_t
lerp_a (pt_t *p1, pt_t *p2, double r)
{
    double  dx = p2->x - p1->x;
    double  dy = p2->y - p1->y;
    pt_t    pt;

    pt.x = p1->x + r * dx;
    pt.y = p1->y + r * dy;
    return pt;
}

double
lerp_dist (pt_t *p1, pt_t *p2, double r)
{
    double  dx = p2->x - p1->x;
    double  dy = p2->y - p1->y;

    dx *= r;
    dy *= r;
    return sqrt (dx * dx + dy * dy);
}

spline_t fit (pt_t *p, int n)
{
    spline_t	s;
    spline_t	best_s;

    double	dist;
    
    double	tol = 0.5;
    double	best_err = 10000;
    double	sbx_min;
    double	sbx_max;
    double	sby_min;
    double	sby_max;
    double	scx_min;
    double	scx_max;
    double	scy_min;
    double	scy_max;

    s.a = p[0];
    s.d = p[n - 1];
    
    dist = floor (distance_to_point (&s.a, &s.d) + 0.5);
    
    if (s.a.x < s.d.x)
    {
	sbx_min = s.a.x;
	sbx_max = s.d.x;

	scx_max = s.d.x;
	scx_min = s.a.x;
    }
    else
    {
	sbx_max = s.a.x;
	sbx_min = s.d.x;

	scx_min = s.d.x;
	scx_max = s.a.x;
    }

    if (s.a.y < s.d.y)
    {
	sby_min = s.a.y;
	sby_max = s.d.y;

	scy_max = s.d.y;
	scy_min = s.a.y;
    }
    else
    {
	sby_max = s.a.y;
	sby_min = s.d.y;

	scy_min = s.d.y;
	scy_max = s.a.y;
    }
    
    tol = 0.5;
    for (s.b.x = sbx_min; s.b.x <= sbx_max; s.b.x += 1.0)
	for (s.b.y = sby_min; s.b.y <= sby_max; s.b.y += 1.0)
	    for (s.c.x = scx_min; s.c.x <= scx_max; s.c.x += 1.0)
		for (s.c.y = scy_min; s.c.y <= scy_max; s.c.y += 1.0)
		{
		    double err = spline_fit_error (p, n, &s, tol);
    
		    if (err < best_err)
		    {
			best_err = err;
			best_s = s;
		    }
		}
    return best_s;
}
