#include "TextureImage.h"
#include "RenderDevice.h"
#include "Utilities/Log.h"

#include <cmath>

#if defined(max)
#define std::max max
#else
#define max(a,b) ( a > b ? a : b )
#endif

namespace BlueCore
{

//------------------------------------------------------------------------------
TextureImage::TextureImage(RenderDevice* device, Texture *texture, float ax,
		float ay, float bx, float by) :
	_Texture(texture), _Device(device)
{
	unsigned int texture_width = _Texture->getWidth();
	unsigned int texture_height = _Texture->getHeight();

	// greater 0, and values < 1 are fractions of texture dimemsions
	float e_ax= max( ax <= 1.0 ? texture_width * ax : ax, 0.0f );
	float e_ay= max( ay <= 1.0 ? texture_height * ay : ay, 0.0f );
	float e_bx= max( bx <= 1.0 ? texture_width * bx : bx, 0.0f );
	float e_by= max( by <= 1.0 ? texture_height * by : by, 0.0f );

	float width = e_bx - e_ax;
	float height = e_by - e_ay;

	// fractional values
	float au= max( ax > 1.0 ? ax / texture_width : ax, 0.0f );
	float av= max( ay > 1.0 ? ay / texture_height : ay, 0.0f );
	float bu= max( bx > 1.0 ? bx / texture_width : bx, 0.0f );
	float bv= max( by > 1.0 ? by / texture_height : by, 0.0f );

	// bottom left
	_Vertices[0] = 0.0;
	_Vertices[1] = 0.0;
	_TexCoords[0] = au;
	_TexCoords[1] = 1.0-bv;

	// top left
	_Vertices[2] = 0.0;
	_Vertices[3] = height-1;
	_TexCoords[2] = au;
	_TexCoords[3] = 1.0-av;

	// top right
	_Vertices[4] = width-1;
	_Vertices[5] = height-1;
	_TexCoords[4] = bu;
	_TexCoords[5] = 1.0-av;

	// bottom right
	_Vertices[6] = width-1;
	_Vertices[7] = 0.0;
	_TexCoords[6] = bu;
	_TexCoords[7] = 1.0-bv;

	_Width = (unsigned int)width;
	_Height = (unsigned int)height;

	clog << ">>> TextureImage constructed..."<< endlog;
}

//------------------------------------------------------------------------------
TextureImage::~TextureImage()
{
	clog << ">>> TextureImage destructed..."<< endlog;
}

//------------------------------------------------------------------------------
void TextureImage::draw(float x, float y, int halign, int valign, float r)
{
	if (!_Device.valid())
		return;

	_Device->begin2D();

	if (x < 0.0)
		x += _Device->getViewportWidth();
	else if (x < 1.0)
		x *= _Device->getViewportWidth();

	if (halign == -1)
		x -= _Width;
	else if (halign == 0)
		x -= _Width / 2;

	if (y < 0.0)
		y += _Device->getViewportHeight();
	else if (y < 1.0)
		y *= _Device->getViewportHeight();

	if (valign == -1)
		y -= _Height;
	else if (valign == 0)
		y -= _Height / 2;

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, _Texture->getId() );

	glPushMatrix();
	glLoadIdentity();
	glTranslatef(x, y, 0);
	if (r != 0.)
		glRotatef(r, 0.0, 0.0, 1.0);

	glBegin(GL_QUADS);

	glTexCoord2f(_TexCoords[2], _TexCoords[3]);
	glVertex2f(_Vertices[2], _Vertices[3]);

	glTexCoord2f(_TexCoords[0], _TexCoords[1]);
	glVertex2f(_Vertices[0], _Vertices[1]);

	glTexCoord2f(_TexCoords[6], _TexCoords[7]);
	glVertex2f(_Vertices[6], _Vertices[7]);

	glTexCoord2f(_TexCoords[4], _TexCoords[5]);
	glVertex2f(_Vertices[4], _Vertices[5]);

	glEnd();

	glPopMatrix();

	_Device->end2D();

}

//------------------------------------------------------------------------------
unsigned int TextureImage::getWidth()
{
	return _Width;
}

//------------------------------------------------------------------------------
unsigned int TextureImage::getHeight()
{
	return _Height;
}

} // namespace BlueCore
