/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
** 
** http://oss.sgi.com/projects/FreeB
** 
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
** 
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
** 
** Additional Notice Provisions: The application programming interfaces
** established by SGI in conjunction with the Original Code are The
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
** Window System(R) (Version 1.3), released October 19, 1998. This software
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
** published by SGI, but has not been independently verified as being
** compliant with the OpenGL(R) version 1.2.1 Specification.
**
** $Date: 2012/03/29 17:22:17 $ $Revision: 1.1.1.1 $
*/
/*
** $Header: /cvs/bao-parsec/pkgs/libs/mesa/src/src/glu/sgi/libnurbs/interface/bezierPatchMesh.cc,v 1.1.1.1 2012/03/29 17:22:17 uid42307 Exp $
*/

#include "gluos.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <GL/gl.h>
#include "bezierEval.h"
#include "bezierPatchMesh.h"

static int isDegenerate(float A[2], float B[2], float C[2]);

void drawStrips(float *vertex_array, float *normal_array, int *length_array, GLenum *type_array, int num_strips)
{
  int i,j,k;
  k=0;
  /*k is the index of the first component of the current vertex*/
  for(i=0; i<num_strips; i++)
    {
      glBegin(type_array[i]);
      for(j=0; j<length_array[i]; j++)
	{
	  glNormal3fv(normal_array+k);
	  glVertex3fv(vertex_array+k);
	  k += 3;
	}
      glEnd();
    }
}

void bezierPatchMeshListDelDeg(bezierPatchMesh* list)
{
  bezierPatchMesh* temp;
  for(temp=list; temp != NULL; temp = temp->next)
    {
      bezierPatchMeshDelDeg(temp);
    }
}

void bezierPatchMeshListDelete(bezierPatchMesh *list)
{
  if(list == NULL) return;
  bezierPatchMeshListDelete(list->next);
  bezierPatchMeshDelete(list);  
}




bezierPatchMesh* bezierPatchMeshListReverse(bezierPatchMesh* list)
{
 bezierPatchMesh* ret=NULL;
 bezierPatchMesh* temp;
 bezierPatchMesh* nextone;
  for(temp = list; temp != NULL; temp = nextone)
    {
      nextone = temp->next;
      ret=bezierPatchMeshListInsert(ret, temp);
    }
 return ret;
}

/*maptype is either GL_MAP2_VERTEX_3 or GL_MAP2_VERTEX_4
 */
bezierPatchMesh *bezierPatchMeshMake(int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints,  int size_UVarray, int size_length_array)
{
  int i,j,k;
  int dimension;
  int the_ustride;
  int the_vstride;
  
  bezierPatchMesh *ret = (bezierPatchMesh*) malloc(sizeof(bezierPatchMesh));
  assert(ret);

  ret->bpatch = NULL;
  ret->bpatch_normal = NULL;
  ret->bpatch_color  = NULL;
  ret->bpatch_texcoord = NULL;
 
  if(maptype == GL_MAP2_VERTEX_3) dimension = 3;
  else if (maptype==GL_MAP2_VERTEX_4) dimension = 4;
  else {
    fprintf(stderr, "error in inMap2f, maptype=%i is wrong, maptype,map is invalid\n", maptype);
    return NULL;
  }
  
  ret->bpatch = bezierPatchMake(umin, vmin, umax, vmax, uorder, vorder, dimension);
  /*copy the control points there*/
  the_ustride = vorder * dimension;
  the_vstride = dimension;
  for(i=0; i<uorder; i++)
    for(j=0; j<vorder; j++)
      for(k=0; k<dimension; k++)
	ret->bpatch->ctlpoints[i * the_ustride + j*the_vstride+k] = ctlpoints[i*ustride+j*vstride+k];
  

  ret->size_UVarray = size_UVarray;
  ret->size_length_array = size_length_array;
  ret->UVarray = (float*) malloc(sizeof(float) * size_UVarray);
  assert(ret->UVarray);
  ret->length_array = (int *)malloc(sizeof(int) * size_length_array);
  assert(ret->length_array);
  ret->type_array = (GLenum *)malloc(sizeof(GLenum) * size_length_array);
  assert(ret->type_array);

  ret->index_UVarray = 0;
  ret->index_length_array = 0;

  ret->vertex_array = NULL;
  ret->normal_array = NULL;
  ret->color_array  = NULL;
  ret->texcoord_array = NULL;

  ret->next = NULL;
  return ret;
}

