
#include "FireDemo.h"
#include <cmath>

namespace
{
	// Live++: make the fire update run at 60 Hz
	static constexpr const float FireUpdateFrequency = 1.0f / 60.0f;
}


FireDemo::FireDemo(unsigned int width, unsigned int height)
	: m_accumulatedTime(0.0f)
	, m_palettizedFrameBuffer(width, height)
	, m_palette()
	, m_leftCube(45.0f)
	, m_rightCube(-60.0f)
#if LPP_DEMONSTRATE_HOOKS
	, m_middleCube(55.0f)
#endif
{
	// Live++: uncomment the following line to make the fire green when creating the FireDemo instance.
	//m_palette.MakeGreen();

	// 06_MultipleProcesses: after the color of the fire has been changed, notice that starting another
	// instance of the same process includes this changed behaviour, even though the executable on disk hasn't changed.
	// making the fire blue then gets applied to all running instances, no matter at which point in time they were started.
	//m_palette.MakeBlue();

	// 07_HotRestart: after the color of the fire has been changed, restart the process and notice that
	// the restarted application now has the changed behaviour applied. hot-restarted processes always have
	// all existing patches injected, and this works for multiple hot-restarted processes as well.
	//m_palette.MakeBlue();
}


void FireDemo::Update(float deltaTime)
{
	m_accumulatedTime = fmodf(m_accumulatedTime, FireUpdateFrequency);
	m_accumulatedTime += deltaTime;

	if (m_accumulatedTime >= FireUpdateFrequency)
	{
		m_palettizedFrameBuffer.SpawnFire();
	}

	m_leftCube.Update(deltaTime);
	m_rightCube.Update(deltaTime);

#if LPP_DEMONSTRATE_HOOKS
	m_middleCube.Update(deltaTime);
#endif
}


void FireDemo::Render(void)
{
	const int width = m_palettizedFrameBuffer.GetWidth();
	const int height = m_palettizedFrameBuffer.GetHeight();

#if LPP_DEMONSTRATE_HOOKS
	m_leftCube.Render(&m_palettizedFrameBuffer, width * 1u / 4u, height / 2u);
	m_rightCube.Render(&m_palettizedFrameBuffer, width * 3u / 4u, height / 2u);
	m_middleCube.Render(&m_palettizedFrameBuffer, width * 2u / 4u, height / 2u);
#else
	m_leftCube.Render(&m_palettizedFrameBuffer, width * 1u / 3u, height / 2u);
	m_rightCube.Render(&m_palettizedFrameBuffer, width * 2u / 3u, height / 2u);
#endif

	if (m_accumulatedTime >= FireUpdateFrequency)
	{
		m_palettizedFrameBuffer.AverageAndShiftUpwards();
		m_palettizedFrameBuffer.FadeOut();
	}
}
