#include "PajaTypes.h"
#include "ColorC.h"
#include "FlareRendererC.h"
#include <math.h>

using namespace PajaTypes;
using namespace Import;

FlareRendererC::FlareRendererC()
{
}

FlareRendererC::~FlareRendererC()
{
}

void
FlareRendererC::render_flare( uint8* pBuffer, uint32 ui32Width, uint32 ui32Height,
							  const ColorC& rBGColor, const ColorC& rGlowColor, float32 f32Size, ImportableImageI* pImp, bool bUseTransparency )
{
	int32	i32R, i32G, i32B, i32A;
	float32	f32DX, f32DY, f32Mag, f32MagY;

	float32	f32CenterX = (float)ui32Width / 2.0f;
	float32	f32CenterY = (float)ui32Height / 2.0f;

	float32	f32MaxDist = f32Size;
	f32MaxDist *= f32MaxDist;

	uint8*	pDest = 0;
	uint32	i, j;

	// Draw glow
	pDest = (uint8*)pBuffer;

	for( i = 0; i < ui32Height; i++ ) {

		f32DY = (float)i - f32CenterY;
		f32MagY = (float)exp( -f32DY * f32DY / f32MaxDist );

		for( j = 0; j < ui32Width; j++ ) {

			f32DX = (float)j - f32CenterX;
			f32Mag = (float)exp( -f32DX * f32DX / f32MaxDist ) * f32MagY;
			f32Mag *= f32Mag;

			i32R = (int)((rGlowColor[0] * f32Mag + rBGColor[0] * (1.0f - f32Mag)) * 255.0f);
			i32G = (int)((rGlowColor[1] * f32Mag + rBGColor[1] * (1.0f - f32Mag)) * 255.0f);
			i32B = (int)((rGlowColor[2] * f32Mag + rBGColor[2] * (1.0f - f32Mag)) * 255.0f);
			i32A = (int)((rGlowColor[3] * f32Mag + rBGColor[3] * (1.0f - f32Mag)) * 255.0f);

			*pDest++ = (uint8)i32B;
			*pDest++ = (uint8)i32G;
			*pDest++ = (uint8)i32R;
			*pDest++ = (uint8)i32A;
		}
	}

	// if the file is available, merge it with multiply
	if( pImp && pImp->get_data() ) {

		pDest = (uint8*)pBuffer;
		uint8*	pSrc = pImp->get_data();
		int32	i32SrcWidth = pImp->get_data_width();
		int32	i32SrcPitch = pImp->get_data_pitch();
		int32	i32SrcHeight = pImp->get_data_height();
		int32	i32BPP = pImp->get_data_bpp() / 8;

		int32	i32SR, i32SG, i32SB;

		for( i = 0; i < ui32Height; i++ ) {
			for( j = 0; j < ui32Width; j++ ) {

				// Get source values
				uint8*	pPixel = &pSrc[((j % i32SrcWidth) + (i % i32SrcHeight) * i32SrcPitch) * i32BPP];
				if( i32BPP == 1 ) {
					i32SR = *pPixel;
					i32SG = *pPixel;
					i32SB = *pPixel;
				}
				else if( i32BPP == 3 || i32BPP == 4 ) {
					i32SR = pPixel[0];
					i32SG = pPixel[1];
					i32SB = pPixel[2];
				}

				pDest[0] = (uint8)(((int32)pDest[0] * i32SB) >> 8);
				pDest[1] = (uint8)(((int32)pDest[1] * i32SG) >> 8);
				pDest[2] = (uint8)(((int32)pDest[2] * i32SR) >> 8);
				pDest += 4;
			}
		}
	}

	if( bUseTransparency ) {

		// Make checker pattern for transparen areas

		pDest = (uint8*)pBuffer;

		for( i = 0; i < ui32Height; i++ ) {
			for( j = 0; j < ui32Width; j++ ) {

				int32	i32Grey = 255;

				if( (((i >> 3) ^ (j >> 3)) & 1) == 0 ) {
					i32Grey = 204;
				}

				int32	i32A = pDest[3];

				i32Grey *= (255 - i32A);

				pDest[0] = (uint8)(((int32)pDest[0] * i32A + i32Grey) >> 8);
				pDest[1] = (uint8)(((int32)pDest[1] * i32A + i32Grey) >> 8);
				pDest[2] = (uint8)(((int32)pDest[2] * i32A + i32Grey) >> 8);
				pDest[3] = pDest[3];

				pDest += 4;
			}
		}

	}
}


