/*********************************************************************
 *
 *         EZWGL, the EZ Widget and Graphics Library
 *
 *             Copyright (C) 1996, 1997  Maorong Zou
 *  
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 **********************************************************************/
/*
 *  June 1996.  Beta Release.
 *  Sept 1996.  Release Version 1.0
 *  Dec 1996.  Release Version 1.1 Beta
 *  April 1997.  Release Version 1.2
 *  November 1997.  Release Version 1.3
 */
/**************************************************************
 *
 *   Define light sources  and materials
 */
#define _EZ_LIGHTMATERIAL1_C_
#include "EZ_Widget.h"

/**************************************************************
 *
 *   Functions implemented in this file
 */
void                EZ_BindMaterial MY_ANSIARGS((int face, EZ_Material *mat));
void                EZ_BindLightSrc MY_ANSIARGS((int num, EZ_LightSrc *lghtsrc));
void                EZ_BindLight MY_ANSIARGS((int num, EZ_LightSrc *lghtsrc));
void                EZ_BindLightModel MY_ANSIARGS((EZ_LightModel *lghtmodel));
void                EZ_MakeColorMapForMaterial MY_ANSIARGS((EZ_Material *mat, int n1, int n2));

EZ_Material         *EZ_GetDefaultMaterial MY_ANSIARGS((int idx));
EZ_Material         *EZ_DefineMaterial MY_ANSIARGS((float *definition));
EZ_LightSrc         *EZ_DefineLightSrc MY_ANSIARGS((float *definition));
EZ_LightSrc         *EZ_DefineLight MY_ANSIARGS((float *definition));
EZ_LightModel       *EZ_DefineLightModel MY_ANSIARGS((float *definition));

void                EZ_FreeMaterialAndLightSrc MY_ANSIARGS((void));
/**************************************************************/

static void     InitializeMaterial  MY_ANSIARGS((EZ_Material *mat));
static void     InitializeLightSrc  MY_ANSIARGS((EZ_LightSrc *src));
static void     InitializeLightModel MY_ANSIARGS((EZ_LightModel *lmod));

/**************************************************************
 *
 *   local variables.
 */
static EZ_Material        *mat_list = (EZ_Material *)NULL;
static EZ_LightSrc        *lightsrc_list = (EZ_LightSrc *)NULL;
static EZ_LightModel      *lightModel_list = (EZ_LightModel *)NULL;
static int avail_mat = 0, current_mat = -1;
static int avail_light = 0, current_light = -1;
static int avail_lmodel = 0, current_lmodel = -1;


/**************************************************************
 *
 *   Bind a predefined Material
 */
void EZ_BindMaterial(face,mat)
     int         face;
     EZ_Material *mat;
{
  int front = 0, back = 0;
  
  if(mat == (EZ_Material *)NULL) return;

  if(EZ_InCompilingMode != 0)
    {
      EZ_Token *t = AllocateNTokens(3);
      t->i = TOKEN_BIND_MATERIAL;
      t++;
      t->i = face;
      t++; 
      t->ptr = (void *)mat;
    }
  if(EZ_InExecutionMode != 0)
    {  
      switch(face)
	{
	case EZ_FRONT:
	  front = 1;
	  break;
	case EZ_BACK:
	  back = 1;
	  break;
	case EZ_FRONT_AND_BACK:
	  front = back = 1;
	  break;
	default:
	  EZ_GLError("EZ_BindMaterial", "Invalid face");
	  return;
	  break;
	}
      if(front)
	{
	  EZ_Material *tmat = &EZ_CurrentMaterial;
	  memcpy((void *)(tmat), (void *)mat, sizeof(EZ_Material));
	  EZ_AmbientValid = 0;
	  EZ_LColorValid = 0;
	}
      if(back)
	{
	  EZ_Material *tmat = &EZ_BackMaterial;
	  memcpy((void *)(tmat), (void *)mat, sizeof(EZ_Material));
	  EZ_AmbientValidB = 0;
	  EZ_LColorValidB = 0;
	}
    }
}

