/*
 * Copyright © 2000 SuSE, Inc.
 * Copyright © 2007 Red Hat, Inc.
 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
 *             2005 Lars Knoll & Zack Rusin, Trolltech
 *
 * 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.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <math.h>
#include "pixman-private.h"

static force_inline double
coordinates_to_parameter (double x, double y, double angle)
{
    double t;

    t = atan2 (y, x) + angle;

    while (t < 0)
	t += 2 * M_PI;

    while (t >= 2 * M_PI)
	t -= 2 * M_PI;

    return 1 - t * (1 / (2 * M_PI)); /* Scale t to [0, 1] and
				      * make rotation CCW
				      */
}

static uint32_t *
conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
{
    pixman_image_t *image = iter->image;
    int x = iter->x;
    int y = iter->y;
    int width = iter->width;
    uint32_t *buffer = iter->buffer;

    gradient_t *gradient = (gradient_t *)image;
    conical_gradient_t *conical = (conical_gradient_t *)image;
    uint32_t       *end = buffer + width;
    pixman_gradient_walker_t walker;
    pixman_bool_t affine = TRUE;
    double cx = 1.;
    double cy = 0.;
    double cz = 0.;
    double rx = x + 0.5;
    double ry = y + 0.5;
    double rz = 1.;

    _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);

    if (image->common.transform)
    {
	pixman_vector_t v;

	/* reference point is the center of the pixel */
	v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
	v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
	v.vector[2] = pixman_fixed_1;

	if (!pixman_transform_point_3d (image->common.transform, &v))
	    return iter->buffer;

	cx = image->common.transform->matrix[0][0] / 65536.;
	cy = image->common.transform->matrix[1][0] / 65536.;
	cz = image->common.transform->matrix[2][0] / 65536.;

	rx = v.vector[0] / 65536.;
	ry = v.vector[1] / 65536.;
	rz = v.vector[2] / 65536.;

	affine =
	    image->common.transform->matrix[2][0] == 0 &&
	    v.vector[2] == pixman_fixed_1;
    }

    if (affine)
    {
	rx -= conical->center.x / 65536.;
	ry -= conical->center.y / 65536.;

	while (buffer < end)
	{
	    if (!mask || *mask++)
	    {
		double t = coordinates_to_parameter (rx, ry, conical->angle);

		*buffer = _pixman_gradient_walker_pixel (
		    &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
	    }

	    ++buffer;

	    rx += cx;
	    ry += cy;
	}
    }
    else
    {
	while (buffer < end)
	{
	    double x, y;

	    if (!mask || *mask++)
	    {
		double t;

		if (rz != 0)
		{
		    x = rx / rz;
		    y = ry / rz;
		}
		else
		{
		    x = y = 0.;
		}

		x -= conical->center.x / 65536.;
		y -= conical->center.y / 65536.;

		t = coordinates_to_parameter (x, y, conical->angle);

		*buffer = _pixman_gradient_walker_pixel (
		    &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
	    }

	    ++buffer;

	    rx += cx;
	    ry += cy;
	    rz += cz;
	}
    }

    iter->y++;
    return iter->buffer;
}

static uint32_t *
conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
{
    uint32_t *buffer = conical_get_scanline_narrow (iter, NULL);

    pixman_expand_to_float (
	(argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);

    return buffer;
}

void
_pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
{
    if (iter->iter_flags & ITER_NARROW)
	iter->get_scanline = conical_get_scanline_narrow;
    else
	iter->get_scanline = conical_get_scanline_wide;
}

PIXMAN_EXPORT pixman_image_t *
pixman_image_create_conical_gradient (const pixman_point_fixed_t *  center,
                                      pixman_fixed_t                angle,
                                      const pixman_gradient_stop_t *stops,
                                      int                           n_stops)
{
    pixman_image_t *image = _pixman_image_allocate ();
    conical_gradient_t *conical;

    if (!image)
	return NULL;

    conical = &image->conical;

    if (!_pixman_init_gradient (&conical->common, stops, n_stops))
    {
	free (image);
	return NULL;
    }

    angle = MOD (angle, pixman_int_to_fixed (360));

    image->type = CONICAL;

    conical->center = *center;
    conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI;

    return image;
}

