/*********************************************************************

Name:		Raytracer
Author:		Kamil Szatkowski "Netrix" (C)
Website:	http://www.netrix.org.pl/

*********************************************************************/
#include "Lights.hpp"
#include "NLib/nLogger.hpp"
#include "NLib/nDataVector.hpp"
#include <stdio.h>
#include <string.h>
using namespace NIne;

#pragma warning(disable: 4996)	// fopen deprecated on windows

namespace
{
	const NIne::NUint32 DATA_VECTOR_REALLOC_SIZE = 4;
}

Lights::Lights()
: m_bLoaded(false)
{
}
/********************************************************/
bool Lights::loadLights(const char* szFile)
{
	NAssert(m_bLoaded == false, "Release file first");

	FILE* pFile = fopen(szFile, "r");
	if(pFile == null)
	{
		NLogHead();
		NLogMessage("Failed to open file: %s", szFile);
		return true;
	}

	// States
	enum
	{
		E_HEAD,			// In this case: number of lights 
		E_LIGHTS,
	};
	
	NUint32 uState = E_HEAD;
	char buffer[2048] = { 0 };
	NSize_t uIndex = 0;

	while(!ferror(pFile) && !feof(pFile))
	{
		fgets(buffer, sizeof(buffer), pFile);	// read line

		if(0 == buffer[0] || 0xA == buffer[0] || 0xD == buffer[0])
		{ continue; }
		else if(buffer[0] == '/' && buffer[1] == '/')
		{ continue;	}
		else if(buffer[0] == ';' && buffer[1] == ';')
		{ continue;	}
		else if(uState == E_HEAD)
		{
			NUint32 uLightsCount;

			if(sscanf(buffer, "%d", &uLightsCount) < 1)
			{
				goto InvalidFile;
			}

			m_aLights.Create(uLightsCount);
			++uState;
		}
		else if(uState == E_LIGHTS)
		{
			LightInfo light;

			if(sscanf(buffer, "%f %f %f %f %f %f %f", &light.v3Position.x, &light.v3Position.y, &light.v3Position.z,
													&light.fPower,
													&light.v3Color.x, &light.v3Color.y, &light.v3Color.z) < 7)
			{
				goto InvalidFile;
			}

			light.v3Color = NMVector3fNormalize(light.v3Color);

			m_aLights[uIndex++] = light;

			if(uIndex >= m_aLights.GetSize())
			{
				uState++;
			}
		}
	}

	m_bLoaded = true;
	fclose(pFile);
	return false;
InvalidFile:
	NLogError("Invalid file");
	fclose(pFile);
	return true;
}
/********************************************************/
void Lights::releaseLights()
{
	m_aLights.Release();
	m_bLoaded = false;
}
/********************************************************/
void Lights::applyDomainFactor(float fDomainFactor)
{
	const float FIXING_FACTOR = 1.0f;//0.99f;

	for(NSize_t i = 0; i < m_aLights.GetSize(); ++i)
	{
		m_aLights[i].v3Position.x *= (fDomainFactor * FIXING_FACTOR);
		m_aLights[i].v3Position.y *= (fDomainFactor * FIXING_FACTOR);
		m_aLights[i].v3Position.z *= (fDomainFactor * FIXING_FACTOR);
	}
}