#include "BstmSky.h"

namespace Brainstem
{
	Sky::Sky(IDirect3DDevice9* device, ID3DXEffect* effect)
	{
		Device = device;
		Effect = effect;

		SetTechnique("Default");
		SetDefaultProperties();
	}

	Sky::~Sky()
	{

	}

	bool Sky::Init()
	{
		int DomeN = 32;

		int Latitude = DomeN / 2;
		int Longitude = DomeN;
		int DVSize = Longitude * Latitude;
        int DISize = (Longitude - 1) * (Latitude - 1) * 2;
        DVSize *= 2;
        DISize *= 2;

		D3DXCreateMeshFVF(DISize, DVSize, D3DXMESH_MANAGED, Vertex::FVF, Device, &Mesh);

		Vertex* v = 0;
		Mesh->LockVertexBuffer(0, (void**)&v);

		int DomeIndex = 0;
        for (int i = 0; i < Longitude; i++)
        {
            double MoveXZ = 100.0f * (i / ((float)Longitude - 1.0f)) * BSTM_PI / 180.0f;

            for (int j = 0; j < Latitude; j++)
            {
                double MoveY = BSTM_PI * j / (Latitude - 1);

				v[DomeIndex].Position.x = (float)(sin(MoveXZ) * cos(MoveY));
                v[DomeIndex].Position.y = (float)cos(MoveXZ);
                v[DomeIndex].Position.z = (float)(sin(MoveXZ) * sin(MoveY));

                v[DomeIndex].Position *= 10.0f;

                v[DomeIndex].tU = 0.5f / (float)Longitude + i / (float)Longitude;
                v[DomeIndex].tV = 0.5f / (float)Latitude + j / (float)Latitude;

                DomeIndex++;
            }
        }

		for (int i = 0; i < Longitude; i++)
        {
            double MoveXZ = 100.0f * (i / (float)(Longitude - 1.0f)) * BSTM_PI / 180.0;

            for (int j = 0; j < Latitude; j++)
            {
                double MoveY = (BSTM_PI * 2.0) - (BSTM_PI * j / (Latitude - 1));

				v[DomeIndex].Position.x = (float)(sin(MoveXZ) * cos(MoveY));
				v[DomeIndex].Position.y = (float)cos(MoveXZ);
				v[DomeIndex].Position.z = (float)(sin(MoveXZ) * sin(MoveY));

                v[DomeIndex].Position *= 10.0f;

				v[DomeIndex].tU = 0.5f / (float)Longitude + i / (float)Longitude;
                v[DomeIndex].tV = 0.5f / (float)Latitude + j / (float)Latitude;

                DomeIndex++;
            }
        }

		Mesh->UnlockVertexBuffer();

		WORD* ind = 0;
		Mesh->LockIndexBuffer(0, (void**)&ind);

		int index = 0;
        for (short i = 0; i < Longitude - 1; i++)
        {
            for (short j = 0; j < Latitude - 1; j++)
            {
                ind[index++] = (short)(i * Latitude + j);
                ind[index++] = (short)((i + 1) * Latitude + j);
                ind[index++] = (short)((i + 1) * Latitude + j + 1);

                ind[index++] = (short)((i + 1) * Latitude + j + 1);
                ind[index++] = (short)(i * Latitude + j + 1);
                ind[index++] = (short)(i * Latitude + j);
            }
        }
        short Offset = (short)(Latitude * Longitude);
        for (short i = 0; i < Longitude - 1; i++)
        {
            for (short j = 0; j < Latitude - 1; j++)
            {
                ind[index++] = (short)(Offset + i * Latitude + j);
                ind[index++] = (short)(Offset + (i + 1) * Latitude + j + 1);
                ind[index++] = (short)(Offset + (i + 1) * Latitude + j);

                ind[index++] = (short)(Offset + i * Latitude + j + 1);
                ind[index++] = (short)(Offset + (i + 1) * Latitude + j + 1);
                ind[index++] = (short)(Offset + i * Latitude + j);
            }
        }

		Mesh->UnlockIndexBuffer();

		return true;
	}

	void Sky::Update()
	{

	}

	void Sky::Render(ICamera* camera)
	{
		Mesh->DrawSubset(0);
	}

	void Sky::Release()
	{
		WRITE_RELEASE(this);
		SAFE_RELEASE(Mesh);
	}

	void Sky::ApplyTexture(ITexture* texture)
	{

	}
	
	ITexture* Sky::GetTexture()
	{
		return NULL;
	}
}