#ifndef _VIEWBASE_H
#define _VIEWBASE_H

#include "Engine.h"
#include "EngineEnums.h"
#include "OverlayBase.h"

// forward declarations for the OGLFT fonts
namespace OGLFT {
	class Monochrome;
}

namespace Engine {

class Module;
class ModelBase;
class CameraBase;

/** \brief Performs the actual drawing based on Camera and Model
 */

class ViewBase : public Module{ 
	public:
		ViewBase() : mModel(NULL), mCamera(NULL), mCurrentFont(NULL) {}
		virtual ~ViewBase() {};

		/** \brief Resizes the View */
		void Resize (int width, int height);

		/** \brief Performs actions before drawing (e.g. timer stuff) */
		void PreDraw();
		/** \brief Performs actions after drawing (e.g. swapping of buffers, etc.) */
		void PostDraw();

		/** \brief Performs all drawing */
		virtual void Draw ();

		/* Fonts */

		/** \brief Selects a font with a given specification or loads it if it was not found
		 * 
		 * Fonts can be specified by strings such as
		 *   "name=default.ttf color=#ff0000 size=12"
		 *   "color=#ff00ff size=12 otherfont.ttf"
		 *   "myfont.ttf"
		 * for which the appropriate values will be parsed.
		 *
		 * Default size is 12 and default color is white (#ffffff).
		 */
		void SelectFont (const char *font_spec);
		void SetFontJustification (FontJustification justification);

		/** \brief Draws a string at the given position using current projection
		 * and modelview matrices */
		void DrawGLString (float x, float y, const char* str);
		/** \brief Computes the width and height of the rasterized string */
		void DrawGLStringMeasure (const char* str, float *width, float *height);

		/** \brief Stores the eye poisition in eye_out */
		void GetCamereEye (float *eye_out);

		/** \brief Calculates the world coordinates to given screen coordinates */
		void CalcWorldCoordinates (int screen_x, int screen_y, float world_y, float *pos_out);

		unsigned int GetWindowWidth () { return mWindowWidth; };
		unsigned int GetWindowHeight () { return mWindowHeight; };
		int GetFrameRate() { return mFrameRate; };

		void SetDrawAxis (bool draw_axis) { mDrawGrid = draw_axis; };
		bool GetDrawAxis () { return mDrawGrid; };
		void SetDrawGrid (bool draw_grid) { mDrawGrid = draw_grid; };
		bool GetDrawGrid () { return mDrawGrid; };
		void SetGridSize (int x, int z) {	mGridSizeX = x; mGridSizeZ = z;	}

//		void AddOverlay (OverlayBasePtr overlay) { mOverlays.push_back (overlay); };

		/* Input forwarding for the overlays */
		/*
		bool SendKeyDown (const SDL_keysym &keysym);
		bool SendKeyUp (const SDL_keysym &keysym);
		bool SendMouseButtonUp (Uint8 button, Uint16 xpos, Uint16 ypos);
		bool SendMouseButtonDown (Uint8 button, Uint16 xpos, Uint16 ypos);
		*/

	private:
	protected:
		/** \brief Initializes the system */
		virtual int OnInit (int argc, char* argv[]);
		/** \brief Destroys the system (must be called!) */
		virtual void OnDestroy ();

		/** \brief Updates the camera for further drawing */
		virtual void UpdateCamera ();
		/** \brief Draws the level and all the visible Entities */
		virtual void DrawWorld ();
		/** \brief Draws orthographic overlay*/
		void DrawOverlay2D ();

		/** \brief Draws a grid of 16 x 16 tiles */
		void DrawGrid ();
		bool mDrawGrid;

		/** \brief Loads a font that was not yet loaded */
		bool LoadFont (const std::string &font_spec_string);

		ModelBase *mModel;
		CameraBase *mCamera;

		OverlayManager mOverlayManager;

		//		std::vector<OverlayBasePtr> mOverlays;

		/** \brief The height of the canvas we're drawing on */
		unsigned int mWindowHeight;
		/** \brief The width of the canvas we're drawing on */
		unsigned int mWindowWidth;
		/** \brief Stores the current frame rate */
		int mFrameRate;

		int mGridSizeX;
		int mGridSizeZ;

		/** \brief The font that is currently used */
		OGLFT::Monochrome* mCurrentFont;

		/** \brief Contains all the fonts that are to be used */
		std::map<std::string, OGLFT::Monochrome*> mFonts;

		friend class Engine;
		friend class ControllerBase;
};

}

#include "ViewBaseGlobal.h"

#endif // _VIEWBase_H