/**************************************************************
 *
 *   Bind a predefined Light source
 */
void EZ_BindLight(lignum,light)
     int         lignum;
     EZ_LightSrc *light;
{
  EZ_BindLightSrc(lignum,light);
}
void EZ_BindLightSrc(lignum,light)
     int         lignum;
     EZ_LightSrc *light;
{
  int   num;
  EZ_LightSrc *li;

  num = lignum - EZ_LIGHT0;
  if(num < 0 || num >= 8)
    {
      EZ_GLError("EZ_BindLight", "Invalid LIGHTi");
      return;
    }
  if(EZ_InCompilingMode != 0)
    {
      EZ_Token *t = AllocateNTokens(3);
      t->i = TOKEN_BIND_LIGHT;
      t++;
      t->i = lignum;
      t++; 
      t->ptr = (void *)light;
    }
  if(EZ_InExecutionMode != 0)
    {  
      li = &(EZ_CurrentLightSrc[num]);
      memcpy((void *)(li), (void *)light, sizeof(EZ_LightSrc));
      /* these two fields are modified at the time it is called */
      EZ_Lightfv(num,EZ_POSITION, li->position);
      EZ_Lightfv(num,EZ_SPOT_DIRECTION, li->direction);
      EZ_LColorValid = 0;
      EZ_LColorValidB = 0;
    }
}

/**************************************************************
 *
 *   Bind a predefined Light model
 */
void EZ_BindLightModel(lmodel)
     EZ_LightModel *lmodel;
{
  if(EZ_InCompilingMode != 0)
    {
      EZ_Token *t = AllocateNTokens(2);
      t->i = TOKEN_BIND_LIGHT_MODEL;
      t++; 
      t->ptr = (void *)lmodel;
    }
  if(EZ_InExecutionMode != 0)
    {  
      EZ_LightModelfv(EZ_LIGHT_MODEL_AMBIENT, lmodel->ambient);
      EZ_LightModelf(EZ_LIGHT_MODEL_LOCAL_VIEWER,
		     (lmodel->localviewer == 0)? 0.0 : 1.0);
      EZ_LightModelf(EZ_LIGHT_MODEL_TWO_SIDE,
		     (lmodel->twoside == 0)? 0.0 : 1.0);
    }
}

/**************************************************************
 *
 *   Define a material;
 */
static void DefineAMaterial(tmat,def)
     EZ_Material *tmat;
     float       *def;
{
  float attr;
  int   done = 0;

  attr = *def++;
  while(!done)
    {
      if(attr == EZ_EMISSION_F)
	{
	  tmat->emission[0] = *def++;
	  tmat->emission[1] = *def++;
	  tmat->emission[2] = *def++;
	  tmat->emission[3] = *def++;
	}
      else if(attr == EZ_AMBIENT_F)
	{
	  tmat->ambient[0] = *def++;
	  tmat->ambient[1] = *def++;
	  tmat->ambient[2] = *def++;
	  tmat->ambient[3] = *def++;
	}
      else if(attr == EZ_DIFFUSE_F)
	{
	  tmat->diffuse[0] = *def++;
	  tmat->diffuse[1] = *def++;
	  tmat->diffuse[2] = *def++;
	  tmat->diffuse[3] = *def++;
	}
      else if(attr == EZ_SPECULAR_F)
	{
	  tmat->specular[0] = *def++;
	  tmat->specular[1] = *def++;
	  tmat->specular[2] = *def++;
	  tmat->specular[3] = *def++;
	}
      else if(attr == EZ_SHININESS_F)
	tmat->shininess = *def++;
      else if(attr == EZ_COLOR_INDICES_F)
	{
	  tmat->aindex = *def++;
	  tmat->dindex = *def++;
	  tmat->sindex = *def++;
	}
      else if(attr ==  EZ_NULL_F)
	done = 1;
      else
	{
	  EZ_GLError("EZ_DefMaterial", "unknown property");
	  done = 1;
	}
      if(!done)  attr = *def++;
    }
}

