#include "../headers/Settings.h"
#include "../headers/PhysXWrapper.h"
#include "../headers/GeMesh.h"
#include "../headers/GeSortedBranch.h"
#include "../headers/GeLight.h"

GeMesh :: GeMesh(GeMesh* mesh) {
	meshRenderer = new GeMeshRenderer(mesh->meshRenderer);
	texture = mesh->texture;
	material = mesh->material;
	animator = NULL;
	if (mesh->animator != NULL)
		setAnimator(mesh->animator->type);
	
	if (!mesh->empty()) {
		for (iterator i = mesh->begin(); i != mesh->end(); i++) {
			push_back(new GeMesh(*i));
		}
	}
}

GeMesh :: GeMesh(GeGeometry* geometry) {
	meshRenderer = new GeMeshRenderer(geometry);
	texture = NULL;
	animator = NULL;
}

GeMesh :: ~GeMesh() {
	if (!empty()) {
		clear();
	}
	delete(animator);
    delete(meshRenderer);
}

void GeMesh :: setTexture(GeTexture* texture) {
	this->texture = texture;
}

void GeMesh :: setAnimator(int type) {
	if (animator != NULL) delete animator;
	animator = NULL;
	if (type != 0) {
		animator = new GeAnimator(&localPose, type);
	}
}

void GeMesh :: render(void) {
	renderOnly();
	
	if (!empty()) {
		for (iterator i = begin(); i != end(); i++) {
			if((*i)->visible) {
				(*i)->render();
			}
		}
	}
}

void GeMesh :: render(NxMat34 globalPose) {
	NxMat34 pose = globalPose;

	glPushMatrix();
	localPose.getColumnMajor44(glMat);
	glMultMatrixf(glMat);

	renderOnly();
	
	if (!empty()) {
		for (iterator i = begin(); i != end(); i++) {
			if((*i)->visible) {
				(*i)->render(globalPose);
			}
		}
	}
	glPopMatrix();
}

void GeMesh :: update(void) {
	if (animator != NULL) {
		setOutOfDate();
		animator->update();
	}
	updateSingle();
	if (!empty()) {
		for (iterator i = begin(); i != end(); i++) {
			(*i)->update();
		}
	}
}

void GeMesh :: setOutOfDate(void) {
	if(meshRenderer != 0)
		meshRenderer->shadowGeometry.silhouetteUpToDate = 0;

	if (!empty()) {
		for (iterator i = begin(); i != end(); i++) {
			(*i)->setOutOfDate();
		}
	}
}

void GeMesh :: shadowPass(GeLight* light, NxMat34 globalPose) {
	NxMat34 pose = globalPose*localPose;
	pose.getColumnMajor44(glMat);
	meshRenderer->shadowPass(light, glMat);

	if (!empty()) {
		for (iterator i = begin(); i != end(); i++) {
			(*i)->shadowPass(light, pose);
		}
	}
}

