#include "plugin.h"

IDirect3DDevice9* Device;
LPD3DXLINE Line;
D3DXVECTOR3 D3DLine[2];

std::vector<float> Heights;

void Init(IDirect3DDevice9* device);
void Quit(void);
void Render(PluginData* Data);

Manifest MosaicPlugin = {
	PLUGIN_VER, 
	PLUGIN_NAME,
	PLUGIN_DESC,
	Init,        
	Quit,        
	Render, 
	&Properties
};
 
void Init(IDirect3DDevice9* device) 
{
	Device = device;

	if (Device != NULL) 
	{
		D3DXCreateLine(Device, &Line);
		Line->SetAntialias(true);
	}
}
 
void Quit() 
{
	if (Line != NULL)
	{
		Line->Release();
		Line = NULL;
	}
}

void Render(PluginData* Data)
{
	if (Device != NULL) 
	{
		float spectrumWidth = 0.0f;
		float spectrumRes = 0.0f;

		switch (Properties.Resolution)
		{
			case RES_SIMPLE:
					spectrumWidth = 800.0f;
					spectrumRes = 50.0f;
				break;
			case RES_DETAILED:
					spectrumWidth = 400.0f;
					spectrumRes = 200.0f;
				break;
			default:
					spectrumWidth = 600.0f;
					spectrumRes = 200.0f;
				break;
		}


		if (Line->GetWidth() != spectrumWidth/spectrumRes)
			Line->SetWidth(spectrumWidth/spectrumRes);

		if (Heights.size() != (int)spectrumRes)
		{
			Heights.clear();
			
			for(int i = 0; i < spectrumRes; i++)
				Heights.push_back(0.0f);
		}

		D3DXMATRIX finalMatrix = Data->World;

		float spacing = 1.0f;

		for(int i = 0; i < Heights.size(); i++)
		{
			float target = Data->Audio.Spectrum[(int)((i+1)*(spectrumWidth/spectrumRes))];
			Heights[i] += (target - Heights[i]) / 10.0f;

			D3DLine[0].x = ((Line->GetWidth()/4)+(spacing/2)) + (i*((Line->GetWidth()/2)+spacing));
			D3DLine[0].y = Heights[i]*2500.0f;
			D3DLine[0].z = 0.0f;

			D3DLine[1].x = ((Line->GetWidth()/4)+(spacing/2)) + (i*((Line->GetWidth()/2)+spacing));
			D3DLine[1].y = 0.0f;
			D3DLine[1].z = 0.0f;

			Line->Begin();
				Line->DrawTransform(D3DLine, 2, &finalMatrix, D3DXCOLOR(Properties.Color.R,
					Properties.Color.G,
					Properties.Color.B,
					Properties.Color.A));

				D3DXMATRIX finalY;
				D3DXMatrixRotationY(&finalY, D3DX_PI);
				finalY *= finalMatrix;

				Line->DrawTransform(D3DLine, 2, &finalY, D3DXCOLOR(Properties.Color.R,
					Properties.Color.G,
					Properties.Color.B,
					Properties.Color.A));

				D3DXMATRIX finalX;
				D3DXMatrixRotationX(&finalX, D3DX_PI);
				finalX *= finalMatrix;

				Line->DrawTransform(D3DLine, 2, &finalX, D3DXCOLOR(Properties.Color.R,
					Properties.Color.G,
					Properties.Color.B,
					Properties.Color.A));

				D3DXMATRIX finalX2;
				D3DXMATRIX finalY2;
				D3DXMATRIX finalXY;
				D3DXMatrixRotationX(&finalX2, D3DX_PI);
				D3DXMatrixRotationY(&finalY2, D3DX_PI);
				finalXY = finalX2 * finalY2 * finalMatrix;

				Line->DrawTransform(D3DLine, 2, &finalXY, D3DXCOLOR(Properties.Color.R,
					Properties.Color.G,
					Properties.Color.B,
					Properties.Color.A));

			Line->End();
		}
	}
}
 
extern "C" __declspec(dllexport) Manifest* Plugin() {
	return &MosaicPlugin;
}