bezierPatchMesh *bezierPatchMeshMake2(int size_UVarray, int size_length_array)
{
  bezierPatchMesh *ret = (bezierPatchMesh*) malloc(sizeof(bezierPatchMesh));
  assert(ret);

  ret->bpatch = NULL;
  ret->bpatch_normal = NULL;
  ret->bpatch_color  = NULL;
  ret->bpatch_texcoord = NULL;

  ret->size_UVarray = size_UVarray;
  ret->size_length_array = size_length_array;
  ret->UVarray = (float*) malloc(sizeof(float) * size_UVarray);
  assert(ret->UVarray);
  ret->length_array = (int *)malloc(sizeof(int) * size_length_array);
  assert(ret->length_array);
  ret->type_array = (GLenum *)malloc(sizeof(GLenum) * size_length_array);
  assert(ret->type_array);

  ret->index_UVarray = 0;
  ret->index_length_array = 0;

  ret->vertex_array = NULL;
  ret->normal_array = NULL;
  ret->color_array  = NULL;
  ret->texcoord_array = NULL;

  ret->next = NULL;
  return ret;
}

void bezierPatchMeshPutPatch(bezierPatchMesh *bpm, int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints)
{
  switch(maptype){
  case GL_MAP2_VERTEX_3:
    bpm->bpatch = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints);
    break;
  case GL_MAP2_VERTEX_4:
    bpm->bpatch = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4,ustride, vstride, ctlpoints );
    break;
  case GL_MAP2_NORMAL:
    bpm->bpatch_normal = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints);
    break;
  case GL_MAP2_INDEX:
    bpm->bpatch_color = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 1, ustride, vstride, ctlpoints);
    break;
  case GL_MAP2_COLOR_4:
    bpm->bpatch_color = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4, ustride, vstride, ctlpoints);
    break;
  case GL_MAP2_TEXTURE_COORD_1:
    bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 1, ustride, vstride, ctlpoints);
    break;
  case GL_MAP2_TEXTURE_COORD_2:
    bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 2, ustride, vstride, ctlpoints);
    break;    
  case GL_MAP2_TEXTURE_COORD_3:
    bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints);
    break;    
  case GL_MAP2_TEXTURE_COORD_4:
    bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4, ustride, vstride, ctlpoints);
    break;    
  default:
    fprintf(stderr, "error in bezierPatchMeshPutPatch, maptype=%i is wrong, maptype,map is invalid\n", maptype);
  }
}
  

/*delete everything including the arrays. So if you want to output the
 *pointers of the arrays, you should not use this function to deallocate space.
 *you should dealocate manually
 */
void bezierPatchMeshDelete(bezierPatchMesh *bpm)
{
  if(bpm->bpatch != NULL)
    bezierPatchDelete(bpm->bpatch);
  if(bpm->bpatch_normal != NULL)
    bezierPatchDelete(bpm->bpatch_normal);
  if(bpm->bpatch_color != NULL)
    bezierPatchDelete(bpm->bpatch_color);
  if(bpm->bpatch_texcoord != NULL)
    bezierPatchDelete(bpm->bpatch_texcoord);
  
  free(bpm->UVarray);
  free(bpm->length_array);
  free(bpm->vertex_array);
  free(bpm->normal_array);
  free(bpm->type_array);
  free(bpm);
}
 
/*begin a strip
 *type is the primitive type:
 */
