/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
/*
 * 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 "pixman-private.h"

static source_image_class_t
linear_gradient_classify (pixman_image_t *image,
                          int             x,
                          int             y,
                          int             width,
                          int             height)
{
    source_image_t *source = (source_image_t *)image;
    linear_gradient_t *linear = (linear_gradient_t *)image;
    pixman_vector_t v;
    pixman_fixed_32_32_t l;
    pixman_fixed_48_16_t dx, dy;
    double inc;
    source_image_class_t class;

    class = SOURCE_IMAGE_CLASS_UNKNOWN;

    if (source->common.transform)
    {
	/* projective transformation */
	if (source->common.transform->matrix[2][0] != 0 ||
	    source->common.transform->matrix[2][1] != 0 ||
	    source->common.transform->matrix[2][2] == 0)
	{
	    return class;
	}

	v.vector[0] = source->common.transform->matrix[0][1];
	v.vector[1] = source->common.transform->matrix[1][1];
	v.vector[2] = source->common.transform->matrix[2][2];
    }
    else
    {
	v.vector[0] = 0;
	v.vector[1] = pixman_fixed_1;
	v.vector[2] = pixman_fixed_1;
    }

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

    l = dx * dx + dy * dy;

    if (l == 0)
	return class;	

    /*
     * compute how much the input of the gradient walked changes
     * when moving vertically through the whole image
     */
    inc = height * (double) pixman_fixed_1 * pixman_fixed_1 *
	(dx * v.vector[0] + dy * v.vector[1]) /
	(v.vector[2] * (double) l);

    /* check that casting to integer would result in 0 */
    if (-1 < inc && inc < 1)
	class = SOURCE_IMAGE_CLASS_HORIZONTAL;

    return class;
}

static void
linear_gradient_get_scanline_32 (pixman_image_t *image,
                                 int             x,
                                 int             y,
                                 int             width,
                                 uint32_t *      buffer,
                                 const uint32_t *mask)
{
    pixman_vector_t v, unit;
    pixman_fixed_32_32_t l;
    pixman_fixed_48_16_t dx, dy;
    gradient_t *gradient = (gradient_t *)image;
    source_image_t *source = (source_image_t *)image;
    linear_gradient_t *linear = (linear_gradient_t *)image;
    uint32_t *end = buffer + width;
    pixman_gradient_walker_t walker;

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

    /* 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 (source->common.transform)
    {
	if (!pixman_transform_point_3d (source->common.transform, &v))
	    return;
	
	unit.vector[0] = source->common.transform->matrix[0][0];
	unit.vector[1] = source->common.transform->matrix[1][0];
	unit.vector[2] = source->common.transform->matrix[2][0];
    }
    else
    {
	unit.vector[0] = pixman_fixed_1;
	unit.vector[1] = 0;
	unit.vector[2] = 0;
    }

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

    l = dx * dx + dy * dy;

    if (l == 0 || unit.vector[2] == 0)
    {
	/* affine transformation only */
        pixman_fixed_32_32_t t, next_inc;
	double inc;

	if (l == 0 || v.vector[2] == 0)
	{
	    t = 0;
	    inc = 0;
	}
	else
	{
	    double invden, v2;

	    invden = pixman_fixed_1 * (double) pixman_fixed_1 /
		(l * (double) v.vector[2]);
	    v2 = v.vector[2] * (1. / pixman_fixed_1);
	    t = ((dx * v.vector[0] + dy * v.vector[1]) - 
		 (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
	    inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden;
	}
	next_inc = 0;

	if (((pixman_fixed_32_32_t )(inc * width)) == 0)
	{
	    register uint32_t color;

	    color = _pixman_gradient_walker_pixel (&walker, t);
	    while (buffer < end)
		*buffer++ = color;
	}
	else
	{
	    int i;

	    i = 0;
	    while (buffer < end)
	    {
		if (!mask || *mask++)
		{
		    *buffer = _pixman_gradient_walker_pixel (&walker,
							     t + next_inc);
		}
		i++;
		next_inc = inc * i;
		buffer++;
	    }
	}
    }
    else
    {
	/* projective transformation */
        double t;

	t = 0;

	while (buffer < end)
	{
	    if (!mask || *mask++)
	    {
	        if (v.vector[2] != 0)
		{
		    double invden, v2;

		    invden = pixman_fixed_1 * (double) pixman_fixed_1 /
			(l * (double) v.vector[2]);
		    v2 = v.vector[2] * (1. / pixman_fixed_1);
		    t = ((dx * v.vector[0] + dy * v.vector[1]) - 
			 (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
		}

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

	    ++buffer;

	    v.vector[0] += unit.vector[0];
	    v.vector[1] += unit.vector[1];
	    v.vector[2] += unit.vector[2];
	}
    }
}

static void
linear_gradient_property_changed (pixman_image_t *image)
{
    image->common.get_scanline_32 = linear_gradient_get_scanline_32;
    image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
}

PIXMAN_EXPORT pixman_image_t *
pixman_image_create_linear_gradient (pixman_point_fixed_t *        p1,
                                     pixman_point_fixed_t *        p2,
                                     const pixman_gradient_stop_t *stops,
                                     int                           n_stops)
{
    pixman_image_t *image;
    linear_gradient_t *linear;

    image = _pixman_image_allocate ();

    if (!image)
	return NULL;

    linear = &image->linear;

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

    linear->p1 = *p1;
    linear->p2 = *p2;

    image->type = LINEAR;
    image->common.classify = linear_gradient_classify;
    image->common.property_changed = linear_gradient_property_changed;

    return image;
}

