#include <Irrlicht.h>
#include <IPhysics.h>

#pragma comment(lib, "Irrlicht.lib")
#pragma comment(lib, "IPhysics.lib")

CPhysics physics;
ISceneManager* smgr;
IVideoDriver* driver;
ICameraSceneNode* cam;

ITexture* cubeTexture;
ITexture* sphereTexture;

class EventReceiver : public IEventReceiver
{
public:
	bool OnEvent(SEvent event)
	{
		if(event.EventType == EET_MOUSE_INPUT_EVENT)
		{
			if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
			{
				//Throw test cube from camera's position
				f32 size,mass,velocity;
				size = 10;
				mass = 10;
				velocity = 5;
						
				SPhysicsPrimitive cube;

				cube.primitiveType = EPT_CUBE;
				cube.bodyType = EBT_DYNAMIC;
				cube.mass = mass;
				cube.node = smgr->addCubeSceneNode(size);
				cube.node->setMaterialFlag(EMF_LIGHTING, false);
				cube.node->setMaterialTexture(0, cubeTexture);
				cube.size = vector3df(size, size, size);

				IPhysicsEntity* entity = physics.addEntity(&cube);

				entity->setPosition(cam->getPosition());

				vector3df vel = (cam->getTarget() - cam->getPosition()).normalize() * velocity;
				entity->setVelocity(vel);

			}
			else if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
			{
				//Throw test sphere from camera's position
				f32 size,mass,velocity;
				size = 10;
				mass = 10;
				velocity = 5;

				SPhysicsPrimitive sphere;

				sphere.primitiveType = EPT_SPHERE;
				sphere.bodyType = EBT_DYNAMIC;
				sphere.mass = mass;
				sphere.node = smgr->addSphereSceneNode(size);
				sphere.node->setMaterialFlag(EMF_LIGHTING, false);
				sphere.node->setMaterialTexture(0, driver->getTexture("../../Media/spheremap.jpg"));
				sphere.size = vector3df(size,size,size);

				IPhysicsEntity* entity = physics.addEntity(&sphere);

				entity->setPosition(cam->getPosition());

				vector3df vel = (cam->getTarget() - cam->getPosition()).normalize() * velocity;
				entity->setVelocity(vel);
			}
		} 

		return false;
	}
};

int main()
{
	IrrlichtDevice* device = createDevice(EDT_DIRECT3D9);

	driver = device->getVideoDriver();
	smgr = device->getSceneManager();

	cubeTexture = driver->getTexture("../../Media/crate.jpg");

	EventReceiver reciever;
	device->setEventReceiver(&reciever);

	physics.init(device);
	
	device->getFileSystem()->addZipFileArchive("../../Media/map-20kdm2.pk3");

	IAnimatedMesh* levelmesh = smgr->getMesh("20kdm2.bsp");
	IAnimatedMeshSceneNode* levelnode = smgr->addAnimatedMeshSceneNode(levelmesh);

	//To load a static mesh like a level we will use the static mesh struct
	SPhysicsStaticMesh staticMesh;
	staticMesh.mesh = levelmesh;
	staticMesh.node = levelnode;
	staticMesh.scale = vector3df(1,1,1);

	IPhysicsEntity* levelEntity = physics.addEntity(&staticMesh);
	levelEntity->setPosition(vector3df(-1300,-144,-1249));	


	IAnimatedMesh* mesh = smgr->getMesh("../../Media/cone.3ds");
	
	IAnimatedMeshSceneNode* meshNode = smgr->addAnimatedMeshSceneNode(mesh);
	meshNode->setMaterialFlag(EMF_LIGHTING, false);
	meshNode->setMaterialTexture(0, driver->getTexture("../../Media/crate.jpg"));

	//But for dynamic meshes we will use the mesh struct
	SPhysicsMesh dynamicMesh;
	dynamicMesh.mesh = mesh;
	dynamicMesh.node = meshNode;
	dynamicMesh.scale = vector3df(1,1,1);
	
	IPhysicsEntity* meshEntity = physics.addEntity(&dynamicMesh);
	
	cam = smgr->addCameraSceneNodeFPS();

	while (device->run())
	{
		if (device->isWindowActive())
		{
			driver->beginScene(true, true, SColor(255,0,0,0));

			smgr->drawAll();

			physics.update();

			driver->endScene();
		}
	}

	physics.close();

	return 0;
}