EZ_Material    *EZ_DefineMaterial(def)
     float *def;
{
  EZ_Material  *tmat;

  current_mat++;
  if(current_mat >= avail_mat)
    {
      if(mat_list == (EZ_Material *)NULL)
	mat_list = (EZ_Material *)my_malloc( 4 * sizeof(EZ_Material), _MATERIAL1_);
      else
	mat_list = (EZ_Material *)my_realloc(mat_list,(avail_mat + 4) * sizeof(EZ_Material), _MATERIAL1_);
      if(!mat_list) EZ_OutOfMemory("EZ_DefineMaterial");
      avail_mat += 4;
    }
  tmat = mat_list + current_mat;
  InitializeMaterial(tmat);
  DefineAMaterial(tmat,def);
  return(tmat);
}

/**************************************************************
 *
 *   Define a Light Src.
 */
EZ_LightSrc    *EZ_DefineLight(def)
     float *def;
{
  return(EZ_DefineLightSrc(def));
}
EZ_LightSrc    *EZ_DefineLightSrc(def)
     float *def;
{
  float        attr;
  EZ_LightSrc  *tlight;
  int          done = 0;

  current_light++;
  if(current_light >= avail_light)
    {
      if(lightsrc_list == (EZ_LightSrc *)NULL)
	lightsrc_list = (EZ_LightSrc *)my_malloc( 4 * sizeof(EZ_LightSrc), _LIGHT_SRC_);
      else
	lightsrc_list = (EZ_LightSrc *)my_realloc(lightsrc_list,(avail_light + 4) * sizeof(EZ_LightSrc), _LIGHT_SRC_);
      if(!lightsrc_list) EZ_OutOfMemory("EZ_DefineLight");
      avail_light += 4;
    }
  tlight = lightsrc_list + current_light;
  
  InitializeLightSrc(tlight);

  attr = *def++;
  while(!done)
    {
      if(attr == EZ_POSITION_F)
	{
	  tlight->position[0] = *def++;
	  tlight->position[1] = *def++;
	  tlight->position[2] = *def++;
	  tlight->position[3] = *def++;

	}
      else if(attr == EZ_AMBIENT_F)
	{
	  tlight->ambient[0] = *def++;
	  tlight->ambient[1] = *def++;
	  tlight->ambient[2] = *def++;
	  tlight->ambient[3] = *def++;
	}
      else if(attr == EZ_DIFFUSE_F)
	{
	  tlight->diffuse[0] = *def++;
	  tlight->diffuse[1] = *def++;
	  tlight->diffuse[2] = *def++;
	  tlight->diffuse[3] = *def++;
	}
      else if(attr == EZ_SPECULAR_F)
	{
	  tlight->specular[0] = *def++;
	  tlight->specular[1] = *def++;
	  tlight->specular[2] = *def++;
	  tlight->specular[3] = *def++;
	}
      else if(attr == EZ_SPOT_DIRECTION_F)
	{
	  tlight->direction[0] = *def++;
	  tlight->direction[1] = *def++;
	  tlight->direction[2] = *def++;
	  tlight->direction[3] = *def++;
	}
      else if(attr == EZ_SPOT_EXPONENT_F)
	{
	  tlight->spotE = *def++;
	}
      else if(attr == EZ_SPOT_CUTOFF_F)
	{
	  tlight->spotA = (float)cos(*def++);
	}
      else if(attr == EZ_CONSTANT_ATTENUATION_F)
	{
	  tlight->att[0] = *def++;
	}
      else if(attr == EZ_LINEAR_ATTENUATION_F)
	{
	  tlight->att[1] = *def++;
	}
      else if(attr == EZ_QUADRATIC_ATTENUATION_F)
	{
	  tlight->att[2] = *def++;
	}
      else if(attr == EZ_NULL_F)
	done = 1;
      else
	{
	  EZ_GLError("EZ_DefLight", "unknown property");
	  done = 1;
	}
      if(!done)  attr = *def++;
    }
  return(tlight);
}

/**************************************************************
 *
 *   Define a Light Src.
 */
