#ifndef _CRENDERER_HPP_
#define _CRENDERER_HPP_

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

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

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

using UtilityEngine::cString;

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

		/* Creates the Renderer */
		const bool Setup();
		/* Uses  */
		void CleanUp();

		void Render( SDL_Texture* texture, SDL_Rect* srcrect, SDL_Rect* dstrect );
		void Render( SDL_Surface* surface, SDL_Rect* srcrect, SDL_Rect* dstrect );
		void Render( SDL_Surface* src, const SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect );
		void Render( SDL_Texture* src, const SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect );
		void Render( SDL_Texture* src, const SDL_Rect* srcrect, SDL_Renderer* dst, SDL_Rect* dstrect );	

		void RenderToTexture( SDL_Texture* src, SDL_Rect* srcrect, SDL_Texture* dst, SDL_Rect* dstrect );

		void RenderDrawColor( const SDL_Colour& colour );
		void RenderDrawRect( const SDL_Rect& rect, SDL_Texture* dst = nullptr );

		/* Takes a screen shot by copying the pixels from the Renderer to a new SDL_Surface and Calls SaveSurface(). */
		void ScreenShot(const cString& filename, const cString& dir = "");
		/* Saves the SDL_Surface to the given file name and directory */
		void SaveSurface( SDL_Surface* surface, const cString& fileName, const cString& dir = "" );
		/* Saves the SDL_Texture to the given file name and directory */
		void SaveTexture( SDL_Texture* texture, const cString& fileName, const cString& dir = "" );

		/* Give it a SDL_Surface and it returns a SDL_Texture */
		SDL_Texture* SurfaceToTexture( SDL_Surface* surface );
		/* Give it a SDL_Texture and it returns and SDL_Surface */
		SDL_Surface* TextureToSurface( SDL_Texture* texture );

		void CopyTexture( SDL_Texture* src, SDL_Texture* dst, bool software = false );

		SDL_Surface* CopySurface( SDL_Surface* src );

		SDL_Surface* NewSurface( long int width = -1, long int height = -1 ) const;
		SDL_Texture* NewTexture( long int width = -1, long int height = -1, const bool copyRenderer = false, const unsigned long int access = SDL_TEXTUREACCESS_TARGET ) const;

		/* Give it two SDL_Surface you wish to compare returns true if the pixels are the same. */
		const bool AreEqual( SDL_Surface& one, SDL_Surface& two );

		void SetRenderTarget( SDL_Renderer* renderer, SDL_Texture* target = nullptr );
		void SetRenderTarget( SDL_Texture* target = nullptr );
		void ResetRenderTarget();

		/// Sets

		/// Gets
		SDL_Renderer* getRenderer();
		SDL_Renderer* getRendererCopy();
	
	private:
		/// Variables
		SDL_Renderer* mp_renderer;
		SDL_Renderer* mp_rendererSoftware;

		static cRenderer* sp_inst;// = nullptr
	};/// END CLASS DEFINITION cRenderer
}/// END NAMESPACE DEFINITION VideoEngine
#endif/// END IFNDEF _CRENDERER_HPP_