void bezierPatchMeshBeginStrip(bezierPatchMesh *bpm, GLenum type)
{
  bpm->counter = 0;
  bpm->type = type;
}

/*signal the end of the current strip*/
void bezierPatchMeshEndStrip(bezierPatchMesh *bpm)
{
  int i;
  
  /*if there are no vertices in this strip, then nothing needs to be done*/
  if(bpm->counter == 0) return;
  
  /*if the length_array is full, it should be expanded*/
  if(bpm->index_length_array >= bpm->size_length_array)
    {
      int *temp = (int*) malloc(sizeof(int) * (bpm->size_length_array*2 + 1));
      assert(temp);
      GLenum *temp_type = (GLenum*) malloc(sizeof(GLenum) * (bpm->size_length_array*2 + 1));
      assert(temp_type);
      /*update the size*/
      bpm->size_length_array = bpm->size_length_array*2 + 1;
      
      /*copy*/
      for(i=0; i<bpm->index_length_array; i++)
	{
	  temp[i] = bpm->length_array[i];
	  temp_type[i] = bpm->type_array[i];
	}
      
      /*deallocate old array*/
      free(bpm->length_array);
      free(bpm->type_array);
      
      /*point to the new array which is twice as bigger*/
      bpm->length_array = temp;
      bpm->type_array = temp_type;
    }
  bpm->type_array[bpm->index_length_array] = bpm->type;
  bpm->length_array[bpm->index_length_array++] = bpm->counter;

}

/*insert (u,v) */
void bezierPatchMeshInsertUV(bezierPatchMesh *bpm, float u, float v)
{
  int i;
  /*if the UVarray is full, it should be expanded*/
  if(bpm->index_UVarray+1 >= bpm->size_UVarray)
    {
      float *temp = (float*) malloc(sizeof(float) * (bpm->size_UVarray * 2 + 2));
      assert(temp);
      
      /*update the size*/
      bpm->size_UVarray = bpm->size_UVarray*2 + 2;
      
      /*copy*/
      for(i=0; i<bpm->index_UVarray; i++)
	{
	  temp[i] = bpm->UVarray[i];
	}
      
      /*deallocate old array*/
      free(bpm->UVarray);
      
      /*pointing to the new arrays*/
      bpm->UVarray = temp;
    }
  /*insert the new UV*/
  bpm->UVarray[bpm->index_UVarray] = u;
  bpm->index_UVarray++;
  bpm->UVarray[bpm->index_UVarray] = v;
  bpm->index_UVarray++;

  /*update counter: one more vertex*/
  bpm->counter++;


}

void bezierPatchMeshPrint(bezierPatchMesh *bpm)
{
  int i;
  printf("the bezier patch is\n");
  bezierPatchPrint(bpm->bpatch);
  printf("index_length_array= %i\n", bpm->index_length_array);
  printf("size_length_array =%i\n", bpm->size_length_array);
  printf("index_UVarray =%i\n", bpm->index_UVarray);
  printf("size_UVarray =%i\n", bpm->size_UVarray);
  printf("UVarray is\n");
  for(i=0; i<bpm->index_UVarray; i++)
    printf("%f ", bpm->UVarray[i]);

  printf("length_array is\n");
  for(i=0; i<bpm->index_length_array; i++)
    printf("%i ", bpm->length_array[i]);
  printf("\n");

}

/*insert a new patch in front of the current linked list and return the new list*/
bezierPatchMesh* bezierPatchMeshListInsert(bezierPatchMesh* list, bezierPatchMesh* bpm)
{
  bpm->next=list;
  return bpm;
}

/*print all the patches*/
void bezierPatchMeshListPrint(bezierPatchMesh* list)
{
  bezierPatchMesh *temp;
  for(temp = list; temp != NULL; temp = temp->next)
    {
      bezierPatchMeshPrint(temp);
    }
}

