#pragma once

#include "renderer.h"
#include "windowing.h"
#include "math.h"
#include "heightmap.h"
#include "quadtree.h"
#include "skybox.h"
#include "interpolators.h"
#include "text.h"

#include <list>
#include <vector>

extern rWindowing *w;
extern rRenderer *g_Renderer;
extern float *fa;
extern vector3 *na;
extern rQuadTree *q;
extern rSkyBox *s;
extern rText *t;

enum renderers
{
	not_supported,
	opengl
};

enum displayparam
{
	width,
	heigth,
	depth,
	full_screen
};

enum etypes
{
	disp,
	rend,
	cwp,
	mapc,
	ca,
	txt,
	snd,
	caminteract,
	mb
};

class rEvent
{
public:
	virtual void execute() = 0;
	int frame;
	int type;
	int intArgs[4];
	float floatArgs[8];
	char charArgs[256];
};

//function for comparing lists
#include <functional>	
namespace std
{
	template <>
	struct greater<rEvent*>
	{
		bool operator()(const rEvent *e1, const rEvent *e2)
		{
			return e1->frame < e2->frame;
		}
	};
};

namespace std
{
	template <>
	struct greater<rInterpolator*>
	{
		bool operator()(rInterpolator *i1, rInterpolator *i2)
		{
			return ((i1->getStartFrame()) < (i2->getStartFrame()));
		}
	};
};


class rInitDisp : public rEvent
{
public:
	void execute();
};

class rInitRend : public rEvent
{
public:
	void execute();
};

class rMapChange : public rEvent
{
public:
	void execute();
};

class rCamInteract : public rEvent
{
public:
	void execute();
};

class rMotionBlur : public rEvent
{
public:
	void execute();
};


class engine
{
public:
	~engine();
	bool Init(char filename[]);	//Parse cfg file
	void Update();
	void MakeInterpolatorActive();
private:
	long frameOfNextEvent;
	list<rEvent*> events;
	list<rInterpolator*> activeInterpolators;
	list<rInterpolator*> interpolators;
	ifstream file;
};

extern engine e;

class rCamWP : public rEvent
{
public:
	void execute()
	{
		for(int i=0; i<intArgs[0]; i++)
		{
			e.MakeInterpolatorActive();
		}
	}
};

class rTextShow : public rEvent
{
public:
	void execute();
	lText tx;
};

#pragma comment(lib, "winmm.lib")

class rPlaySound : public rEvent
{
public:
	void execute();
};
