#include <opengl-playground/material.hpp>

std::ostream &operator<<(std::ostream &os, glm::vec3 const &vec3)
{
	return os << "(" << vec3.r << "|" << vec3.g << "|" << vec3.b << ")";
}

std::ostream &operator<<(std::ostream &os, Material const &material)
{
	return os	<< "Diffuse Color: " << material.diff_color << ", "
			<< "Ambient Color: " << material.ambient_color << ", "
			<< "Specular Color: " << material.specular_color << ", "
			<< "Texture counts (diff, amb, spec): " << material.diffuse_textures.size()
			<< ", " << material.ambient_textures.size() << ", " << material.specular_textures.size();
}

Material::Material()
{
	shininess_strength = 0.0f;
	shininess = 1.0f;
	this->setDiffuseColor(glm::vec3(0.0f));
	this->setAmbientColor(glm::vec3(0.0f));
	this->setSpecularColor(glm::vec3(0.0f));
}

Material::Material(const glm::vec3 &diff_color, const glm::vec3 &ambient_color, const glm::vec3 &specular_color) : Material()
{
	this->setDiffuseColor(diff_color);
	this->setAmbientColor(ambient_color);
	this->setSpecularColor(specular_color);
}

void Material::setSpecularColor(const glm::vec3 &color)
{
	this->specular_color = color;
}

void Material::setAmbientColor(const glm::vec3 &color)
{
	this->ambient_color = color;
}

void Material::setDiffuseColor(const glm::vec3 &color)
{
	this->diff_color = color;
}

void Material::pushSpecularTexture(std::shared_ptr<OpenGlTexture> texture)
{
	this->specular_textures.push_back(texture);
}

void Material::pushAmbientTexture(std::shared_ptr<OpenGlTexture> texture)
{
	this->ambient_textures.push_back(texture);
}

void Material::pushDiffuseTexture(std::shared_ptr<OpenGlTexture> texture)
{
	this->diffuse_textures.push_back(texture);
}

void Material::pushSpecularTexture(const std::vector<std::shared_ptr<OpenGlTexture>> &textures)
{
	this->specular_textures.insert(this->specular_textures.end(), textures.begin(), textures.end());
}

void Material::pushAmbientTexture(const std::vector<std::shared_ptr<OpenGlTexture>> &textures)
{
	this->ambient_textures.insert(this->ambient_textures.end(), textures.begin(), textures.end());
}

void Material::pushDiffuseTexture(const std::vector<std::shared_ptr<OpenGlTexture>> &textures)
{
	this->diffuse_textures.insert(this->diffuse_textures.end(), textures.begin(), textures.end());
}

const std::vector<std::shared_ptr<OpenGlTexture>> &Material::getSpecularTextures()
{
	return this->specular_textures;
}

const std::vector<std::shared_ptr<OpenGlTexture>> &Material::getAmbientTextures()
{
	return this->ambient_textures;
}

const std::vector<std::shared_ptr<OpenGlTexture>> &Material::getDiffuseTextures()
{
	return this->diffuse_textures;
}

const glm::vec3 &Material::getDiffuseColor()
{
	return this->diff_color;
}

const glm::vec3 &Material::getAmbientColor()
{
	return this->ambient_color;
}

const glm::vec3 &Material::getSpecularColor()
{
	return this->specular_color;
}

