#include <stdlib.h>

#include <IrrEventsClass.h>
#include <DebugDisplayClass.h>
#include "WaterNode.h"
#include "PostProcessing.h"

IrrlichtDevice *device;
DebugDisplayClass *debugdisplay;
EnvClass *environment;


void Quit()
{
	device->closeDevice();
}

void Screenshot()
{
	debugdisplay->takeScreenshot();
}

int main(int argc, char **argv)
{
	IrrEvents EventReceiver;
 	EventReceiver.on_key_esc = Quit;
 	EventReceiver.on_key_f6 = Screenshot;

 	//initialize Irrlicht
 	SIrrlichtCreationParameters initparas;
 	initparas.AntiAlias = false;
 	initparas.DriverType = video::EDT_DIRECT3D9;
 	initparas.EventReceiver = &EventReceiver;
 	initparas.Fullscreen = false;
 	initparas.Bits = 32;
 	initparas.Stencilbuffer = false;
 	initparas.Vsync = false;
 	initparas.WindowSize = core::dimension2d< s32 >(1024, 768);
 	initparas.HighPrecisionFPU = false;
 	initparas.WindowId = 0;

	device = createDeviceEx(initparas);

	video::IVideoDriver *driver = device->getVideoDriver();
	scene::ISceneManager *smgr = device->getSceneManager();
	gui::IGUIEnvironment *guienv = device->getGUIEnvironment();

	device->setWindowCaption(L"Water Test Environment");

	debugdisplay = new DebugDisplayClass(device);

	srand(device->getTimer()->getTime());

	//add a camera to the scene
	scene::ICameraSceneNode *fpscam = smgr->addCameraSceneNodeFPS(0,100,10);
	fpscam->setFarValue(50000.0f);
	fpscam->setNearValue(0.01f);

	device->getCursorControl()->setVisible(false);

	scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode( "Textures/terrain-heightmap.bmp");
	terrain->setMaterialTexture(0, driver->getTexture("Textures/Strandsand.tga"));
	terrain->setMaterialTexture(1, driver->getTexture("Textures/caustics.bmp"));
	terrain->setMaterialTexture(2, driver->getTexture("Textures/Graß.tga"));
	terrain->setMaterialTexture(3, driver->getTexture("Textures/Fels.bmp"));
	terrain->setPosition(core::vector3df(-100,-15,-100));
	terrain->setScale(core::vector3df(1,0.1,1));

	//build up the effect chain for bloom
	PostProcessing *PP_Test = new PostProcessing(smgr,"PP_Shaders/PP_GL_Bloom1.fx","PP_Shaders/PP_DX_Bloom1.fx",video::EPST_PS_1_4,1024,512);
    PP_Test->setShaderParameters(0.6f);
    PostProcessing *Test2 = PP_Test->addMaterial("PP_Shaders/PP_GL_Bloom2.fx","PP_Shaders/PP_DX_Bloom2.fx",video::EPST_PS_2_0,256,256);
    Test2->setShaderParameters(0.01f);
    Test2 = Test2->addMaterial("PP_Shaders/PP_GL_Bloom3.fx","PP_Shaders/PP_DX_Bloom3.fx",video::EPST_PS_2_0,256,256);
    Test2->setShaderParameters(0.01f);
    Test2 = Test2->addMaterial("PP_Shaders/PP_GL_Bloom4.fx","PP_Shaders/PP_DX_Bloom4.fx",video::EPST_PS_2_0,1024,512);
    Test2->setShaderParameters(0.7f);
    Test2->setSecondMap(PP_Test->getFirstMap(),video::ETC_CLAMP);


	//create the watersurface
	environment = new EnvClass(device,512);
	environment->setDistFogColor(0.85,0.95,1.0);
	environment->setSkyColor(0.4,0.6,1.0);
	environment->setDayNightChange(0.3);

	environment->createSky();

	environment->registerTerrain(terrain);

	scene::ISceneNode *plant;
	f32 rand_x;
	f32 rand_y;
	f32 rand_scale;
	int i;
	for(i = 500; i > 0; i--)
	{
		rand_x = 100-(rand()%200);
		rand_y = 100-(rand()%200);
		rand_scale = 1.0+(rand()%200)/200;

		plant = smgr->addMeshSceneNode(smgr->getMesh("Meshs/Wasserpflanze.b3d"));
		plant->setPosition(core::vector3df(rand_x,terrain->getHeight(rand_x,rand_y)-0.1,rand_y));
		plant->setScale(core::vector3df(rand_scale,rand_scale,rand_scale));

		if(plant->getPosition().Y > -1)
			plant->remove();
		else
			environment->registerWaterplant(plant);
	}

	//the main loop
	while(device->run())
	{
		 if (device->isWindowActive())
		 {
			driver->beginScene(true, true, video::SColor(255,150,180,255));

			smgr->setActiveCamera(fpscam);

			environment->update();

			//render the scene into the postprocessing texture
			driver->setRenderTarget(PP_Test->getFirstMap(), true, true, video::SColor(255,150,180,255));
			smgr->drawAll();
			driver->setRenderTarget(0);

			//render the effect chain
			PP_Test->renderEffect();

			guienv->drawAll();
			driver->endScene();

			debugdisplay->updateDebugDisplay();
		  }
	}

	delete debugdisplay;

	//drop the irrlicht device
	device->drop();

	delete environment;

	return 0;
}
