///////////////////////////////////////////////////////////////////////////////
//
// File			: AVP_Overlay_Render.cpp
// Author		: Chris Wallace
// Date			: 20-Dec-2006
// Description	: Class to help with setting and rendering overlay quads
//
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////
#include "Core/Asura.h"
#include "Rendering/AVP_Overlay_Render.h"

void AVP_Overlay_Render::SetUV(float u1, float v1, float u2, float v2)
{
	Asura_Render::Overlay.U[0] = u1;
	Asura_Render::Overlay.U[1] = u2;
	Asura_Render::Overlay.U[2] = u2;
	Asura_Render::Overlay.U[3] = u1;

	Asura_Render::Overlay.V[0] = v1;
	Asura_Render::Overlay.V[1] = v1;
	Asura_Render::Overlay.V[2] = v2;
	Asura_Render::Overlay.V[3] = v2;
}

void AVP_Overlay_Render::SetPixelPos(float x, float y, float w, float h)
{
	Asura_Render::Overlay.X[0] = x;
	Asura_Render::Overlay.X[1] = x+w;
	Asura_Render::Overlay.X[2] = x+w;
	Asura_Render::Overlay.X[3] = x;

	Asura_Render::Overlay.Y[0] = y;
	Asura_Render::Overlay.Y[1] = y;
	Asura_Render::Overlay.Y[2] = y+h;
	Asura_Render::Overlay.Y[3] = y+h;
}

bool AVP_Overlay_Render::SetFromTileHash(Asura_Hash_ID uTileHash, bool bMirrorX, bool bMirrorY, float x, float y)
{
	return(SetFromTileHash(uTileHash, bMirrorX, bMirrorY, x, y, 1.0f, 1.0f, false, false));
}

bool AVP_Overlay_Render::SetFromTileHash(Asura_Hash_ID uTileHash, bool bMirrorX, bool bMirrorY, float x, float y, float fScaleX, float fScaleY)
{
	return(SetFromTileHash(uTileHash, bMirrorX, bMirrorY, x, y, fScaleX, fScaleY, false, false));
}

bool AVP_Overlay_Render::SetFromTileHash(Asura_Hash_ID uTileHash, bool bMirrorX, bool bMirrorY, float x, float y, bool bCentreX, bool bCentreY)
{
	return(SetFromTileHash(uTileHash, bMirrorX, bMirrorY, x, y, 1.0f, 1.0f, bCentreX, bCentreY));
}

bool AVP_Overlay_Render::SetFromTileHash(Asura_Hash_ID uTileHash, bool bMirrorX, bool bMirrorY, float x, float y, float fScaleX, float fScaleY, bool bCentreX, bool bCentreY)
{
	//Get tile data
	const Asura_TiledTextureInfo* xAnimInfo = Asura_TiledTextureManagement::GetTileInfoByHash(uTileHash);

	if(xAnimInfo)
	{
		//Set texture index
		Asura_Render::Overlay.TextureIndex = xAnimInfo->m_iIndexOfTextureUsed;

		//Work out 1:1 pixel widths
		float fLeft		= (xAnimInfo->m_TiledToWidth * xAnimInfo->m_fu1);
		float fRight	= (xAnimInfo->m_TiledToWidth * xAnimInfo->m_fu2);

		float fWidth	= fScaleX*(fRight-fLeft);

		float fTop		= (xAnimInfo->m_TiledToHeight * xAnimInfo->m_fv1);
		float fBottom	= (xAnimInfo->m_TiledToHeight * xAnimInfo->m_fv2);

		float fHeight	= fScaleY*(fBottom-fTop);

		x = (bCentreX) ? x-(fWidth*0.5f) : x;
		y = (bCentreY) ? y-(fHeight*0.5f) : y;
		

		//Set the UV's
		if(bMirrorX)
		{
			if(bMirrorY)
			{
				SetUV(xAnimInfo->m_fu2,xAnimInfo->m_fv2,xAnimInfo->m_fu1,xAnimInfo->m_fv1);
			}
			else
			{
				SetUV(xAnimInfo->m_fu2,xAnimInfo->m_fv1,xAnimInfo->m_fu1,xAnimInfo->m_fv2);
			}
		}
		else
		{
			if(bMirrorY)
			{
				SetUV(xAnimInfo->m_fu1,xAnimInfo->m_fv2,xAnimInfo->m_fu2,xAnimInfo->m_fv1);
			}
			else
			{
				SetUV(xAnimInfo->m_fu1,xAnimInfo->m_fv1,xAnimInfo->m_fu2,xAnimInfo->m_fv2);
			}
		}

		//Set Position
		SetPixelPos(x,y,fWidth,fHeight);
	}

	return(xAnimInfo!=NULL);

}

