#define MODULE_USR

#include "graf.h"

extern RGBA ZBF_ColorMap[];
extern int LMD_Lmodel;

FLOAT USR_polygon[USR_MAX_VERTICES][VERTEX_NCOMP];
FLOAT USR_VertexInfo[VERTEX_NCOMP];

int USR_BackFace,USR_ColorMaterial;
int USR_VertexCount;

void usr_map_color( int n, FLOAT r, FLOAT g, FLOAT b )
{
    if ( n < 0 || n >= 4096 )
    {
       fprintf( stderr, "usr_map_color: colormap index [%d] out of range.\n" );
       return;
   }

    ZBF_ColorMap[n].r = 255.0 * r;
    ZBF_ColorMap[n].g = 255.0 * g;
    ZBF_ColorMap[n].b = 255.0 * b;
    ZBF_ColorMap[n].a = 1.0;
}

void usr_map_color4( int n, FLOAT r, FLOAT g, FLOAT b,FLOAT a )
{
    if ( n < 0 || n >= 4096 )
    {
       fprintf( stderr, "usr_map_color: colormap index [%d] out of range.\n" );
       return;
   }

    ZBF_ColorMap[n].r = 255.0 * r;
    ZBF_ColorMap[n].g = 255.0 * g;
    ZBF_ColorMap[n].b = 255.0 * b;
    ZBF_ColorMap[n].a = a;
}

FLOAT *usr_pack3f( FLOAT x, FLOAT y, FLOAT z )
{
    static FLOAT v[3];

    v[0] = x; v[1] = y; v[2] = z;

    return v;
}

void usr_backface( int status )
{
    USR_BackFace  = status;
}

void usr_bgnline( )
{
   USR_VertexCount = 0;
}

void usr_bgnpolygon()
{
   USR_VertexCount = 0;
}

void usr_bgnpoint( )
{
   USR_VertexCount = 0;
}

void usr_vertex( FLOAT *v )
{
    int i;

    for( i = VERTEX_COORD_Z+1; i<VERTEX_NCOMP; i++ )
    {
        USR_polygon[USR_VertexCount][i] = USR_VertexInfo[i];
    }

    USR_polygon[USR_VertexCount][VERTEX_COORD_X] = v[0];
    USR_polygon[USR_VertexCount][VERTEX_COORD_Y] = v[1];
    USR_polygon[USR_VertexCount][VERTEX_COORD_Z] = v[2];

    USR_VertexCount++;
}

void usr_normal( FLOAT *n )
{
    USR_VertexInfo[VERTEX_NORMAL_X] = n[0];
    USR_VertexInfo[VERTEX_NORMAL_Y] = n[1];
    USR_VertexInfo[VERTEX_NORMAL_Z] = n[2];
}

void usr_texture( FLOAT *t )
{
    USR_VertexInfo[VERTEX_TEXTURE_U] = t[0];
    USR_VertexInfo[VERTEX_TEXTURE_V] = t[1];
    USR_VertexInfo[VERTEX_TEXTURE_W] = t[2];
}

void usr_color_material(int choice)
{
    USR_ColorMaterial = choice;
}

void usr_color( FLOAT *c )
{
    switch( USR_ColorMaterial )
    {
        case LMD_COLOR_AMBIENT_AND_DIFFUSE:
           usr_material_ambient(c);
           usr_material_diffuse(c);
        break;

        case LMD_COLOR_AMBIENT:
           usr_material_ambient(c);
        break;

        case LMD_COLOR_DIFFUSE:
           usr_material_diffuse(c);
        break;

        default:
            USR_VertexInfo[VERTEX_COLOR_R] = 255.0 * c[0];
            USR_VertexInfo[VERTEX_COLOR_G] = 255.0 * c[1];
            USR_VertexInfo[VERTEX_COLOR_B] = 255.0 * c[2];
            USR_VertexInfo[VERTEX_COLOR_A] = 1.0;
        break;
    }
}

void usr_color4( FLOAT *c )
{
    switch( USR_ColorMaterial )
    {
        case LMD_COLOR_AMBIENT_AND_DIFFUSE:
           usr_material_ambient(c);
           usr_material_diffuse(c);
           usr_material_alpha(c[3]);
        break;

        case LMD_COLOR_AMBIENT:
           usr_material_ambient(c);
           usr_material_alpha(c[3]);
        break;

        case LMD_COLOR_DIFFUSE:
           usr_material_diffuse(c);
           usr_material_alpha(c[3]);
        break;

        default:
            USR_VertexInfo[VERTEX_COLOR_R] = 255.0 * c[0];
            USR_VertexInfo[VERTEX_COLOR_G] = 255.0 * c[1];
            USR_VertexInfo[VERTEX_COLOR_B] = 255.0 * c[2];
            USR_VertexInfo[VERTEX_COLOR_A] = c[3];
        break;
    }
}

void usr_color_index( FLOAT i )
{
    USR_VertexInfo[VERTEX_COLOR_I] = i;
}

void usr_endpolygon( )
{
    if ( USR_VertexCount >= 3 )
    {
        zbf_draw_polygon( USR_VertexCount, (ZBF_VERTEX *)USR_polygon );
    }
}

void usr_endline( )
{
    if ( USR_VertexCount > 1 )
    {
        zbf_draw_polyline( USR_VertexCount, (ZBF_VERTEX *)USR_polygon );
    }
}

void usr_endpoint( )
{
    if ( USR_VertexCount >= 1 )
    {
        zbf_draw_points( USR_VertexCount, (ZBF_VERTEX *)USR_polygon );
    }
}

void usr_material_alpha( FLOAT a )
{
    USR_VertexInfo[VERTEX_MATERIAL_ALPHA] = a;
}

void usr_material_ambient( FLOAT *ambient )
{
    int i;

    for( i = 0; i < 3; i++ )
    {
        USR_VertexInfo[VERTEX_MATERIAL_AMBIENT+i] = ambient[i];
    }
}    

void usr_material_diffuse( FLOAT *diffuse )
{
    int i;

    for( i = 0; i < 3; i++ )
    {
        USR_VertexInfo[VERTEX_MATERIAL_DIFFUSE+i]  = diffuse[i];
    }
}    

void usr_material_specular( FLOAT *specular, FLOAT exp )
{
    int i;

    for( i = 0; i < 3; i++ )
    {
        USR_VertexInfo[VERTEX_MATERIAL_SPECULAR+i]  = specular[i];
    }
    USR_VertexInfo[VERTEX_MATERIAL_SPECULAR_EXP] = exp;
}    
