//	Darkstar Engine  (c) UnderWorld Interactive Studio (all coding by Svarog    2008)
//
//      Данный файл является частью Darkstar Engine. Любое использование кода файла
//      без согласия компании, является нарушением закона об авторском праве (в слу-
//      чае если не оговорено обратное).
//
//      Имя файла: quad.cpp
//      Краткое описание: стандартный объект - квад
//

#include <Darkstar/Resource System/Model/SimpleModels/quad.hpp>
#include <Darkstar/Graphic System/Render State/cull_render_state.hpp>

using namespace rs;
using gs::Effect;

Quad::Quad(const shared_ptr<Effect>& effect)
{
	_create(-1.0, 1.0, 2.0f, effect);
};

Quad::Quad(const float size, const shared_ptr<Effect>& effect)
{
	_create(-1.0, -1.0, size, effect);
};

Quad::Quad(const float lx, const float ly, const float size, const shared_ptr<gs::Effect>& effect)
{
	_create(lx, ly, size, effect);
};

Quad::~Quad()
{

};

Quad& Quad::operator =(const Quad& new_quad)
{
	this->quad_model = new_quad.getModel();
	return *this;
};

void Quad::_create(const float lx, const float ly, const float size, const shared_ptr<Effect>& effect)
{
	float vertex_data[] = 
	{
		lx, ly, 0.0f, 0.0f, 0.0f,
		lx + size, ly, 0.0f, 1.0f, 0.0f,
		lx + size, ly - size, 0.0f, 1.0f, 1.0f,
		lx, ly - size, 0.0f, 0.0f, 1.0f,
	};

	short index_data [] = 
	{
		0, 1, 2, 2, 3, 0,
	};
	this->lx = lx;
	this->ly = ly;
	this->size = size;

	shared_ptr<InputLayout> input_layout(new InputLayout());
	input_layout->addElement("POSITION", 0, 0, 0, DFMT_R32G32B32_FLOAT);
	input_layout->addElement("TEXCOORD", 0, 0, 12, DFMT_R32G32_FLOAT);
	input_layout->create(effect->getEffectInputSignature().code.get(), effect->getEffectInputSignature().size);

	shared_ptr<VertexBuffer> vertex_buffer(new VertexBuffer(input_layout));
	vertex_buffer->createNextStreamWithData(5*sizeof(float), 4, vertex_data);

	shared_ptr<IndexBuffer> index_buffer(new IndexBuffer());
	index_buffer->createWithData(6, DSEIB_16, index_data);

	shared_ptr<Material> quad_material(new Material());
	quad_material->setEffect(effect);
	quad_material->setTechnique("base");
	quad_material->setCullMode(shared_ptr<gs::CullModeRenderState>(new gs::CullModeRenderState(gs::DCULL_BACK)));

	quad_model.reset(new StaticModel());
	quad_model->addNextMesh(shared_ptr<Mesh>(new Mesh(vertex_buffer, index_buffer, quad_material)));
};

const shared_ptr<StaticModel>& Quad::getModel() const
{
	return quad_model;
};

void Quad::setShaderMaterialConstants(const shared_ptr<Effect>& new_effect, const std::string& technique_name)
{
	quad_model->getMesh(0)->getMaterial()->setEffect(new_effect);
	quad_model->getMesh(0)->getMaterial()->setTechnique(technique_name);
};

void Quad::setCurTechniqueName(const std::string& tech_name)
{
	quad_model->getMesh(0)->getMaterial()->setTechnique(tech_name);
};

void Quad::addMaterialTexture(const std::string& texture_name, const shared_ptr<BaseTexture>& texture)
{
	quad_model->getMesh(0)->getMaterial()->addTexture(texture_name, texture);
};

float Quad::getLX() const
{
	return lx;
};

float Quad::getLY() const
{
	return ly;
};

float Quad::getSize() const
{
	return size;
};