/*
 * Twin - A Tiny Window System
 * Copyright © 2004 Keith Packard <keithp@keithp.com>
 * All rights reserved.
 *
 * This Library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This Library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with the Gnome Library; see the file COPYING.LIB.  If not,
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "twinint.h"
	    
/*
 * Find the point in path which is furthest left of the line
 */
static int
_twin_path_leftpoint (twin_path_t   *path,
		      twin_spoint_t *p1,
		      twin_spoint_t *p2)
{
    twin_spoint_t   *points = path->points;
    int		    p;
    int		    best = 0;
    /*
     * Normal form of the line is Ax + By + C = 0,
     * these are the A and B factors.  As we're just comparing
     * across x and y, the value of C isn't relevant
     */
    twin_dfixed_t   Ap = p2->y - p1->y;
    twin_dfixed_t   Bp = p1->x - p2->x;
    
    twin_dfixed_t   max = -0x7fffffff;
    
    for (p = 0; p < path->npoints; p++)
    {
	twin_dfixed_t	vp = Ap * points[p].x + Bp * points[p].y;

	if (vp > max)
	{
	    max = vp;
	    best = p;
	}
    }
    return best;
}

static int
_around_order (twin_spoint_t    *a1,
	       twin_spoint_t    *a2,
	       twin_spoint_t    *b1,
	       twin_spoint_t    *b2)
{
    twin_dfixed_t   adx = (a2->x - a1->x);
    twin_dfixed_t   ady = (a2->y - a1->y);
    twin_dfixed_t   bdx = (b2->x - b1->x);
    twin_dfixed_t   bdy = (b2->y - b1->y);
    twin_dfixed_t   diff = (ady * bdx - bdy * adx);

    if (diff < 0) return -1;
    if (diff > 0) return 1;
    return 0;
}

#define F(x)	twin_sfixed_to_double(x)
#if 0
#include <stdio.h>
#include <math.h>
#define DBGOUT(x...)	printf(x)

static double
_angle (twin_spoint_t *a, twin_spoint_t *b)
{
    twin_sfixed_t    dx = b->x - a->x;
    twin_sfixed_t    dy = b->y - a->y;
    double	    rad;

    rad = atan2 ((double) dy, (double) dx);
    return rad * 180 / M_PI;
}
#else
#define DBGOUT(x...)
#endif

#define A(a)  ((a) < 0 ? -(a) : (a))

/*
 * Convolve one subpath with a convex pen.  The result is
 * a closed path.
 */
