#include "world/WorldMapBuilder.hpp"
#include "world/MapImageColor.hpp"
#include <mof/multi_solid.hpp>
#include <vector>
#include <ostream>
#include "resource.hpp"


WorldMapBuilder::WorldMapBuilder(const AreaMap &map, float scale)
: scale_(scale), map_(map)
{
}

WorldMapBuilder::~WorldMapBuilder(void)
{
}

mof::tstring WorldMapBuilder::make_model_name(AreaPowerLevel level) const
{
	int forest_number;
	if (level.forest < 3) forest_number = 0;
	else if (level.forest < 6) forest_number = 1;
	else if (level.forest < 9) forest_number = 2;
	else forest_number = 3;
	
	int earth_number;
	if (level.earth < 3) earth_number = 0;
	else if (level.earth < 6) earth_number = 1;
	else if (level.earth < 9) earth_number = 2;
	else earth_number = 3;
	

	std::basic_ostringstream<TCHAR> os;
	os << _T("model/area") << earth_number << forest_number << _T(".x");
	return os.str();
}

std::unique_ptr<::WorldMapBuilder::world_data_t> WorldMapBuilder::create() const
{
	using namespace mof;

	std::vector<Graphics3D::ptr> children;
	size_t width = map_[0].size();
	size_t height = map_.size();

	std::vector<mof::ReferenceWrapper<mof::Color4f>> color_refs;
	double half_x = width / 2;
	double half_y = height / 2;

	for (size_t y = 0; y < height; ++y) {
		for (size_t x = 0; x < width; ++x) {
			auto name = make_model_name(map_[y][x].powerLevel);
			auto p = getMeshBuilderResourceManager(::SYSTEM)->getResource(name)->construct();
			p->world_transform() 
				<< mof::Matrix3D::createScaling(mof::Vector3D(scale_, scale_, scale_))
				<< mof::Matrix3D::createTranslation(mof::Vector3D(scale_ * (x - half_x), 0, -scale_ * (y - half_y)));
			mof::ReferenceWrapper<mof::Color4f> color_ref;
			p->getColorStream() << color_ref.makeRef(mof::Color4f(1, 1, 1));
			color_refs.push_back(color_ref);
			children.push_back(std::shared_ptr<Graphics3D>(p));
		}
	}
	
	auto p = std::unique_ptr<::WorldMapBuilder::world_data_t>(new ::WorldMapBuilder::world_data_t());
	p->world_ = std::make_shared<multi_solid>(children.front(), children.back());
	p->width_ = width;
	p->height_ = height;
	p->color_refs_ = color_refs;
	return p;

}
