#include <ri.h>
#include <stdio.h>

// spits out the RIB files for jello
void Jello::render() {
  int i,j,k;
  static int frame = -1;
  char file[13];

  frame++;
  if (frame == 800) RiEnd();
  if (frame >= 800) return;
  if (frame % 8) return;	// only render 1/8th of the frames

  sprintf(file,"jello%03d.tif", frame/8);
  file[13] = 0;

  RiFrameBegin(frame);
  RiDisplay(file, "file", "rgba", RI_NULL);
  RiFormat(400,400,1);
  RiProjection("perspective", RI_NULL);

  // camera
  RiTransformBegin();
  RiTranslate(0,0,5);	// camera is at (0, 0, -5)
  RiDeclare("blur","float");
  RiDeclare("transmitcolor","color");

  RiWorldBegin();

  RiAttributeBegin();
  RiTranslate(0,-300,0);
  RtColor areaLightColor = { 1, 1, 1 };
  char *areaLightHandle = RiAreaLightSource("distantlight","lightcolor",areaLightColor,RI_NULL);
  RtPoint areaLightPoints[4] = { -500, 0, -500,   500, 0, -500,   500, 0,  500,   -500, 0,  500 };
  RiPolygon(4, "P",areaLightPoints, RI_NULL);
  RiAttributeEnd();
  RiIlluminate(areaLightHandle, RI_TRUE);

  RtPoint spotLightFrom = { 1, 1, 1 };
  RtPoint spotLightTo = { 0, 0, 0 };
  RtFloat spotLightIntensity = 90;
  RtFloat spotLightAngle = 45;
  char *spotLightHandle = RiLightSource("spotlight","intensity",&spotLightIntensity,
                          "from",spotLightFrom, "to",spotLightTo,"coneangle",&spotLightAngle,RI_NULL);
  RiIlluminate(spotLightHandle, RI_FALSE);

  // the jello
  RiAttributeBegin();
  RtFloat surfaceBlur = 0.2;
  RtColor surfaceColor = { 0.8, 0.6, 0.1 };
  RtFloat surfaceKr = 0.3;
  RtFloat surfaceKs = 0.5;
  RtFloat surfaceKd = 0.4;
  RiSurface("glass","blur",&surfaceBlur, "transmitcolor",&surfaceColor, "Kr",&surfaceKr, "Ks",&surfaceKs,"Kd",&surfaceKd, RI_NULL);

  RtColor glasscolor = {.8,.6,0};
  RiColor(glasscolor);
  RtColor glassopacity = {.5,.5,.5};
  RiOpacity(glassopacity);

  float patchPosition[12];
  for(i=1; i<xNodes; i++) {
    for(j=1; j<yNodes; j++) {
      patchPosition[0] = nodes[i-1][j-1][zNodes-1]->position.x;
      patchPosition[1] = nodes[i-1][j-1][zNodes-1]->position.y;
      patchPosition[2] = nodes[i-1][j-1][zNodes-1]->position.z;

      patchPosition[3] = nodes[i-1][j][zNodes-1]->position.x;
      patchPosition[4] = nodes[i-1][j][zNodes-1]->position.y;
      patchPosition[5] = nodes[i-1][j][zNodes-1]->position.z;

      patchPosition[6] = nodes[i][j-1][zNodes-1]->position.x;
      patchPosition[7] = nodes[i][j-1][zNodes-1]->position.y;
      patchPosition[8] = nodes[i][j-1][zNodes-1]->position.z;

      patchPosition[9] = nodes[i][j][zNodes-1]->position.x;
      patchPosition[10] = nodes[i][j][zNodes-1]->position.y;
      patchPosition[11] = nodes[i][j][zNodes-1]->position.z;

      RiPatch("bilinear", "P", patchPosition, RI_NULL);
    }
  }
  
  for(i=xNodes-1; i>0; i--) {
    for(j=yNodes-1; j>0; j--) {
      patchPosition[0] = nodes[i-1][j-1][0]->position.x;
      patchPosition[1] = nodes[i-1][j-1][0]->position.y;
      patchPosition[2] = nodes[i-1][j-1][0]->position.z;

      patchPosition[3] = nodes[i-1][j][0]->position.x;
      patchPosition[4] = nodes[i-1][j][0]->position.y;
      patchPosition[5] = nodes[i-1][j][0]->position.z;

      patchPosition[6] = nodes[i][j-1][0]->position.x;
      patchPosition[7] = nodes[i][j-1][0]->position.y;
      patchPosition[8] = nodes[i][j-1][0]->position.z;

      patchPosition[9] = nodes[i][j][0]->position.x;
      patchPosition[10] = nodes[i][j][0]->position.y;
      patchPosition[11] = nodes[i][j][0]->position.z;

      RiPatch("bilinear", "P", patchPosition, RI_NULL);
    }
  }

  for(i=1; i<yNodes; i++) {
    for(j=1; j<zNodes; j++) {
      patchPosition[0] = nodes[xNodes-1][i-1][j-1]->position.x;
      patchPosition[1] = nodes[xNodes-1][i-1][j-1]->position.y;
      patchPosition[2] = nodes[xNodes-1][i-1][j-1]->position.z;

      patchPosition[3] = nodes[xNodes-1][i-1][j]->position.x;
      patchPosition[4] = nodes[xNodes-1][i-1][j]->position.y;
      patchPosition[5] = nodes[xNodes-1][i-1][j]->position.z;

      patchPosition[6] = nodes[xNodes-1][i][j-1]->position.x;
      patchPosition[7] = nodes[xNodes-1][i][j-1]->position.y;
      patchPosition[8] = nodes[xNodes-1][i][j-1]->position.z;

      patchPosition[9] = nodes[xNodes-1][i][j]->position.x;
      patchPosition[10] = nodes[xNodes-1][i][j]->position.y;
      patchPosition[11] = nodes[xNodes-1][i][j]->position.z;

      RiPatch("bilinear", "P", patchPosition, RI_NULL);
    }
  }
  
  for(i=yNodes-1; i>0; i--) {
    for(j=zNodes-1; j>0; j--) {
      patchPosition[0] = nodes[0][i-1][j-1]->position.x;
      patchPosition[1] = nodes[0][i-1][j-1]->position.y;
      patchPosition[2] = nodes[0][i-1][j-1]->position.z;

      patchPosition[3] = nodes[0][i][j-1]->position.x;
      patchPosition[4] = nodes[0][i][j-1]->position.y;
      patchPosition[5] = nodes[0][i][j-1]->position.z;

      patchPosition[6] = nodes[0][i-1][j]->position.x;
      patchPosition[7] = nodes[0][i-1][j]->position.y;
      patchPosition[8] = nodes[0][i-1][j]->position.z;

      patchPosition[9] = nodes[0][i][j]->position.x;
      patchPosition[10] = nodes[0][i][j]->position.y;
      patchPosition[11] = nodes[0][i][j]->position.z;

      RiPatch("bilinear","P", patchPosition, RI_NULL);
    }
  }

  for(i=1; i<xNodes; i++) {
    for(j=1; j<zNodes; j++) {
      patchPosition[0] = nodes[i-1][yNodes-1][j-1]->position.x;
      patchPosition[1] = nodes[i-1][yNodes-1][j-1]->position.y;
      patchPosition[2] = nodes[i-1][yNodes-1][j-1]->position.z;

      patchPosition[3] = nodes[i][yNodes-1][j-1]->position.x;
      patchPosition[4] = nodes[i][yNodes-1][j-1]->position.y;
      patchPosition[5] = nodes[i][yNodes-1][j-1]->position.z;

      patchPosition[6] = nodes[i-1][yNodes-1][j]->position.x;
      patchPosition[7] = nodes[i-1][yNodes-1][j]->position.y;
      patchPosition[8] = nodes[i-1][yNodes-1][j]->position.z;

      patchPosition[9] = nodes[i][yNodes-1][j]->position.x;
      patchPosition[10] = nodes[i][yNodes-1][j]->position.y;
      patchPosition[11] = nodes[i][yNodes-1][j]->position.z;

      RiPatch("bilinear","P", patchPosition, RI_NULL);
    }
  }
  
  for(i=xNodes-1; i>0; i--) {
    for(j=zNodes-1; j>0; j--) {
      patchPosition[0] = nodes[i-1][0][j-1]->position.x;
      patchPosition[1] = nodes[i-1][0][j-1]->position.y;
      patchPosition[2] = nodes[i-1][0][j-1]->position.z;

      patchPosition[3] = nodes[i-1][0][j]->position.x;
      patchPosition[4] = nodes[i-1][0][j]->position.y;
      patchPosition[5] = nodes[i-1][0][j]->position.z;

      patchPosition[6] = nodes[i][0][j-1]->position.x;
      patchPosition[7] = nodes[i][0][j-1]->position.y;
      patchPosition[8] = nodes[i][0][j-1]->position.z;

      patchPosition[9] = nodes[i][0][j]->position.x;
      patchPosition[10] = nodes[i][0][j]->position.y;
      patchPosition[11] = nodes[i][0][j]->position.z;

      RiPatch("bilinear","P", patchPosition, RI_NULL);
    }
  }

  RiAttributeEnd();
  RiWorldEnd();
  RiTransformEnd();
  RiFrameEnd();
  frame++;
  //glPopMatrix();
}