int bezierPatchMeshListTotalStrips(bezierPatchMesh* list)
{
  int sum=0;
  bezierPatchMesh *temp;
  for(temp=list; temp != NULL; temp = temp->next)
    {
      sum += temp->index_length_array;
    }
  return sum;
}

int bezierPatchMeshListTotalVert(bezierPatchMesh* list)
{
  int sum=0;
  bezierPatchMesh *temp;
  for(temp=list; temp != NULL; temp = temp->next)
    {
      sum += temp->index_UVarray;
    }
  return sum/2;
}

int bezierPatchMeshListNumTriangles(bezierPatchMesh* list)
{
  int sum=0;
  bezierPatchMesh* temp;
  for(temp=list; temp != NULL; temp = temp->next)
    {
      sum +=  bezierPatchMeshNumTriangles(temp);
    }
  return sum;
}

int bezierPatchMeshNumTriangles(bezierPatchMesh* bpm)
{
  int i;
  int sum=0;
  for(i=0; i<bpm->index_length_array; i++)
    {
      switch(bpm->type_array[i])
	{
	case GL_TRIANGLES:
	  sum += bpm->length_array[i]/3;
	  break;
	case GL_TRIANGLE_FAN:
	  if(bpm->length_array[i] > 2)
	    sum += bpm->length_array[i]-2;
	  break;
	case GL_TRIANGLE_STRIP:
	  if(bpm->length_array[i] > 2)
	    sum += bpm->length_array[i]-2;
	  break;
	case GL_QUAD_STRIP:
	  if(bpm->length_array[i]>2)
	    sum += (bpm->length_array[i]-2);
	  break;
	default:
	  fprintf(stderr,"error in bezierPatchMeshListNumTriangles, type invalid\n");
	}
    }
  return sum;
}

/*delete degenerate triangles*/
void bezierPatchMeshDelDeg(bezierPatchMesh* bpm)
{
  if(bpm == NULL) return;
  int i,j,k;
  int *new_length_array;
  GLenum *new_type_array;
  int index_new_length_array;
  float *new_UVarray;
  int index_new_UVarray;

  new_length_array = (int*)malloc(sizeof(int) * bpm->index_length_array);
  assert(new_length_array);
  new_type_array = (GLenum*)malloc(sizeof(GLenum) * bpm->index_length_array);
  assert(new_length_array);
  new_UVarray = (float*) malloc(sizeof(float) * bpm->index_UVarray);
  assert(new_UVarray);

  index_new_length_array = 0;
  index_new_UVarray=0;
  k=0;
  for(i=0; i<bpm->index_length_array; i++){
    
    /*(if not degenerate, we have to copy*/
    if( (bpm->length_array[i] != 3) || (!isDegenerate(bpm->UVarray+k, bpm->UVarray+k+2, bpm->UVarray+k+4)))
	  {
	    for(j=0; j<2* bpm->length_array[i]; j++)
	      new_UVarray[index_new_UVarray++] = bpm->UVarray[k++];

	    new_length_array[index_new_length_array] = bpm->length_array[i];
	    new_type_array[index_new_length_array] = bpm->type_array[i];
	    index_new_length_array++;
	  }
    else
      {
	k += 6;
      }
  }  
  free(bpm->UVarray);
  free(bpm->length_array);
  free(bpm->type_array);
  bpm->UVarray=new_UVarray;
  bpm->length_array=new_length_array;
  bpm->type_array=new_type_array;
  bpm->index_UVarray = index_new_UVarray;
  bpm->index_length_array = index_new_length_array;
  
}

/*(u,v) to XYZ
 *the xyz and normals are stored in vertex_array, 
 *and normal_array. the spaces of both are allocated here
 */