EZ_LightModel   *EZ_DefineLightModel(def)
     float *def;
{
  float         attr;
  EZ_LightModel *tlmodel;
  int           done = 0;

  current_lmodel++;
  if(current_lmodel >= avail_lmodel)
    {
      if(lightModel_list == (EZ_LightModel *)NULL)
	lightModel_list = (EZ_LightModel *)my_malloc( 4 * sizeof(EZ_LightModel),_LMODEL_);
      else
	lightModel_list = 
	  (EZ_LightModel *)my_realloc(lightModel_list,(avail_lmodel + 4) * sizeof(EZ_LightModel), _LMODEL_);
      if(!lightModel_list) EZ_OutOfMemory("EZ_DefineLightModel");
      avail_lmodel += 4;
    }
  tlmodel = lightModel_list + current_lmodel;
  
  InitializeLightModel(tlmodel);

  attr = *def++;
  while(!done)
    {
      if(attr == EZ_LIGHT_MODEL_AMBIENT_F)
	{
	  tlmodel->ambient[0] = *def++;
	  tlmodel->ambient[1] = *def++;
	  tlmodel->ambient[2] = *def++;
	  tlmodel->ambient[3] = *def++;
	}
      else if(attr == EZ_LIGHT_MODEL_LOCAL_VIEWER_F)
	tlmodel->localviewer = 1;
      else if(attr == EZ_LIGHT_MODEL_TWO_SIDE_F)
	tlmodel->twoside = 1;
      else if(attr == EZ_NULL_F)
	done = 1;
      else
	{
	  EZ_GLError("EZ_DefLightModel", "unknown property");
	  done = 1;
	}
      if(!done)  attr = *def++;
    }
  return(tlmodel);
}

/************************************************************
 *
 *  Release allocated spaces.
 */

void EZ_FreeMaterialAndLightSrc()
{
  if(mat_list)
    (void)my_free( (char *)mat_list);
  if(lightsrc_list)
    (void)my_free( (char *)lightsrc_list);
  if(lightModel_list)  
    (void)my_free( (char *)lightModel_list);

  mat_list = (EZ_Material *)NULL;
  avail_mat = 0; current_mat = -1;
  lightsrc_list = (EZ_LightSrc *)NULL;
  avail_light = 0; current_light = -1;
  lightModel_list = (EZ_LightModel *)NULL;
  avail_lmodel = 0; current_light = -1;
}

static void     InitializeMaterial(tmat)
     EZ_Material *tmat;
{
  float *fptr;

  fptr = tmat->emission;
  *fptr++ = 0.2; *fptr++ = 0.2; *fptr++ = 0.2; *fptr = 1.0;    
  fptr = tmat->ambient;
  *fptr++ = 0.2; *fptr++ = 0.2; *fptr++ = 0.2; *fptr = 1.0;    
  fptr = tmat->diffuse;
  *fptr++ = 0.8; *fptr++ = 0.8; *fptr++ = 0.8; *fptr = 1.0;
  fptr = tmat->specular;
  *fptr++ = 0.0; *fptr++ = 0.0; *fptr++ = 0.0; *fptr = 1.0;    
  fptr = tmat->emission;
  *fptr++ = 0.0; *fptr++ = 0.0; *fptr++ = 0.0; *fptr = 1.0; 
  tmat->shininess = 0.0;
  tmat->aindex = 0.0;
  tmat->dindex = 1.0;
  tmat->sindex = 1.0;
}

static void     InitializeLightSrc(tlight)
     EZ_LightSrc *tlight;
{
  float *fptr;

  fptr = tlight->ambient;
  *fptr++ = 0.0; *fptr++ = 0.0; *fptr++ = 0.0; *fptr = 1.0;
  
  fptr = tlight->diffuse;
  *fptr++ = 0.0; *fptr++ = 0.0; *fptr++ = 0.0; *fptr = 1.0;
  fptr = tlight->specular;
  *fptr++ = 0.0; *fptr++ = 0.0; *fptr++ = 0.0; *fptr = 1.0;
  fptr = tlight->position;
  *fptr++ = 0.0; *fptr++ = 0.0; *fptr++ = 1.0; *fptr = 0.0;
  fptr = tlight->direction;
  *fptr++ = 0.0; *fptr++ = 0.0; *fptr++ = -1.0; *fptr = 1.0;
  tlight->spotE = 0.0;
  tlight->spotA = -1.0;
  fptr = tlight->att;
  *fptr++ = 1.0; *fptr++ = 0.0; *fptr = 0.0;
}

