#ifndef SDLFORMATMAPPING_H
#define SDLFORMATMAPPING_H

#include "IMapping.h"

namespace Salamander
{

// TODO : potentially need a 'addFallbackMapping' or similar, which allows for a mapping that prints out a warning
// that an alternative has been used. 'Fallback' parameter? 'Action' parameter (MAP, FALLBACK, ERROR)

/*
** This header contains three pixel format mappings for SDL. The three different mappings convert from
** Salamander internal to various texture parameters for creating textures. 
**
** SDLPixelContentMapping specifies the source image pixel type.			ie, GL_RGB
** SDLPixelMaskMapping specifies the data format of the source pixel data.	ie, 565
** SDLInternalFormatMapping specifies the internal format for textures.		ie, RGB5A1
*/

/*
** Pixel content mapping for use when creating a 2D texture. The result should be passed in
** as the 'format' parameter.
*/
class SDLPixelContentMapping : public IMapping<PixelFormat::contentType, unsigned long>
{
public:
	/*
	** Redeclaration of the constructor
	*/
	SDLPixelContentMapping(PixelFormat::contentType contentType) : IMapping(contentType) {};

private:

	/*
	** Add all PixelFormat -> GL_FORMAT mappings to the table.
	*/
	virtual void initialiseMapping()
	{
		SDLPixelContentMapping::addMapping(PixelFormat::Colour,			GL_RGB);
		SDLPixelContentMapping::addMapping(PixelFormat::ColourAlpha,	GL_RGBA);
		SDLPixelContentMapping::addMapping(PixelFormat::Alpha,			GL_ALPHA);
		SDLPixelContentMapping::addMapping(PixelFormat::Luminance,		GL_LUMINANCE);
		SDLPixelContentMapping::addMapping(PixelFormat::LuminanceAlpha,	GL_LUMINANCE_ALPHA);
		SDLPixelContentMapping::addMapping(PixelFormat::Intensity,		GL_INTENSITY);
	}
};

/*
** Mask mapping is used when creating a 2D texture. The mapping type must be passed in
** as the 'type' parameter.
*/
class SDLPixelMaskMapping: public IMapping<PixelFormat::byteMask, unsigned long>
{
public:
	/*
	** Redeclaration of the constructor
	*/
	SDLPixelMaskMapping(PixelFormat::byteMask byteMask) : IMapping(byteMask) {};

private:

	/*
	** Add all PixelMask -> GL_TYPE mappings to the table.
	*/
	virtual void initialiseMapping()
	{
		SDLPixelMaskMapping::addMapping(PixelFormat::Unsigned8,		GL_UNSIGNED_BYTE);
		SDLPixelMaskMapping::addMapping(PixelFormat::Signed8,		GL_BYTE);
		SDLPixelMaskMapping::addMapping(PixelFormat::Unsigned16,	GL_UNSIGNED_SHORT);
		SDLPixelMaskMapping::addMapping(PixelFormat::Signed16,		GL_SHORT);

		SDLPixelMaskMapping::addMapping(PixelFormat::R3G3B2,		GL_UNSIGNED_BYTE_3_3_2);
		SDLPixelMaskMapping::addMapping(PixelFormat::B2G3R3,		GL_UNSIGNED_BYTE_2_3_3_REV);
		SDLPixelMaskMapping::addMapping(PixelFormat::R5G6B5,		GL_UNSIGNED_SHORT_5_6_5);
		SDLPixelMaskMapping::addMapping(PixelFormat::B5G6R5,		GL_UNSIGNED_SHORT_5_6_5_REV);
		//SDLPixelMaskMapping::addMapping(PixelFormat::R8G8B8,
		//SDLPixelMaskMapping::addMapping(PixelFormat::B8G8R8,

		SDLPixelMaskMapping::addMapping(PixelFormat::R4G4B4A4,		GL_UNSIGNED_SHORT_4_4_4_4);
		SDLPixelMaskMapping::addMapping(PixelFormat::B4G4R4A4,		GL_UNSIGNED_SHORT_4_4_4_4_REV);
		SDLPixelMaskMapping::addMapping(PixelFormat::R5G5B5A1,		GL_UNSIGNED_SHORT_5_5_5_1);
		SDLPixelMaskMapping::addMapping(PixelFormat::B5G5R5A1,		GL_UNSIGNED_SHORT_1_5_5_5_REV);
		SDLPixelMaskMapping::addMapping(PixelFormat::R8G8B8A8,		GL_UNSIGNED_INT_8_8_8_8);
		SDLPixelMaskMapping::addMapping(PixelFormat::B8G8R8A8,		GL_UNSIGNED_INT_8_8_8_8_REV);
		SDLPixelMaskMapping::addMapping(PixelFormat::R10G10B10A2,	GL_UNSIGNED_INT_10_10_10_2);
		SDLPixelMaskMapping::addMapping(PixelFormat::B10G10R10A2,	GL_UNSIGNED_INT_2_10_10_10_REV);
	}
};

/*
** Internal format mappings, for use when creating a 2D texture. The result should be passed
** in as the 'internal format' parameter.
*/
class SDLInternalFormatMapping  : public IMapping<PixelFormat::contentType, unsigned long>
{
public:
	/*
	** Redeclaration of the constructor
	*/
	SDLInternalFormatMapping(PixelFormat::contentType contentType) : IMapping(contentType) {};

private:

	/*
	** Add all PixelFormat -> GL_INTERNAL_FORMAT mappings to the table.
	*/
	virtual void initialiseMapping()
	{
		SDLInternalFormatMapping::addMapping(PixelFormat::Colour,			GL_RGB);
	}
};

}

#endif // SDLBLENDMAPPING_H