void bezierPatchMeshEval(bezierPatchMesh* bpm)
{
  int i,j,k,l;
  float u,v;
  float u0 = bpm->bpatch->umin;
  float u1 = bpm->bpatch->umax;
  int uorder = bpm->bpatch->uorder;
  float v0 = bpm->bpatch->vmin;
  float v1 = bpm->bpatch->vmax;
  int vorder = bpm->bpatch->vorder;
  int dimension = bpm->bpatch->dimension;
  int ustride = dimension * vorder;
  int vstride = dimension;
  float *ctlpoints = bpm->bpatch->ctlpoints;
  
  bpm->vertex_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3);
  assert(bpm->vertex_array);
  bpm->normal_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3);
  assert(bpm->normal_array);

  k=0;
  l=0;
  for(i=0; i<bpm->index_length_array; i++)
    {
      for(j=0; j<bpm->length_array[i]; j++)
	{
	  u = bpm->UVarray[k];
	  v = bpm->UVarray[k+1];
	  bezierSurfEval(u0,u1,uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u,v, bpm->vertex_array+l);
	  bezierSurfEvalNormal(u0,u1,uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u,v, bpm->normal_array+l);
	  k += 2;
	  l += 3;
	}
    }
}
    
void bezierPatchMeshListEval(bezierPatchMesh* list)
{
  bezierPatchMesh* temp;
  for(temp = list; temp != NULL; temp = temp->next)
    {
      bezierPatchMeshEval(temp);
    }
}

void bezierPatchMeshDraw(bezierPatchMesh* bpm)
{
  int i,j,k;
  k=0;
  /*k is the index of the first component of the current vertex*/
  for(i=0; i<bpm->index_length_array; i++)
    {
      glBegin(bpm->type_array[i]);
      for(j=0; j<bpm->length_array[i]; j++)
	{
	  glNormal3fv(bpm->normal_array+k);
	  glVertex3fv(bpm->vertex_array+k);
	  k+= 3;
	}
      glEnd();
    }
}

void bezierPatchMeshListDraw(bezierPatchMesh* list)
{
  bezierPatchMesh* temp;
  for(temp = list; temp != NULL; temp = temp->next)
    {
      bezierPatchMeshDraw(temp);
    }
}

void bezierPatchMeshListCollect(bezierPatchMesh* list, float **vertex_array, float **normal_array, int **length_array, GLenum **type_array, int *num_strips)
{
  int i,j,k,l;
  bezierPatchMesh *temp;
  int total_num_vertices = bezierPatchMeshListTotalVert(list);
  (*vertex_array) = (float *) malloc(sizeof(float) * total_num_vertices*3);
  assert(*vertex_array);
  (*normal_array) = (float *) malloc(sizeof(float) * total_num_vertices*3);
  assert(*normal_array);

  *num_strips = bezierPatchMeshListTotalStrips(list);
   
  *length_array = (int*) malloc(sizeof(int) * (*num_strips));
  assert(*length_array);

  *type_array = (GLenum*) malloc(sizeof(GLenum) * (*num_strips));
  assert(*type_array);
  
  k=0;
  l=0;
  for(temp = list; temp != NULL; temp = temp->next)
    {
      int x=0;
      for(i=0; i<temp->index_length_array; i++)
	{
	  for(j=0; j<temp->length_array[i]; j++)
	    {
	      (*vertex_array)[k] = temp->vertex_array[x];
	      (*vertex_array)[k+1] = temp->vertex_array[x+1];
	      (*vertex_array)[k+2] = temp->vertex_array[x+2];

	      (*normal_array)[k] = temp->normal_array[x];
	      (*normal_array)[k+1] = temp->normal_array[x+1];
	      (*normal_array)[k+2] = temp->normal_array[x+2];

	      x += 3;
	      k += 3;
	    }
	  (*type_array)[l]  = temp->type_array[i];
	  (*length_array)[l++] = temp->length_array[i];
	}
    }
}



static int isDegenerate(float A[2], float B[2], float C[2])
{
  if( (A[0] == B[0] && A[1]==B[1]) ||
      (A[0] == C[0] && A[1]==C[1]) ||
      (B[0] == C[0] && B[1]==C[1])
     )
    return 1;
  else
    return 0;
}




