#ifndef _CVIDEO_HPP_
#define _CVIDEO_HPP_

/*** SDL Header Files ***/
#include <SDL.h>

/*** DLL Header File ***/
#include "dllExport.h"

/*** Custom Header Files ***/
#include "../UtilityEngine/cString.hpp"
#include "../MathEngine/iVector/iVector2.hpp"

using UtilityEngine::cString;

namespace VideoEngine {
	/* Singleton */
	class EXPORT_FROM_MYDLL cVideo
	{
	private:
		cVideo();
		~cVideo();
		
	public:
		///Functions
		static cVideo& Inst();
		static void Delete();

		const bool Initialize() const;
		
		/* Creates the cVideo's mp_buff and mp_screen surfaces */
		const bool Setup();
		/* Uses SDL_Freesurface to delete cVideo's mp_buff and mp_screen surfaces */
		void CleanUp();

		/* Used to Display the new frame */
		void Display();

		/* ScreenShot */
		void ScreenShot( const cString& filename, const cString& dir = "" );

		SDL_Renderer* CreateRender();
		
		///Sets
		/* Sets the videos width resolution */
		void setWidth( const unsigned long int width = 640 );
		/* Sets the videos height resolution */
		void setHeight( const unsigned long int height = 480 );
		/* Sets the videos colour depth in bits */
		void setColour( const unsigned long int colour = 32 );
		/* Sets the caption on the displayed window */
		void setCaption( const cString& caption = "" );
		
		/* Sets video to use hardware surfaces if true other wise software surfaces are used */
		void setHardwareVideo( const bool hardware = false );
		/* Sets the video to full screen if true other wise a window is used */
		void setFullScreen( const bool fullscreen = false );
		/* Sets the video to use double buffering other wise no buffering is used */
		void setVSync( const bool vsync = false );

		void setDisplayMode( const SDL_DisplayMode& mode );
		
		///Gets
		/* Gets return true if video was initialized */
		const bool IsInit() const;
		/* Gets the videos width resolution */
		const unsigned long int getWidth() const;
		/* Gets the videos height resolution */
		const unsigned long int getHeight() const;
		/* Gets the videos colour depth in bits */
		const unsigned long int getColour() const;
		/* Gets the caption displayed on the window */
		const cString getCaption() const;
		
		/* Gets returns true if hardware surfaces are being used other wise false is return */
		const bool getHardwareVideo() const;
		/* Gets returns true if full screen is being used other wise false is return */
		const bool getFullScreen() const;
		/* Gets returns true if Double Buffering is being used other wise false is return */
		const bool getVSync() const;

		/* Gets returns the SDL video flags */
		const unsigned long int getVideoSettings() const;

		/* Gets returns the SDL_Window pointer */
		SDL_Window* getWindow();

		/* Gets returns the Display Mode */
		SDL_DisplayMode getDisplayMode() const;

		/* Gets returns the Red mask value */
		const unsigned long int getRmask() const;
		/* Gets returns the Green mask value */
		const unsigned long int getGmask() const;
		/* Gets returns the Blue mask value */
		const unsigned long int getBmask() const;
		/* Gets returns the Alpha mask value */
		const unsigned long int getAmask() const;
		
	private:	
		///Functions
		void VideoSettings();		
		
	private:
		///Variables
		SDL_Window* mp_window;// = nullptr
		//SDL_Renderer* mp_rend;// = nullptr

		unsigned long int m_xPos;// = 100
		unsigned long int m_yPos;// = 100
		unsigned long int m_width;// = 640
		unsigned long int m_height;// = 480
		unsigned long int m_colour;// = 32
		
		bool m_hardwareVideo;// = false
		bool m_fullscreen;// = false
		bool m_vsync;// = false
		
		unsigned long int m_videoSettings;// = SDL_RENDERER_SOFTWARE

		static cVideo* sp_inst;// = nullptr
	
		/*SDL interprets each pixel as a 32-bit number, so our masks must depend
	   on the endianness (byte order) of the machine */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
		const unsigned long int m_rmask;// = 0xff000000;
		const unsigned long int m_gmask;// = 0x00ff0000;
		const unsigned long int m_bmask;// = 0x0000ff00;
		const unsigned long int m_amask;// = 0x000000ff;
#else
		const unsigned long int m_rmask;// = 0x000000ff;
		const unsigned long int m_gmask;// = 0x0000ff00;
		const unsigned long int m_bmask;// = 0x00ff0000;
		const unsigned long int m_amask;// = 0xff000000;
#endif
	};/// END CLASS DEFINITION cVideo
}/// END NAMESPACE DEFINITION VideoEngine
#endif/// END IFNDEF _CVIDEO_HPP_