bool AVP_Overlay_Render::SetFromTileHashClipped(Asura_Hash_ID uTileHash, bool bMirrorX, bool bMirrorY, float x, float y, float fScaleX, float fScaleY, float fMinX, float fMinY, float fMaxX, float fMaxY)
{
	//Get tile data
	const Asura_TiledTextureInfo* xAnimInfo = Asura_TiledTextureManagement::GetTileInfoByHash(uTileHash);

	if(xAnimInfo)
	{
		//Set texture index
		Asura_Render::Overlay.TextureIndex = xAnimInfo->m_iIndexOfTextureUsed;

		//Work out 1:1 pixel widths
		float fLeft		= (xAnimInfo->m_TiledToWidth * xAnimInfo->m_fu1);
		float fRight	= (xAnimInfo->m_TiledToWidth * xAnimInfo->m_fu2);

		float fWidth	= fScaleX*(fRight-fLeft);

		float fTop		= (xAnimInfo->m_TiledToHeight * xAnimInfo->m_fv1);
		float fBottom	= (xAnimInfo->m_TiledToHeight * xAnimInfo->m_fv2);

		float fHeight	= fScaleY*(fBottom-fTop);

// 		x = (bCentreX) ? x-(fWidth*0.5f) : x;
// 		y = (bCentreY) ? y-(fHeight*0.5f) : y;

		//Set the UV's
		if(bMirrorX)
		{
			if(bMirrorY)
			{
				SetUV(xAnimInfo->m_fu2,xAnimInfo->m_fv2,xAnimInfo->m_fu1,xAnimInfo->m_fv1);
			}
			else
			{
				SetUV(xAnimInfo->m_fu2,xAnimInfo->m_fv1,xAnimInfo->m_fu1,xAnimInfo->m_fv2);
			}
		}
		else
		{
			if(bMirrorY)
			{
				SetUV(xAnimInfo->m_fu1,xAnimInfo->m_fv2,xAnimInfo->m_fu2,xAnimInfo->m_fv1);
			}
			else
			{
				SetUV(xAnimInfo->m_fu1,xAnimInfo->m_fv1,xAnimInfo->m_fu2,xAnimInfo->m_fv2);
			}
		}

		//Set Position
		Asura_Render::Overlay.SetClippedRectXY(x,y,fWidth,fHeight,fMinX,fMinY,fMaxX,fMaxY);
	}

	return(xAnimInfo!=NULL);

}