static void    InitializeLightModel(lmodel)
     EZ_LightModel *lmodel;
{
  float *fptr;

  fptr = lmodel->ambient;
  *fptr++ =0.2; *fptr++ =0.2; *fptr++ =0.2; *fptr = 1.0;
  lmodel->localviewer = 0;
  lmodel->twoside = 0;  
}
/**********************************************************************/

static float predefined_materials[][(((sizeof(EZ_Material) +3)/sizeof(float)))] = 
{
 /* silver */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.19125, 0.0735, 0.0225, 1.0,
    /* EZ_DIFFUSE_F */        0.7038, 0.27048, 0.0828, 1.0,
    /* EZ_SPECULAR_F */       0.256777, 0.137622, 0.086014, 1.0,
    /* EZ_SHININESS_F */      1.0,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },
  /* s silver */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.23125, 0.23125, 0.23125, 1.0,
    /* EZ_DIFFUSE_F */        0.2775, 0.2775, 0.2775, 1.0,
    /* EZ_SPECULAR_F */       0.773911, 0.773911, 0.773911, 1.0,
    /* EZ_SHININESS_F */      7.0,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },

  /* gold */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.24725, 0.1995, 0.0745, 1.0,
    /* EZ_DIFFUSE_F */        0.75164, 0.60648, 0.22648, 1.0,
    /* EZ_SPECULAR_F */       0.628281, 0.555802, 0.366065, 1.0,
    /* EZ_SHININESS_F */      4.0,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },
  /*s gold */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.24725, 0.2245, 0.0645, 1.0,
    /* EZ_DIFFUSE_F */        0.34615, 0.3143, 0.0903, 1.0,
    /* EZ_SPECULAR_F */       0.797357, 0.723991, 0.208006, 1.0,
    /* EZ_SHININESS_F */      6.5,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },
 
/* brass */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.329412, 0.223529, 0.027451, 1.0,
    /* EZ_DIFFUSE_F */        0.780392, 0.568627, 0.113725, 1.0,
    /* EZ_SPECULAR_F */       0.992157, 0.941176, 0.807843, 1.0,
    /* EZ_SHININESS_F */      2.2,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },
  
  /* copper */
  {     
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.19125, 0.0735, 0.0225, 1.0,
    /* EZ_DIFFUSE_F */        0.7038, 0.27048, 0.0828, 1.0,
    /* EZ_SPECULAR_F */       0.256777, 0.137622, 0.086014, 1.0,
    /* EZ_SHININESS_F */      1.0,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },
  /* s copper */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.2295, 0.08825, 0.0275, 1.0,
    /* EZ_DIFFUSE_F */        0.5508, 0.2118, 0.066, 1.0,
    /* EZ_SPECULAR_F */       0.580594, 0.223257, 0.0695701, 1.0,
    /* EZ_SHININESS_F */      4.1,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },

  /* bronze */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.2125, 0.1275, 0.054, 1.0,
    /* EZ_DIFFUSE_F */        0.714, 0.4284, 0.18144, 1.0,
    /* EZ_SPECULAR_F */       0.393548, 0.271906, 0.166721, 1.0,
    /* EZ_SHININESS_F */      2.2,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },

