// ---------------------------------------------------------------------------
// 
//   Lily Engine alpha
// 
//   Copyright (c) 2010 Clifford Jolly
//     http://cliffjolly.com
//     cliff@cliffjolly.com
// 
// ---------------------------------------------------------------------------
// 
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation; either version 2 of the License, or
//   (at your option) any later version.
//  
//   This program is distributed in the hope that it will be useful, but
//   WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
//   General Public License for more details.
// 
//   You should have received a copy of the GNU General Public License
//   along with this program; if not, write to the Free Software
//   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
//   USA
// -------------------------- END HEADER -------------------------------------

/*#ifdef WIN32
	// In Windows, compile both DirectX and OpenGL.
#	define RENDERER_COMPILE_DIRECTX
//#	define RENDERER_COMPILE_OPENGL
#else
	// In Linux, compile only OpenGL.
#	ifdef WINELIB
#		define RENDERER_COMPILE_DIRECTX
#	else
#		define RENDERER_COMPILE_OPENGL
#	endif
#endif*/

#define RENDERER_COMPILE_OPENGL

#define RENDERER_GL     1
#define RENDERER_D3D    2
#define RENDERER_MYBUTT 4

#include <string>
#include <vector>
#include <map>

#include "../math/vector2d.h"

#define RENDERER_NOTEXTURE -1

typedef struct SDL_Surface SDL_Surface;

struct Vertex3D {
	float x, y, z;
	float r, g, b, a;
	float u, v;
};

enum Renderer_ListType {
	RENDERER_LIST_QUADS,
	RENDERER_LIST_TRIANGLES,
	RENDERER_LIST_LINESTRIP,
	RENDERER_LIST_LINES,
};

enum Renderer_BlendMode {
	RENDERER_BLEND_MODULATE,
	RENDERER_BLEND_ADD,
};

enum Renderer_FilterType {
	RENDERER_FILTER_LINEAR,
	RENDERER_FILTER_NEAREST,
};

/// Renderer module. Graphics code was, at one point, all pulled into
/// this so that it could be abstracted away and allow separate OpenGL
/// and DirectX versions of the project. That is no longer needed, and
/// the DirectX version can go die in a fire. (It doesn't work anymore,
/// anyway.)
class Renderer {
	public:
	
		Renderer();
		~Renderer(void);
		
		void init(int screenWidth, int screenHeight);
		void shutdown(void);
		
		void clearScreen(float r, float g, float b);
		void flipScreen(void);
		
		void drawLineStrip(const Vector2D *points, int numPoints);
		void drawLines(const Vector2D *points, int numPoints);
		void drawQuads(const Vertex3D *vertices, int numQuads);
		void drawTriangleFan(const Vertex3D *vertices, int numVerts);
		
		void setColor(float r, float g, float b, float a);
		
		void bindTexture(int texNum);
		void unbindTexture(void);
		int getBoundTexture(void);
		int makeTextureFromRGBA(void *pixels, int width, int height);
		void freeTexture(int texNum);
		
		void pushMatrix(void);
		void popMatrix(void);
		
		void rotateZ(float radians);
		void scale(float x, float y, float z);
		void translate(float x, float y, float z);
		
		/// Create a display list from the given vertices.
		int createList(const Vertex3D *vertices, int numVertices, Renderer_ListType primType);		
		void setListColor(int listNum, float r, float g, float b, float a);
		void callList(int listNum);
		void freeList(int listNum);
		
		void processExtraEvents(void);
		
		void beginScene(void);
		void endScene(void);
		
		void setBlendMode(Renderer_BlendMode mode);
		
		// Note: Affects texture in OpenGL and overall state in DirectX
		void setFilter(Renderer_FilterType type);

		SDL_Surface *screen;
		Vector2D getScreenSize(void);
		
		/// This needs to be called if the screen ever gets resized.
		/// Re-initializes OpenGL with the correct size.
		void initGL(int width, int height, unsigned int videoInitFlags);

        void purgeLists(void);

	private:
		bool initialized;
		int boundTexture;

#		ifdef RENDERER_COMPILE_OPENGL
			std::vector<unsigned int> openGLTextures;
			std::vector<unsigned int> openGLLists;
#		endif

#		ifdef RENDERER_COMPILE_DIRECTX
			std::vector<void*> directXTextures;
			std::vector<void*> directXLists;
			std::vector<void*> directXMatrixStack;
			
			void *dxhWnd;
			void *direct3dDev;
			void *direct3d;
#		endif

		float r, g, b, a;

		//std::vector<bool> allocatedTextures;
		int totalTextures;
		std::vector<unsigned int> textureListGaps;
		int totalLists;
		std::vector<unsigned int> listListGaps;
		std::vector<Renderer_ListType> listTypes;
};



