/*
 *  rm_varargs.c --
 *    Implements the Renderman procedures with variable argument lists. 
 *    The procedures with va lists are implemented with the compagnion
 *    commands which are using arrays. 
 *
 *  Created by Karsten Lüth on 30.12.07.
 *  Copyright 2007 Karsten Lüth. All rights reserved.
 *
 *  Implementation notes:
 *    The maximum nunber of arguments is limited to 256. 
 */

#include "ri.h"
#include <stdarg.h>
#include "rm_error.h"

/* --------------------------------- */ 
/* Utilities for the argument lists. */ 
/* --------------------------------- */ 

/* The maximum number of arguments in a list */ 
#define MAX_ARGS 256

/* The number of arguments in a va list, the tokens and their values */ 
static RtInt     rm_argc;
static RtToken   rm_argv_toks[MAX_ARGS];
static RtPointer rm_argv_vals[MAX_ARGS];

/* rm_args --
 *   Scan the option list. If more than 'MAX_ARGS' are
 *   used than raise an error. 
 */ 
void rm_args(va_list argptr)
{
    rm_argc = 0;
    
    rm_argv_toks[rm_argc] = va_arg(argptr, RtToken);
    while (rm_argv_toks[rm_argc] != RI_NULL) {
        rm_argv_vals[rm_argc++] = va_arg(argptr, RtPointer);
        if (rm_argc>=MAX_ARGS) {
            rm_error(RIE_LIMIT, RIE_ERROR, "too many options in variable argument list"); 
            break; 
        }
    }
}

/* ----------------------------------------------- */ 
/* Renderman commands with variable argument lists */ 
/* ----------------------------------------------- */ 