/* ruby */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */       0.1745, 0.01175, 0.01175, 1.0,
    /* EZ_DIFFUSE_F */       0.61424, 0.04136, 0.04136, 1.0,
    /* EZ_SPECULAR_F */      0.727811, 0.626959, 0.626959, 1.0,
    /* EZ_SHININESS_F */     6.5,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },

  /* turquoise */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.1, 0.18725, 0.1745, 1.0,
    /* EZ_DIFFUSE_F */        0.396, 0.74151, 0.69102, 1.0,
    /* EZ_SPECULAR_F */       0.297254, 0.30829, 0.306678, 1.0,
    /* EZ_SHININESS_F */      1.0,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },
  /* jade */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.135, 0.2225, 0.1575, 1.0,
    /* EZ_DIFFUSE_F */        0.54, 0.89, 0.63, 1.0,
    /* EZ_SPECULAR_F */       0.316228, 0.316228, 0.316228, 1.0,
    /* EZ_SHININESS_F */      1.2,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },

/* emerald */
  {
    /* EZ_EMISSION_F */       0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.0215, 0.1745, 0.0215, 1.0,
    /* EZ_DIFFUSE_F */        0.07568, 0.61424, 0.07568, 1.0,
    /* EZ_SPECULAR_F */       0.633, 0.727811, 0.633, 1.0,
    /* EZ_SHININESS_F */      6.4,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,		       
    /* EZ_NULL_F */
  },

/* perl */
  {
    /* EZ_EMISSION_F */        0.0,0.0,0.0,1.0,
    /* EZ_AMBIENT_F */        0.25, 0.20725, 0.20725, 1.0,
    /* EZ_DIFFUSE_F */        1.0, 0.829, 0.829, 1.0,
    /* EZ_SPECULAR_F */       0.296648, 0.296648, 0.296648, 1.0,
    /* EZ_SHININESS_F */      1.0,
    /* EZ_COLOR_INDICES_F */   0.0,0.0,1.0,  
    /* EZ_NULL_F */
  },
};
/**********************************************************************/

EZ_Material *EZ_GetDefaultMaterial(indx)
     int indx;
{
  if(indx < 0 || indx >= 12)
    {
      EZ_GLError("EZ_GetDefaultMaterial", "Index out of range");
      return((EZ_Material *)NULL);
    }
  return( (EZ_Material *)( &(predefined_materials[indx][0])));
}
/**********************************************************************/

void EZ_MakeColorMapForMaterial(mat, start_indx,end_indx)
     EZ_Material *mat;
     int         start_indx, end_indx;
{
  float r,g,b,ra,ga,ba,rd,gd,bd,rs,gs,bs;
  float df, sf, dff, sff, sf1, shininess;
  int   i;

  if(mat == (EZ_Material *)NULL) 
    {
      mat = &(EZ_CurrentMaterial);
      EZ_AmbientValid = EZ_AmbientValidB = 0;
    }

  ra = mat->ambient[0] + mat->emission[0];
  ga = mat->ambient[1] + mat->emission[1];
  ba = mat->ambient[2] + mat->emission[2];
  rd = mat->diffuse[0];
  gd = mat->diffuse[1];
  bd = mat->diffuse[2];
  rs = mat->specular[0];
  gs = mat->specular[1];
  bs = mat->specular[2];

  df = ra + rd;
  if(df > 1.0) { ra /= df; rd /= df;}
  df = ga + gd;
  if(df > 1.0) { ga /= df; gd /= df;}
  df = ba + bd;
  if(df > 1.0) { ba /= df; bd /= df;}

  shininess = mat->shininess + 2.0;
  sf = 1.0/(float)(end_indx - start_indx +1);
  df =  sf;
  dff = 0.0;   sff = 0.0000001;
  for(i = start_indx; i <= end_indx; i++)
    {
      sf1 = pow(sff,shininess);
      r = ra + (dff * rd + sf1 * rs);
      if(r > 1.0) r = 1.0;
      g = ga + (dff * gd + sf1 * gs);
      if(g > 1.0) g = 1.0;
      b = ba + (dff * bd + sf1 * bs);
      if(b > 1.0) b = 1.0;

      dff += df; sff += sf;
      EZ_MapColor(i, (int)(r * 255.0),
                  (int)(g * 255.0),(int)(b * 255.0));
    }
}

/**********************************************************************************/
#undef _EZ_LIGHTMATERIAL1_C_
