#include "view.h"

Object *newObject(facelist,maxChildren)
FaceList *facelist;
int maxChildren;
{
	Object *obj;
	
	obj = Malloc(Object,1);
	
	obj->facelist = facelist;
	obj->face = NOINDEX;
	obj->numFaces = 0;
	setIdentityMatrix(obj->L.TM);
	setIdentityMatrix(obj->G.TM);
	setIdentityMatrix(obj->C.TM);
	
	if(maxChildren>0) obj->child = Malloc(ObjectPtr,maxChildren);
	
	obj->maxChildren = maxChildren;
	obj->n = 0;
	
	return(obj);
}

Object *cloneObject(object)
/*this delivers a clone of object, but not its children, with
  matrices set to identity*/
Object *object;
{
	Object *obj;
	int size;
	Vertex *oldvertex,*vertex;
	register int i;
	Index *faceIndex,*ind;
	FaceList *facelist;
	Face *face,*newface;
	Shading *s;
	int n;
	Point3D *p;
	
	if(object == NOOBJECT) return(NOOBJECT);
	
	/*assume same facelist*/
	obj = newObject((facelist=FACEListOfObject(object)),MAXChilrenOfObject(object));
	
	/*find number of vertices*/
	oldvertex = VERTEXOfObject(object);
	size = oldvertex->size;
	n = oldvertex->n;
	
	/*create new vertex list of this size*/
	vertex = newVertex(size);
	
	/*copy points from old vertex into new*/
	for(i=0;i<n;++i) {
		p = atVertex(oldvertex,i);
		atPutCoordVertex(vertex,i,p->x,p->y,p->z);
	}
	
	/*create the new faces*/
	n = NEXTFreeFaceList(facelist);
	faceIndex = FACESOfObject(object);
	while(faceIndex != NOINDEX){
		face = atFaceList(facelist,INDEX(faceIndex));
		ind = FIRSTOfFace(face);
		newface = newFace(vertex,INDEX(ind));
		do{
			ind = NEXT(ind);
			addToBackFace(newface,INDEX(ind));
		} while(ind != LASTOfFace(face));
		/*set the shading*/
		s = newShading(REDReflectionOf(face),
					   GREENReflectionOf(face),
					   BLUEReflectionOf(face));
		setShadingOfFace(newface,s);
		atPutFaceList(facelist,NEXTFreeFaceList(facelist),newface);
		faceIndex = NEXT(faceIndex);
	}
	
	for(i=n;i<NEXTFreeFaceList(facelist);++i) addFaceToObject(obj,i);
	
	return(obj);
}	
void addFaceToObject(object,i)
Object *object;
int i;
{
	object->face = addToFrontIndex(object->face,i);
	object->numFaces++;
}

void addChildToObject(parent,child)
Object *parent,*child;
{
	*(parent->child+parent->n) = child;
	parent->n++;
	
	/*global matrix of the child set to CTM of parent*/
	child->G = parent->C;
	
	/*and reset the LTM of child*/
	setLocalMatrixOfObject(child,&child->L);
}

void setGlobalMatrixOfObject(object,gtm)
Object *object;
TMatrix *gtm;
{
	register int i;
	
	object->G = *gtm;
	multiplyMatrix(object->L.TM,object->G.TM,object->C.TM);
	
	if(object->n > 0)
		for(i=0;i<object->n;++i)
			setGlobalMatrixOfObject(*(object->child+i),&object->C);
}

void setLocalMatrixOfObject(object,ltm)
Object *object;
TMatrix *ltm;
{
	register int i;
	
	object->L = *ltm;
	multiplyMatrix(object->L.TM,object->G.TM,object->C.TM);
	
	if(object->n > 0)
		for(i=0;i<object->n;++i)
			setGlobalMatrixOfObject(*(object->child+i),&object->C);
}

void traverseObject(object,f)
Object *object;
void (*f)();
{
	register int i;
	
	(*f)(object);	
	
	if(object->n > 0)
		for(i=0;i<object->n;++i)
			traverseObject(*(object->child+i),f);
}

void transformVerticesOfObject(object)
Object *object;
{
	register int i,n;
	Vertex *v;
	
	v = VERTEXOfObject(object);
	n = NEXTFreeVertex(v);
	if(n > 0)
		for(i=0;i<n;++i) TRANSFORMVertex(v,i,&object->C);
}
	