/* ppmgrad.c - create a pixmap of a specified size and gradient.  Stolen from
               ppmmake.c.
**
** Copyright (C) 1991 by Jef Poskanzer.
** Copyright (C) 1994 by Gerald Combs.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation.  This software is provided "as is" without express or
** implied warranty.
*/

#include "ppm.h"
#include <math.h>

int
main( argc, argv )
    int argc;
    char* argv[];
    {
    pixel color, grads[10];
    pixel* pixrow;
    register pixel* pP;
    int argn, argb, dosin = 0, rows, cols, row, zone, zone_u, zone_l;
    int num_u, num_l, denom;
    register int col;
    char* usage = "width height color1 ... <color10>";
    float fmul;


    ppm_init( &argc, argv );

    if ( argc > 1 )
        if ( strcmp( argv[1], "-sin" ) == 0 )
            ++dosin;

    if ( ( argc < ( 4 + dosin ) ) || ( argc > ( 13 + dosin ) ) )
        pm_usage( usage );

    argb = dosin + 1;
    if ( sscanf( argv[argb], "%d", &cols ) != 1 )
	pm_usage( usage );
    ++argb;
    if ( sscanf( argv[argb], "%d", &rows ) != 1 )
	pm_usage( usage );
    ++argb;
    for ( argn = argb; argn < argc; ++argn )
        grads[argn - argb] = ppm_parsecolor( argv[argn], PPM_MAXMAXVAL );
    ++argb;
    argn -= argb;

    ppm_writeppminit( stdout, cols, rows, PPM_MAXMAXVAL, 0 );
    pixrow = ppm_allocrow( cols );

    if ( argn == 0 )
        {
        color.r = grads[0].r;
        color.g = grads[0].g;
        color.b = grads[0].b;
        for ( row = 0; row < rows; ++row )
	    {
            for ( col = 0, pP = pixrow; col < cols; ++col, ++pP )
	        *pP = color;
    	    ppm_writeppmrow( stdout, pixrow, cols, PPM_MAXMAXVAL, 0 );
	    }
        }
    else
        {
        --rows;
        for ( zone = 1; zone <= argn; ++zone )
            {
            zone_l = ( (zone - 1) * rows ) / argn;
            zone_u = ( zone * rows ) / argn;
            denom = zone_u - zone_l;
            for ( row = zone_l; row < zone_u; ++row )
                {
                if ( dosin == 0 )
                    {
                    num_u = zone_u - row;
                    num_l = row - zone_l;
                    }
                else
                    {
                    fmul = (cos ( (float) (row - zone_l) * 3.1415 /
                           (float) (zone_u - zone_l) ) + 1.0 ) / 2.0;
                    num_u = (int) ( ( fmul * (float) denom ) + 0.5 );
                    num_l = (int) ( ( ( 1 - fmul ) * (float) denom ) + 0.5 );
                    }
                color.r = ( grads[zone - 1].r * num_u + grads[zone].r *
                            num_l ) / denom;
                color.g = ( grads[zone - 1].g * num_u + grads[zone].g *
                            num_l ) / denom;
                color.b = ( grads[zone - 1].b * num_u + grads[zone].b *
                            num_l ) / denom;
                for (col = 0, pP = pixrow; col < cols; ++col, ++pP )
                    *pP = color;
                ppm_writeppmrow( stdout, pixrow, cols, PPM_MAXMAXVAL, 0 );
                }
            }
        color.r = grads[argn].r;
        color.g = grads[argn].g;
        color.b = grads[argn].b;
        for (col = 0, pP = pixrow; col < cols; ++col, ++pP )
            *pP = color;
        ppm_writeppmrow( stdout, pixrow, cols, PPM_MAXMAXVAL, 0 );
        }

    pm_close( stdout );
    exit( 0 );
    }