bool AVP_Overlay_Render::SetFromTileHashRotated(Asura_Hash_ID uTileHash, bool bMirrorX, bool bMirrorY, float x, float y, float fScaleX, float fScaleY, float fTheta)
{
	//Get tile data
	const Asura_TiledTextureInfo* xAnimInfo = Asura_TiledTextureManagement::GetTileInfoByHash(uTileHash);

	if(xAnimInfo)
	{
		//Set texture index
		Asura_Render::Overlay.TextureIndex = xAnimInfo->m_iIndexOfTextureUsed;

		//Work out 1:1 pixel widths
		float fLeft		= (xAnimInfo->m_TiledToWidth * xAnimInfo->m_fu1);
		float fRight	= (xAnimInfo->m_TiledToWidth * xAnimInfo->m_fu2);

		float fWidth	= fScaleX*(fRight-fLeft);

		float fTop		= (xAnimInfo->m_TiledToHeight * xAnimInfo->m_fv1);
		float fBottom	= (xAnimInfo->m_TiledToHeight * xAnimInfo->m_fv2);

		float fHeight	= fScaleY*(fBottom-fTop);

		//Set the UV's
		if(bMirrorX)
		{
			if(bMirrorY)
			{
				SetUV(xAnimInfo->m_fu2,xAnimInfo->m_fv2,xAnimInfo->m_fu1,xAnimInfo->m_fv1);
			}
			else
			{
				SetUV(xAnimInfo->m_fu2,xAnimInfo->m_fv1,xAnimInfo->m_fu1,xAnimInfo->m_fv2);
			}
		}
		else
		{
			if(bMirrorY)
			{
				SetUV(xAnimInfo->m_fu1,xAnimInfo->m_fv2,xAnimInfo->m_fu2,xAnimInfo->m_fv1);
			}
			else
			{
				SetUV(xAnimInfo->m_fu1,xAnimInfo->m_fv1,xAnimInfo->m_fu2,xAnimInfo->m_fv2);
			}
		}

		//Set Position
		Asura_Render::Overlay.SetRotatedRectXY(x,y,fWidth,fHeight,fTheta);
	}

	return(xAnimInfo!=NULL);

}

float AVP_Overlay_Render::GetGraphicWidth(Asura_Hash_ID uTileHash)
{
	const Asura_TiledTextureInfo* xAnimInfo = Asura_TiledTextureManagement::GetTileInfoByHash(uTileHash);

	if(xAnimInfo)
	{
		float fLeft		= (xAnimInfo->m_TiledToWidth * xAnimInfo->m_fu1);
		float fRight	= (xAnimInfo->m_TiledToWidth * xAnimInfo->m_fu2);

		return(fRight-fLeft);
	}

	return(0.0f);
}

float AVP_Overlay_Render::GetGraphicHeight(Asura_Hash_ID uTileHash)
{
	const Asura_TiledTextureInfo* xAnimInfo = Asura_TiledTextureManagement::GetTileInfoByHash(uTileHash);

	if(xAnimInfo)
	{
		float fTop		= (xAnimInfo->m_TiledToHeight * xAnimInfo->m_fv1);
		float fBottom	= (xAnimInfo->m_TiledToHeight * xAnimInfo->m_fv2);

		return(fBottom-fTop);
	}

	return(0.0f);
}


u_int AVP_Overlay_Render::MultiplyAlphaValue(u_int uColour, float fRatio)
{
	// for simple implementation of ModifyAlphaValue
	return (static_cast<u_int>(Asura_Maths::FloatToInt((uColour >> 24) * fRatio)) << 24)
		| (uColour & 0x00FFFFFF);
}

u_int AVP_Overlay_Render::MultiplyRedValue(u_int uColour, float fRatio)
{
	// for simple implementation of ModifyRedValue
	u_int uRed = (uColour & 0x00FF0000);
	u_int uStep1 = (uRed >> 16);
	u_int uStep2 = Asura_Maths::FloatToInt(uStep1 * fRatio);
	u_int uStep3 = (uStep2 << 16);
	u_int Step4 = (uColour & 0xFF00FFFF);
	u_int Step5 = uStep3 | Step4;
	
	return (Step5);
}

u_int AVP_Overlay_Render::MultiplyGreenValue(u_int uColour, float fRatio)
{
	// for simple implementation of ModifyRedValue
	u_int uRed = (uColour & 0x0000FF00);
	u_int uStep1 = (uRed >> 8);
	u_int uStep2 = Asura_Maths::FloatToInt(uStep1 * fRatio);
	u_int uStep3 = (uStep2 << 8);
	u_int Step4 = (uColour & 0xFFFF00FF);
	u_int Step5 = uStep3 | Step4;

	return (Step5);
}

u_int AVP_Overlay_Render::MultiplyBlueValue(u_int uColour, float fRatio)
{
	// for simple implementation of ModifyRedValue
	u_int uRed = (uColour & 0x000000FF);
	u_int uStep1 = Asura_Maths::FloatToInt(uRed * fRatio);
	u_int Step2 = (uColour & 0xFFFFFF00);
	u_int Step3 = uStep1 | Step2;

	return (Step3);
}

// End of File //
