#pragma once

#include "volumeshop.h"

#include "Environment.h"
#include "Importer.h"
#include "Volume.h"
#include "DataVoxel.h"
#include "Element.h"
#include "Attribute.h"
#include <fstream>

class ImporterSelectionVolumeBrk : public Importer
{
public:

	ImporterSelectionVolumeBrk(Environment & envEnvironment) : m_envEnvironment(envEnvironment), m_fProgress(0.0f)
	{
	};

	virtual ~ImporterSelectionVolumeBrk()
	{
	};

	Environment & GetEnvironment()
	{
		return m_envEnvironment;
	};

	virtual const bool IsAccepted(const std::string & strFilename)
	{		
		std::string strLower(strFilename);
		std::transform(strFilename.begin(), strFilename.end(), strLower.begin(), tolower);

		std::vector<std::string> vecExtensions;
		vecExtensions.push_back("selectionvolume.brk");

		for (unsigned int i=0;i<vecExtensions.size();i++)
			if (strLower.substr(strLower.size()-vecExtensions[i].size()) == vecExtensions[i])
				return true;
		
		return false;
	};

	virtual void load(const std::string & strFilename)
	{
		m_fProgress = 0.0f;

		std::cout << "Loading file: " << strFilename << " ... " << std::endl;

		std::string strAdditionalFilename;
		size_t uIndex = strFilename.find_last_of('.');
		strAdditionalFilename = strFilename.substr(0,uIndex);
		strAdditionalFilename += std::string(".xml");

		std::ifstream of(strAdditionalFilename.c_str());

		Element eleRoot;
		of >> eleRoot;
		
		const unsigned int uSizeX = eleRoot[ Element("size") ][ Attribute("x")=0 ];
		const unsigned int uSizeY = eleRoot[ Element("size") ][ Attribute("y")=0 ];
		const unsigned int uSizeZ = eleRoot[ Element("size") ][ Attribute("z")=0 ];

		const float fScaleX = eleRoot[ Element("scale") ][ Attribute("x")=1.0f ];
		const float fScaleY = eleRoot[ Element("scale") ][ Attribute("y")=1.0f ];
		const float fScaleZ = eleRoot[ Element("scale") ][ Attribute("z")=1.0f ];
		const unsigned int uBlocks = (Element &)eleRoot[ Element("blocks") = 0];

		std::cout << "Volume dimensions: (" << uSizeX << "," << uSizeY << "," << uSizeZ << ")" << std::endl;
		GetEnvironment().resize(uSizeX,uSizeY,uSizeZ);
		GetEnvironment().GetSelectionVolume().clear();
		GetEnvironment().GetSelectionVolume().SetScale(Vector(fScaleX,fScaleY,fScaleZ));

		std::ifstream iz(strFilename.c_str(),std::ios::in | std::ios::binary);

		unsigned int uCount = 0;
		static SelectionVoxel vsData[BLOCKSIZE];

		while (!iz.eof())
		{
			//std::cout << "  " << (100 * uCount) / uBlocks << " %" << "\r";
			m_fProgress = float(uCount) / float(uBlocks);

			unsigned int uX,uY,uZ;
			iz.read((char*)&uX,sizeof(unsigned int));
			iz.read((char*)&uY,sizeof(unsigned int));
			iz.read((char*)&uZ,sizeof(unsigned int));
			iz.read((char*)vsData,BLOCKSIZE*sizeof(SelectionVoxel));
			GetEnvironment().GetSelectionVolume().SetBlock(uX,uY,uZ,vsData);

			uCount++;
		}

		std::cout << "Success loading file." << std::endl << std::endl;

		m_fProgress = 1.0f;

		GetEnvironment().update();
	};

	virtual const float GetProgress()
	{
		return m_fProgress;
	};

private:

	Environment & m_envEnvironment;
	float m_fProgress;
};