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

GeActor :: GeActor(GeActor* mesh, int type) : GeMesh(mesh) {
	actor = mesh->actor;
	actor->userData = this;
	if (type != 0) actor->setGroup(type);
	cull = true;
	castShadow = false;
}

GeActor :: GeActor(GeGeometry* geometry, NxActor* actor) : GeMesh(geometry) {
	this->actor = actor;
	cull = true;
	castShadow = false;
}

GeActor :: ~GeActor() {
	if (actor != NULL) {
		physx.scene->releaseActor(*actor);
	}
}

void GeActor :: render(void) {
	if (((settings.flags & FLAG_VIEWFRUSTUM_CULLING) == 0) || (!cull)) {
		glPushMatrix();
		actor->getGlobalPose().getColumnMajor44(glMat);
		glMultMatrixf(glMat);

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

void GeActor :: render(NxMat34 globalPose) {
	if (((settings.flags & FLAG_VIEWFRUSTUM_CULLING) == 0) || (!cull)) {
		glPushMatrix();
		actor->getGlobalPose().getColumnMajor44(glMat);
		glMultMatrixf(glMat);

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

void GeActor :: update(void) {
	if(!actor->isSleeping())
		setOutOfDate();
	if (!empty()) {
		for (iterator i = begin(); i != end(); i++) {
			(*i)->update();
		}
	}
}

void GeActor :: shadowPass(GeLight* light) {
	if (actor->isDynamic() || castShadow) {
		actor->getGlobalPose().getColumnMajor44(glMat);
		meshRenderer->shadowPass(light, glMat);
	}
	if (!empty()) {
		for (iterator i = begin(); i != end(); i++) {
			(*i)->shadowPass(light, actor->getGlobalPose());
		}
	}
}