RtVoid RiProjection(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    RiProjectionV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiImager(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    RiImagerV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiDisplay(RtToken name, RtToken type, RtToken mode, ...)
{
    va_list argptr;
    va_start(argptr, mode);
    rm_args(argptr);
    RiDisplayV(name, type, mode, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiHider(RtToken type, ...)
{
    va_list argptr;
    va_start(argptr, type);
    rm_args(argptr);
    RiHiderV(type, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiOption(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    RiOptionV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtLightHandle RiLightSource(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    return RiLightSourceV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtLightHandle RiAreaLightSource(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    return RiAreaLightSourceV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiSurface(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    RiSurfaceV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiAtmosphere(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    RiAtmosphereV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiInterior(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    RiInteriorV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiExterior(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    RiExteriorV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiDeformation(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    RiDeformationV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiDisplacement(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    RiDisplacementV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiAttribute(RtToken name, ...)
{
    va_list argptr;
    va_start(argptr, name);
    rm_args(argptr);
    RiAttributeV(name, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiPolygon(RtInt nverts, ...)
{
    va_list argptr;
    va_start(argptr, nverts);
    rm_args(argptr);
    RiPolygonV(nverts, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiGeneralPolygon(RtInt nloops, RtInt nverts[], ...)
{
    va_list argptr;
    va_start(argptr, nverts);
    rm_args(argptr);
    RiGeneralPolygonV(nloops, nverts, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiPointsPolygons(RtInt npolys, RtInt nverts[], RtInt verts[], ...)
{
    va_list argptr;
    va_start(argptr, verts);
    rm_args(argptr);
    RiPointsPolygonsV(npolys, nverts, verts, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiPointsGeneralPolygons(RtInt npolys, RtInt nloops[], RtInt nverts[],
							   RtInt verts[], ...)
{
    va_list argptr;
    va_start(argptr, verts);
    rm_args(argptr);
    RiPointsGeneralPolygonsV(npolys, nloops, nverts, verts, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiPatch(RtToken type, ...)
{
    va_list argptr;
    va_start(argptr, type);
    rm_args(argptr);
    RiPatchV(type, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiPatchMesh(RtToken type, RtInt nu, RtToken uwrap,
				   RtInt nv, RtToken vwrap, ...)
{
    va_list argptr;
    va_start(argptr, vwrap);
    rm_args(argptr);
    RiPatchMeshV(type, nu, uwrap, nv, vwrap, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiNuPatch(RtInt nu, RtInt uorder, RtFloat uknot[], RtFloat umin,
				 RtFloat umax, RtInt nv, RtInt vorder, RtFloat vknot[],
				 RtFloat vmin, RtFloat vmax, ...)
{
    va_list argptr;
    va_start(argptr, vmax);
    rm_args(argptr);
    RiNuPatch(nu, uorder, uknot, umin, umax, nv, vorder, vknot,
			  vmin, vmax, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiSphere(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...)
{
    va_list argptr;
    va_start(argptr, tmax);
    rm_args(argptr);
    RiSphereV(radius, zmin, zmax, tmax, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiCone(RtFloat height, RtFloat radius, RtFloat tmax, ...)
{
    va_list argptr;
    va_start(argptr, tmax);
    rm_args(argptr);
    RiConeV(height, radius, tmax, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiCylinder(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...)
{
    va_list argptr;
    va_start(argptr, tmax);
    rm_args(argptr);
    RiCylinderV(radius, zmin, zmax, tmax, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiHyperboloid(RtPoint point1, RtPoint point2, RtFloat tmax, ...)
{
    va_list argptr;
    va_start(argptr, tmax);
    rm_args(argptr);
    RiHyperboloidV(point1, point2, tmax, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiParaboloid(RtFloat rmax, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...)
{
    va_list argptr;
    va_start(argptr, tmax);
    rm_args(argptr);
    RiParaboloidV(rmax, zmin, zmax, tmax, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiDisk(RtFloat height, RtFloat radius, RtFloat tmax, ...)
{
    va_list argptr;
    va_start(argptr, tmax);
    rm_args(argptr);
    RiDiskV(height, radius, tmax, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiTorus(RtFloat majrad, RtFloat minrad, RtFloat phimin,
			   RtFloat phimax, RtFloat tmax, ...)
{
    va_list argptr;
    va_start(argptr, tmax);
    rm_args(argptr);
    RiTorusV(majrad, minrad, phimin, phimax, tmax, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiBlobby(RtInt nleaf, RtInt ncode, RtInt code[],
			   RtInt nflt, RtFloat flt[],
			   RtInt nstr, RtToken str[], ...)
{
    va_list argptr;
    va_start(argptr, str);
    rm_args(argptr);
    RiBlobbyV(nleaf, ncode, code, nflt, flt, nstr, str, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiCurves(RtToken type, RtInt ncurves,
				RtInt nvertices[], RtToken wrap, ...)
{
    va_list argptr;
    va_start(argptr, wrap);
    rm_args(argptr);
    RiCurvesV(type, ncurves, nvertices, wrap, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiPoints(RtInt nverts, ...)
{
    va_list argptr;
    va_start(argptr, nverts);
    rm_args(argptr);
    RiPointsV(nverts, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiSubdivisionMesh(RtToken mask, RtInt nf, RtInt nverts[],
				RtInt verts[],
				RtInt ntags, RtToken tags[], RtInt numargs[],
				RtInt intargs[], RtFloat floatargs[], ...)
{
    va_list argptr;
    va_start(argptr, floatargs);
    rm_args(argptr);
    RiSubdivisionMeshV(mask, nf, nverts, verts, ntags, tags, numargs,
					   intargs, floatargs, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiGeometry(RtToken type, ...)
{
    va_list argptr;
    va_start(argptr, type);
    rm_args(argptr);
    RiGeometryV(type, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiMakeTexture(char *pic, char *tex, RtToken swrap, RtToken twrap,
					 RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...)
{
    va_list argptr;
    va_start(argptr, twidth);
    rm_args(argptr);
    RiMakeTextureV(pic, tex, swrap, twrap, filterfunc, swidth, twidth, 
				rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiMakeBump(char *pic, char *tex, RtToken swrap, RtToken twrap,
				  RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...)
{
    va_list argptr;
    va_start(argptr, twidth);
    rm_args(argptr);
    RiMakeBumpV(pic, tex, swrap, twrap, filterfunc, swidth, twidth, 
				rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiMakeLatLongEnvironment(char *pic, char *tex, 
								RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...)
{
    va_list argptr;
    va_start(argptr, twidth);
    rm_args(argptr);
    RiMakeLatLongEnvironmentV(pic, tex, filterfunc, swidth, twidth, 
							  rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiMakeCubeFaceEnvironment(char *px, char *nx, char *py, char *ny,
								 char *pz, char *nz, char *tex, RtFloat fov,
								 RtFilterFunc filterfunc, RtFloat swidth, RtFloat ywidth, ...)
{
    va_list argptr;
    va_start(argptr, ywidth);
    rm_args(argptr);
    RiMakeCubeFaceEnvironmentV(px, nx, py, ny, pz, nz, tex, fov,
							   filterfunc, swidth, ywidth, 
							   rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiMakeShadow(char *pic, char *tex, ...)
{
    va_list argptr;
    va_start(argptr, tex);
    rm_args(argptr);
    RiMakeShadowV(pic, tex, rm_argc, rm_argv_toks, rm_argv_vals); 
}

RtVoid RiReadArchive(RtToken name, RtArchiveCallback callback, ...)
{
    va_list argptr;
    va_start(argptr, callback);
    rm_args(argptr);
    RiReadArchiveV(name, callback, rm_argc, rm_argv_toks, rm_argv_vals); 
}

/* End of file */ 