//-----------------------------------------------------------------------------------------------
// Texture.hpp
//
#pragma once
#ifndef include_Texture
#define include_Texture

//-----------------------------------------------------------------------------------------------
#include "Engine/Core/IntVector2.hpp"
#include "Engine/Core/AABB2.hpp"


/////////////////////////////////////////////////////////////////////////////////////////////////
enum TextureEdgeMode
{
	TEXTURE_EDGE_CLAMP,
	TEXTURE_EDGE_REPEAT,
	NUM_TEXTURE_EDGE_MODES
};


/////////////////////////////////////////////////////////////////////////////////////////////////
enum TextureFilterMode
{
	TEXTURE_FILTER_NEAREST,
	TEXTURE_FILTER_LINEAR,
	NUM_TEXTURE_FILTER_MODES
};


/////////////////////////////////////////////////////////////////////////////////////////////////
class Texture
{
public:
	IntVector2 GetDimensions() const { return m_dimensions; }

protected:
	Texture();
	virtual ~Texture();
	virtual void PopulateFromFile( const char* imageFilePath, TextureFilterMode minFilter, TextureFilterMode magFilter, TextureEdgeMode edgeMode ) = 0;
	virtual void PopulateFromData( unsigned char* imageData, const IntVector2& dimensions, int numChannels, TextureFilterMode minFilter, TextureFilterMode magFilter, TextureEdgeMode edgeMode ) = 0;

protected:
	IntVector2		m_dimensions;
	int				m_numChannels;

	friend class Renderer;
};


/////////////////////////////////////////////////////////////////////////////////////////////////
// A logical whole or part of a physical texture.  Generalization of (a) an entire texture map,
//	or (b) a sub-region of a texture map (specified by texture coordinates).
//
// Can also be created by calling Renderer::CreateOrGetLogicalTexture() and specifying texture
//	file path name, which may or may not already be loaded.
//
class LogicalTexture
{
public:
	LogicalTexture()
		: m_texture( nullptr )
		, m_texCoords( AABB2::ZERO_TO_ONE )
	{}

	explicit LogicalTexture( Texture* texture, const AABB2& texCoords = AABB2::ZERO_TO_ONE )
		: m_texture( texture )
		, m_texCoords( texCoords )
	{}

	explicit LogicalTexture( Texture* texture, const IntVector2& sheetCoords, const IntVector2& sheetLayout )
		: m_texture( texture )
	{
		float sheetTileWidth = (1.f / (float) sheetLayout.x);
		float sheetTileHeight = (1.f / (float) sheetLayout.y);
		m_texCoords.mins.x = sheetTileWidth * (float) sheetCoords.x;
		m_texCoords.mins.y = sheetTileHeight * (float) sheetCoords.y;
		m_texCoords.maxs.x = m_texCoords.mins.x + sheetTileWidth;
		m_texCoords.maxs.y = m_texCoords.mins.y + sheetTileHeight;
	}

public:
	Texture*	m_texture;
	AABB2		m_texCoords;
};



#endif // include_Texture