static void
_twin_subpath_convolve (twin_path_t	*path,
			twin_path_t	*stroke,
			twin_path_t	*pen)
{
    twin_spoint_t   *sp   = stroke->points;
    twin_spoint_t   *pp   = pen->points;
    int		    ns    = stroke->npoints;
    int		    np    = pen->npoints;
    twin_spoint_t   *sp0  = &sp[0];
    twin_spoint_t   *sp1  = &sp[1];
    int		    start = _twin_path_leftpoint (pen, sp0, sp1);
    twin_spoint_t   *spn1 = &sp[ns-1];
    twin_spoint_t   *spn2 = &sp[ns-2];
    int		    ret   = _twin_path_leftpoint (pen, spn1, spn2);
    int		    p;
    int		    s;
    int		    starget;
    int		    ptarget;
    int		    inc;
    int		    first;

    DBGOUT ("convolve stroke:\n");
    for (s = 0; s < ns; s++)
	DBGOUT ("\ts%02d: %9.4f, %9.4f\n", s, F(sp[s].x), F(sp[s].y));
    DBGOUT ("convolve pen:\n");
    for (p = 0; p < np; p++)
	DBGOUT ("\tp%02d: %9.4f, %9.4f\n", p, F(pp[p].x), F(pp[p].y));
    
    s = 0;
    p = start;
    DBGOUT ("start:  ");
    DBGOUT ("s%02d (%9.4f, %9.4f), p%02d (%9.4f, %9.4f): %9.4f, %9.4f\n",
	    s, F(sp[s].x), F(sp[s].y),
	    p, F(pp[p].x), F(pp[p].y),
	    F(sp[s].x + pp[p].x), F(sp[s].y + pp[p].y));
    _twin_path_smove (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
    first = path->npoints - 1;
    
    /* step along the path first */
    inc = 1;
    starget = ns-1;
    ptarget = ret;
    for (;;)
    {
	/*
	 * Convolve the edges
	 */
	do
	{
	    int	sn = s + inc;
	    int	pn = (p == np - 1) ? 0 : p + 1;
	    int	pm = (p == 0) ? np - 1 : p - 1;
    
	    /*
	     * step along pen (forwards or backwards) or stroke as appropriate
	     */
	     
	    DBGOUT ("\tangles: stroke %9.4f +pen %9.4f -pen %9.4f\n",
		    _angle (&sp[s], &sp[sn]),
		    _angle (&pp[p], &pp[pn]),
		    _angle (&pp[pm], &pp[p]));
	    if (_around_order (&sp[s],&sp[sn],&pp[p],&pp[pn]) > 0)
	    {
		DBGOUT ("+pen:   ");
		p = pn;
	    }
	    else if (_around_order (&sp[s],&sp[sn],&pp[pm],&pp[p]) < 0)
	    {
		DBGOUT ("-pen:   ");
		p = pm;
	    }
	    else
	    {
		DBGOUT ("stroke: ");
		s = sn;
	    }
	    DBGOUT ("s%02d (%9.4f, %9.4f), p%02d (%9.4f, %9.4f): %9.4f, %9.4f\n",
		    s, F(sp[s].x), F(sp[s].y),
		    p, F(pp[p].x), F(pp[p].y),
		    F(sp[s].x + pp[p].x), F(sp[s].y + pp[p].y));
	    _twin_path_sdraw (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
	} while (s != starget);
	
	/*
	 * Finish this edge
	 */
	
	/* draw a cap */
	switch (path->state.cap_style) {
	    int		pm;
	case TwinCapProjecting:
	    /*
	     * This draws a rough projecting cap using the
	     * pen.
	     *
	     * First, project the line forward one pen radius
	     * by finding the pen location halfway between the
	     * two normals.
	     *
	     * Then, just add that to the normals themselves to
	     * find the corners of the projecting cap.  
	     * 
	     * The result may have significant error, so overwrite
	     * the existing corners with the new coordinates to
	     * avoid a kink.
	     */
	    if (p <= ptarget)
		pm = (ptarget + p) >> 1;
	    else
	    {
		pm = (ptarget + np + p) >> 1;
		if (pm >= np) pm -= np;
	    }
	    
	    /* replace last point with corner of cap */
	    path->npoints--;
	    _twin_path_sdraw (path,
			      sp[s].x + pp[pm].x + pp[p].x,
			      sp[s].y + pp[pm].y + pp[p].y);
	    p = ptarget;
	    if (inc == 1)
	    {
		/* start next line at cap corner */
		_twin_path_sdraw (path,
				  sp[s].x + pp[pm].x + pp[p].x,
				  sp[s].y + pp[pm].y + pp[p].y);
	    }
	    else
	    {
		/* overwrite initial point */
		path->points[first].x = sp[s].x + pp[pm].x + pp[p].x;
		path->points[first].y = sp[s].y + pp[pm].y + pp[p].y;
	    }
	    break;
	case TwinCapButt:
	    p = ptarget-1;
	    /* fall through … */
	case TwinCapRound:
	    while (p != ptarget)
	    {
		if (++p == np) p = 0;
		DBGOUT("cap:    ");
		DBGOUT ("s%02d (%9.4f, %9.4f), p%02d (%9.4f, %9.4f): %9.4f, %9.4f\n",
			s, F(sp[s].x), F(sp[s].y),
			p, F(pp[p].x), F(pp[p].y),
			F(sp[s].x + pp[p].x), F(sp[s].y + pp[p].y));
		_twin_path_sdraw (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
	    }
	    break;
	}
	
	if (inc == -1)
	    break;
	
	/* reach the end of the path?  Go back the other way now */
	inc = -1;
	ptarget = start;
	starget = 0;
    }
    twin_path_close (path);
}

void
twin_path_convolve (twin_path_t	*path,
		    twin_path_t	*stroke,
		    twin_path_t	*pen)
{
    int		p;
    int		s;
    twin_path_t	*hull = twin_path_convex_hull (pen);

    p = 0;
    for (s = 0; s <= stroke->nsublen; s++)
    {
	int sublen;
	int npoints;

	if (s == stroke->nsublen)
	    sublen = stroke->npoints;
	else
	    sublen = stroke->sublen[s];
	npoints = sublen - p;
	if (npoints > 1)
	{
	    twin_path_t	subpath;

	    subpath.points = stroke->points + p;
	    subpath.npoints = npoints;
	    subpath.sublen = 0;
	    subpath.nsublen = 0;
	    _twin_subpath_convolve (path, &subpath, hull);
	    p = sublen;
	}
    }
    twin_path_destroy (hull);
}
