/* 
 * glass - the openGL Articulated Skeleton System
 *
 * Copyright (C) 2001  Robert Ancell <bob27@users.sourceforge.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __glass_types_h__
#define __glass_types_h__

#ifdef __cplusplus
extern "C" {
#endif

typedef struct _GlassTriangle         GlassTriangle;
typedef struct _GlassTriangleList     GlassTriangleList;
typedef struct _GlassTexture          GlassTexture;
typedef struct _GlassMaterial         GlassMaterial;
/* In C++ you appear to have to define the enum first */
#ifndef __cplusplus
typedef enum   _GlassTransformType    GlassTransformType;
#endif
typedef struct _GlassTransform        GlassTransform;
typedef struct _GlassVariable         GlassVariable;
typedef struct _GlassActivePoint      GlassActivePoint;
typedef struct _GlassComponent        GlassComponent;
typedef struct _GlassObject           GlassObject;
typedef struct _GlassLibrary          GlassLibrary;
typedef struct _GlassLibraryEntry     GlassLibraryEntry;
typedef struct _GlassComponentList    GlassComponentList;
typedef struct _GlassVariableList     GlassVariableList;
typedef struct _GlassTriangleListList GlassTriangleListList;
typedef struct _GlassStructureTree    GlassStructureTree;
typedef struct _GlassRGBImage         GlassRGBImage;

/* A list of triangles, that are grouped together */
struct _GlassTriangleList {
  char *name;

  int index, alpha_index;
  int visible;

  GlassTriangle *first;
  GlassTriangle *first_alpha;
  GlassTriangleList *next;
};

/* A texture */
struct _GlassTexture {
  char *name;
  int is_alpha;

  char *image_file;
  unsigned int width, height;
  GLuint texture;

  GlassTexture *next;
};

/* A triangles material */
struct _GlassMaterial {
  char *name;
  int is_alpha;
  GLfloat ambient[4], diffuse[4], specular[4], emission[4], shininess;
  GlassTexture *texture;

  GlassMaterial *next;
};

/* A triangle */
struct _GlassTriangle {
  int is_alpha;

  GLfloat **pos;
  GLfloat **col;
  GLfloat **nor;
  GLfloat **tex;
  GlassMaterial *material;

  GlassTriangle *next;
};

/* A component, ie a transform and triangle list in an inheritance tree */
struct _GlassComponent {
  GlassTransform *transform;
  GlassTriangleList *list;
  GlassActivePoint *apoint;

  /* If this component, or it's children are required for an active point(s) */
  int apoint_transform;

  GlassComponent *next;
  GlassComponent *child;
};

/* The types of transforms */
enum _GlassTransformType {
  GLASS_NONE = 0,
  GLASS_TRANSLATE,
  GLASS_ROTATE,
  GLASS_SCALE,
  GLASS_TRANSLATE_X,
  GLASS_TRANSLATE_Y,
  GLASS_TRANSLATE_Z,
  GLASS_ROTATE_X,
  GLASS_ROTATE_Y,
  GLASS_ROTATE_Z,
  GLASS_SCALE_X,
  GLASS_SCALE_Y,
  GLASS_SCALE_Z,
  GLASS_SCALE_EVEN
};

/* In C++ you appear to have to define the enum first */
#ifdef __cplusplus
typedef enum   _GlassTransformType    GlassTransformType;
#endif

/* An openGL transform */
struct _GlassTransform {
  GlassTransformType type;
  GlassVariable **variables;
  GLfloat **values;
};

/* A bounded value, that controls a transform */
struct _GlassVariable {
  char *name;

  GLfloat value, min, max;
  GlassVariable *next;
};

/* A point on a component, whose absolute position and direction
   can be retrieved */
struct _GlassActivePoint {
  char *name;

  GLfloat pos[3];
  GLfloat dir[3];
  GLfloat initial_dir[3];

  GlassActivePoint *next;
};

/* An actual object */
struct _GlassObject {
  char *name;
  GlassLibrary *library;

  int nlists, nvariables, npoints;
  GlassVariable **variable_array;
  GlassTriangleList **list_array;
  GlassActivePoint **apoint_array;

  int variables_changed;

  GlassTexture *textures;
  GlassMaterial *materials;
  GlassVariable *variables;
  GlassTriangleList *lists;
  GlassActivePoint *points;
  GlassComponent *child;
};

/* A library of objects, so that each object can use eachothers variables, etc */
struct _GlassLibrary {

  char *name;

  GlassLibraryEntry *first;
};

struct _GlassLibraryEntry {
  GlassObject *object;

  GlassLibraryEntry *next, *last;
};

/* Below: Used temporarily for interfacing with the data file */
/* A raw list of components listed in the file */
struct _GlassComponentList
{
  int index, child_index, next_index;
  char *list_name, *apoint_name, *variable_names[4];
  GlassComponent *component;

  GlassComponentList *next;
};

/* How the components relate to eachother */
struct _GlassStructureTree
{
  int index;
  GlassComponent *component;

  GlassStructureTree *next;
  GlassStructureTree *child;
};

/* A temporary RGB image file */
typedef struct  
{
  unsigned short imagic;
  unsigned short type;
  unsigned short dim;
  unsigned short sizeX, sizeY, sizeZ;
  unsigned long min, max;
  unsigned long wasteBytes;
  char name[80];
  unsigned long colorMap;
  FILE *file;
  unsigned char *tmp[5];
  unsigned long rleEnd;
  unsigned long *rowStart;
  unsigned long *rowSize;
} GlassRGBImageTemp;

/* An RGB image file */
struct _GlassRGBImage
{
  unsigned short imagic;
  unsigned short type;
  unsigned short dim;
  unsigned short sizeX, sizeY, sizeZ;
  char name[128];
  unsigned char *data;
};
   
#ifdef __cplusplus
}
#endif

#endif /* __glass_types_h__ */
